History

Lua 5.0

Lua Team committed 23 years ago

Commit 488a64b1 parent c2bb718138 files · +16186 −12300Browse files

Showing the changes to src (63 of 138 files). Show all

Unified · Split

63 files
  1. src/Makefile +6 −2
  2. src/README +5 −0
  3. src/lapi.c +664 −236
  4. src/lapi.h +1 −2
  5. src/lcode.c +530 −517
  6. src/lcode.h +31 −27
  7. src/ldebug.c +409 −290
  8. src/ldebug.h +16 −6
  9. src/ldo.c +347 −277
  10. src/ldo.h +40 −13
  11. src/ldump.c +170 −0
  12. src/lfunc.c +78 −52
  13. src/lfunc.h +5 −4
  14. src/lgc.c +377 −237
  15. src/lgc.h +9 −3
  16. src/lib/Makefile +5 −6
  17. src/lib/README +6 −4
  18. src/lib/lauxlib.c +433 −58
  19. src/lib/lbaselib.c +445 −422
  20. src/lib/ldblib.c +176 −65
  21. src/lib/liolib.c +509 −477
  22. src/lib/lmathlib.c +80 −72
  23. src/lib/loadlib.c +205 −0
  24. src/lib/lstrlib.c +374 −225
  25. src/lib/ltablib.c +250 −0
  26. src/llex.c +201 −164
  27. src/llex.h +17 −14
  28. src/llimits.h +83 −102
  29. src/lmem.c +52 −111
  30. src/lmem.h +21 −19
  31. src/lobject.c +125 −55
  32. src/lobject.h +246 −114
  33. src/lopcodes.c +102 −0
  34. src/lopcodes.h +165 −95
  35. src/lparser.c +787 −582
  36. src/lparser.h +33 −22
  37. src/lstate.c +174 −75
  38. src/lstate.h +158 −40
  39. src/lstring.c +55 −108
  40. src/lstring.h +11 −15
  41. src/ltable.c +393 −187
  42. src/ltable.h +14 −17
  43. src/ltests.c +500 −191
  44. src/ltm.c +38 −131
  45. src/ltm.h +14 −22
  46. src/lua/Makefile +4 −5
  47. src/lua/README +21 −29
  48. src/lua/lua.c +332 −216
  49. src/luac/Makefile +13 −6
  50. src/luac/README +4 −8
  51. src/luac/dump.c +0 −121
  52. src/luac/luac.c +106 −118
  53. src/luac/luac.h +0 −31
  54. src/luac/opt.c +0 −127
  55. src/luac/print.c +171 −53
  56. src/luac/print.h +0 −55
  57. src/luac/stubs.c +0 −127
  58. src/lundump.c +176 −134
  59. src/lundump.h +16 −17
  60. src/lvm.c +575 −505
  61. src/lvm.h +17 −14
  62. src/lzio.c +43 −46
  63. src/lzio.h +37 −26
src/Makefile+6−2
@@ -9,11 +9,13 @@ OBJS= \ · 8 unmodified lines
99 lcode.o \
1010 ldebug.o \
1111 ldo.o \
12+ ldump.o \
1213 lfunc.o \
1314 lgc.o \
1415 llex.o \
1516 lmem.o \
1617 lobject.o \
18+ lopcodes.o \
1719 lparser.o \
1820 lstate.o \
1921 lstring.o \
@@ -29,11 +31,13 @@ SRCS= \ · 9 unmodified lines
2931 lcode.c \
3032 ldebug.c \
3133 ldo.c \
34+ ldump.c \
3235 lfunc.c \
3336 lgc.c \
3437 llex.c \
3538 lmem.c \
3639 lobject.c \
40+ lopcodes.c \
3741 lparser.c \
3842 lstate.c \
3943 lstring.c \
@@ -65,9 +69,9 @@ SRCS= \ · 25 unmodified lines
6569
6670 T= $(LIB)/liblua.a
6771
68−all: $T
72+all: $T
6973
70−$T: $(OBJS)
74+$T: $(OBJS)
7175 $(AR) $@ $(OBJS)
7276 $(RANLIB) $@
7377
src/README+5−0
@@ -0,0 +1,5 @@
1+This is the Lua core.
2+
3+The standard Lua library are in lib/.
4+A sample interpreter is in lua/.
5+A standalone compiler is in luac/.
src/lapi.c+664−236
@@ -1,15 +1,19 @@
11 /*
2−** $Id: lapi.c,v 1.110a 2000/10/30 12:50:09 roberto Exp $
2+** $Id: lapi.c,v 1.235 2003/04/07 14:36:08 roberto Exp $
33 ** Lua API
44 ** See Copyright Notice in lua.h
55 */
66
77
8+#include <assert.h>
89 #include <string.h>
910
11+#define lapi_c
12+
1013 #include "lua.h"
1114
1215 #include "lapi.h"
16+#include "ldebug.h"
1317 #include "ldo.h"
1418 #include "lfunc.h"
1519 #include "lgc.h"
@@ -19,43 +23,128 @@ · 3 unmodified lines
1923 #include "lstring.h"
2024 #include "ltable.h"
2125 #include "ltm.h"
26+#include "lundump.h"
2227 #include "lvm.h"
2328
2429
25−const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
26− "$Authors: " LUA_AUTHORS " $";
30+const char lua_ident[] =
31+ "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
32+ "$Authors: " LUA_AUTHORS " $\n"
33+ "$URL: www.lua.org $\n";
34+
2735
2836
37+#ifndef api_check
38+#define api_check(L, o) /*{ assert(o); }*/
39+#endif
2940
30−#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
41+#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
3142
32−#define api_incr_top(L) incr_top
43+#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
3344
3445
3546
3647
37−TObject *luaA_index (lua_State *L, int index) {
38− return Index(L, index);
48+static TObject *negindex (lua_State *L, int idx) {
49+ if (idx > LUA_REGISTRYINDEX) {
50+ api_check(L, idx != 0 && -idx <= L->top - L->base);
51+ return L->top+idx;
52+ }
53+ else switch (idx) { /* pseudo-indices */
54+ case LUA_REGISTRYINDEX: return registry(L);
55+ case LUA_GLOBALSINDEX: return gt(L);
56+ default: {
57+ TObject *func = (L->base - 1);
58+ idx = LUA_GLOBALSINDEX - idx;
59+ lua_assert(iscfunction(func));
60+ return (idx <= clvalue(func)->c.nupvalues)
61+ ? &clvalue(func)->c.upvalue[idx-1]
62+ : NULL;
63+ }
64+ }
65+}
66+
67+
68+static TObject *luaA_index (lua_State *L, int idx) {
69+ if (idx > 0) {
70+ api_check(L, idx <= L->top - L->base);
71+ return L->base + idx - 1;
72+ }
73+ else {
74+ TObject *o = negindex(L, idx);
75+ api_check(L, o != NULL);
76+ return o;
77+ }
3978 }
4079
4180
42−static TObject *luaA_indexAcceptable (lua_State *L, int index) {
43− if (index >= 0) {
44− TObject *o = L->Cbase+(index-1);
81+static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
82+ if (idx > 0) {
83+ TObject *o = L->base+(idx-1);
84+ api_check(L, idx <= L->stack_last - L->base);
4585 if (o >= L->top) return NULL;
4686 else return o;
4787 }
48− else return L->top+index;
88+ else
89+ return negindex(L, idx);
4990 }
5091
5192
5293 void luaA_pushobject (lua_State *L, const TObject *o) {
53− *L->top = *o;
54− incr_top;
94+ setobj2s(L->top, o);
95+ incr_top(L);
96+}
97+
98+
99+LUA_API int lua_checkstack (lua_State *L, int size) {
100+ int res;
101+ lua_lock(L);
102+ if ((L->top - L->base + size) > LUA_MAXCSTACK)
103+ res = 0; /* stack overflow */
104+ else {
105+ luaD_checkstack(L, size);
106+ if (L->ci->top < L->top + size)
107+ L->ci->top = L->top + size;
108+ res = 1;
109+ }
110+ lua_unlock(L);
111+ return res;
55112 }
56113
57−LUA_API int lua_stackspace (lua_State *L) {
58− return (L->stack_last - L->top);
114+
115+LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
116+ int i;
117+ lua_lock(to);
118+ api_checknelems(from, n);
119+ from->top -= n;
120+ for (i = 0; i < n; i++) {
121+ setobj2s(to->top, from->top + i);
122+ api_incr_top(to);
123+ }
124+ lua_unlock(to);
125+}
126+
127+
128+LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
129+ lua_CFunction old;
130+ lua_lock(L);
131+ old = G(L)->panic;
132+ G(L)->panic = panicf;
133+ lua_unlock(L);
134+ return old;
135+}
136+
137+
138+LUA_API lua_State *lua_newthread (lua_State *L) {
139+ lua_State *L1;
140+ lua_lock(L);
141+ luaC_checkGC(L);
142+ L1 = luaE_newthread(L);
143+ setthvalue(L->top, L1);
144+ api_incr_top(L);
145+ lua_unlock(L);
146+ lua_userstateopen(L1);
147+ return L1;
59148 }
60149
61150
@@ -66,37 +155,61 @@ LUA_API int lua_stackspace (lua_State *L) { · 4 unmodified lines
66155
67156
68157 LUA_API int lua_gettop (lua_State *L) {
69− return (L->top - L->Cbase);
158+ return (L->top - L->base);
70159 }
71160
72161
73−LUA_API void lua_settop (lua_State *L, int index) {
74− if (index >= 0)
75− luaD_adjusttop(L, L->Cbase, index);
76− else
77− L->top = L->top+index+1; /* index is negative */
162+LUA_API void lua_settop (lua_State *L, int idx) {
163+ lua_lock(L);
164+ if (idx >= 0) {
165+ api_check(L, idx <= L->stack_last - L->base);
166+ while (L->top < L->base + idx)
167+ setnilvalue(L->top++);
168+ L->top = L->base + idx;
169+ }
170+ else {
171+ api_check(L, -(idx+1) <= (L->top - L->base));
172+ L->top += idx+1; /* `subtract' index (index is negative) */
173+ }
174+ lua_unlock(L);
78175 }
79176
80177
81−LUA_API void lua_remove (lua_State *L, int index) {
82− StkId p = luaA_index(L, index);
83− while (++p < L->top) *(p-1) = *p;
178+LUA_API void lua_remove (lua_State *L, int idx) {
179+ StkId p;
180+ lua_lock(L);
181+ p = luaA_index(L, idx);
182+ while (++p < L->top) setobjs2s(p-1, p);
84183 L->top--;
184+ lua_unlock(L);
85185 }
86186
87187
88−LUA_API void lua_insert (lua_State *L, int index) {
89− StkId p = luaA_index(L, index);
188+LUA_API void lua_insert (lua_State *L, int idx) {
189+ StkId p;
90190 StkId q;
91− for (q = L->top; q>p; q--)
92− *q = *(q-1);
93− *p = *L->top;
191+ lua_lock(L);
192+ p = luaA_index(L, idx);
193+ for (q = L->top; q>p; q--) setobjs2s(q, q-1);
194+ setobjs2s(p, L->top);
195+ lua_unlock(L);
94196 }
95197
96198
97−LUA_API void lua_pushvalue (lua_State *L, int index) {
98− *L->top = *luaA_index(L, index);
199+LUA_API void lua_replace (lua_State *L, int idx) {
200+ lua_lock(L);
201+ api_checknelems(L, 1);
202+ setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
203+ L->top--;
204+ lua_unlock(L);
205+}
206+
207+
208+LUA_API void lua_pushvalue (lua_State *L, int idx) {
209+ lua_lock(L);
210+ setobj2s(L->top, luaA_index(L, idx));
99211 api_incr_top(L);
212+ lua_unlock(L);
100213 }
101214
102215
@@ -106,93 +219,167 @@ LUA_API void lua_pushvalue (lua_State *L, int index) { · 3 unmodified lines
106219 */
107220
108221
109−LUA_API int lua_type (lua_State *L, int index) {
110− StkId o = luaA_indexAcceptable(L, index);
222+LUA_API int lua_type (lua_State *L, int idx) {
223+ StkId o = luaA_indexAcceptable(L, idx);
111224 return (o == NULL) ? LUA_TNONE : ttype(o);
112225 }
113226
227+
114228 LUA_API const char *lua_typename (lua_State *L, int t) {
115229 UNUSED(L);
116− return (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
230+ return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
117231 }
118232
119233
120−LUA_API int lua_iscfunction (lua_State *L, int index) {
121− StkId o = luaA_indexAcceptable(L, index);
234+LUA_API int lua_iscfunction (lua_State *L, int idx) {
235+ StkId o = luaA_indexAcceptable(L, idx);
122236 return (o == NULL) ? 0 : iscfunction(o);
123237 }
124238
125−LUA_API int lua_isnumber (lua_State *L, int index) {
126− TObject *o = luaA_indexAcceptable(L, index);
127− return (o == NULL) ? 0 : (tonumber(o) == 0);
239+
240+LUA_API int lua_isnumber (lua_State *L, int idx) {
241+ TObject n;
242+ const TObject *o = luaA_indexAcceptable(L, idx);
243+ return (o != NULL && tonumber(o, &n));
128244 }
129245
130−LUA_API int lua_isstring (lua_State *L, int index) {
131− int t = lua_type(L, index);
246+
247+LUA_API int lua_isstring (lua_State *L, int idx) {
248+ int t = lua_type(L, idx);
132249 return (t == LUA_TSTRING || t == LUA_TNUMBER);
133250 }
134251
135252
136−LUA_API int lua_tag (lua_State *L, int index) {
137− StkId o = luaA_indexAcceptable(L, index);
138− return (o == NULL) ? LUA_NOTAG : luaT_tag(o);
253+LUA_API int lua_isuserdata (lua_State *L, int idx) {
254+ const TObject *o = luaA_indexAcceptable(L, idx);
255+ return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
139256 }
140257
141−LUA_API int lua_equal (lua_State *L, int index1, int index2) {
258+
259+LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
142260 StkId o1 = luaA_indexAcceptable(L, index1);
143261 StkId o2 = luaA_indexAcceptable(L, index2);
144− if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */
145− else return luaO_equalObj(o1, o2);
262+ return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
263+ : luaO_rawequalObj(o1, o2);
264+}
265+
266+
267+LUA_API int lua_equal (lua_State *L, int index1, int index2) {
268+ StkId o1, o2;
269+ int i;
270+ lua_lock(L); /* may call tag method */
271+ o1 = luaA_indexAcceptable(L, index1);
272+ o2 = luaA_indexAcceptable(L, index2);
273+ i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
274+ : equalobj(L, o1, o2);
275+ lua_unlock(L);
276+ return i;
146277 }
147278
279+
148280 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
149− StkId o1 = luaA_indexAcceptable(L, index1);
150− StkId o2 = luaA_indexAcceptable(L, index2);
151− if (o1 == NULL || o2 == NULL) return 0; /* index out-of-range */
152− else return luaV_lessthan(L, o1, o2, L->top);
281+ StkId o1, o2;
282+ int i;
283+ lua_lock(L); /* may call tag method */
284+ o1 = luaA_indexAcceptable(L, index1);
285+ o2 = luaA_indexAcceptable(L, index2);
286+ i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
287+ : luaV_lessthan(L, o1, o2);
288+ lua_unlock(L);
289+ return i;
153290 }
154291
155292
156293
157−LUA_API double lua_tonumber (lua_State *L, int index) {
158− StkId o = luaA_indexAcceptable(L, index);
159− return (o == NULL || tonumber(o)) ? 0 : nvalue(o);
294+LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
295+ TObject n;
296+ const TObject *o = luaA_indexAcceptable(L, idx);
297+ if (o != NULL && tonumber(o, &n))
298+ return nvalue(o);
299+ else
300+ return 0;
160301 }
161302
162−LUA_API const char *lua_tostring (lua_State *L, int index) {
163− StkId o = luaA_indexAcceptable(L, index);
164− return (o == NULL || tostring(L, o)) ? NULL : svalue(o);
303+
304+LUA_API int lua_toboolean (lua_State *L, int idx) {
305+ const TObject *o = luaA_indexAcceptable(L, idx);
306+ return (o != NULL) && !l_isfalse(o);
165307 }
166308
167−LUA_API size_t lua_strlen (lua_State *L, int index) {
168− StkId o = luaA_indexAcceptable(L, index);
169− return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len;
309+
310+LUA_API const char *lua_tostring (lua_State *L, int idx) {
311+ StkId o = luaA_indexAcceptable(L, idx);
312+ if (o == NULL)
313+ return NULL;
314+ else if (ttisstring(o))
315+ return svalue(o);
316+ else {
317+ const char *s;
318+ lua_lock(L); /* `luaV_tostring' may create a new string */
319+ s = (luaV_tostring(L, o) ? svalue(o) : NULL);
320+ luaC_checkGC(L);
321+ lua_unlock(L);
322+ return s;
323+ }
170324 }
171325
172−LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
173− StkId o = luaA_indexAcceptable(L, index);
174− return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c;
326+
327+LUA_API size_t lua_strlen (lua_State *L, int idx) {
328+ StkId o = luaA_indexAcceptable(L, idx);
329+ if (o == NULL)
330+ return 0;
331+ else if (ttisstring(o))
332+ return tsvalue(o)->tsv.len;
333+ else {
334+ size_t l;
335+ lua_lock(L); /* `luaV_tostring' may create a new string */
336+ l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
337+ lua_unlock(L);
338+ return l;
339+ }
175340 }
176341
177−LUA_API void *lua_touserdata (lua_State *L, int index) {
178− StkId o = luaA_indexAcceptable(L, index);
179− return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL :
180− tsvalue(o)->u.d.value;
342+
343+LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
344+ StkId o = luaA_indexAcceptable(L, idx);
345+ return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
181346 }
182347
183−LUA_API const void *lua_topointer (lua_State *L, int index) {
184− StkId o = luaA_indexAcceptable(L, index);
348+
349+LUA_API void *lua_touserdata (lua_State *L, int idx) {
350+ StkId o = luaA_indexAcceptable(L, idx);
185351 if (o == NULL) return NULL;
186352 switch (ttype(o)) {
187− case LUA_TTABLE:
188− return hvalue(o);
189− case LUA_TFUNCTION:
190− return clvalue(o);
353+ case LUA_TUSERDATA: return (uvalue(o) + 1);
354+ case LUA_TLIGHTUSERDATA: return pvalue(o);
191355 default: return NULL;
192356 }
193357 }
194358
195359
360+LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
361+ StkId o = luaA_indexAcceptable(L, idx);
362+ return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
363+}
364+
365+
366+LUA_API const void *lua_topointer (lua_State *L, int idx) {
367+ StkId o = luaA_indexAcceptable(L, idx);
368+ if (o == NULL) return NULL;
369+ else {
370+ switch (ttype(o)) {
371+ case LUA_TTABLE: return hvalue(o);
372+ case LUA_TFUNCTION: return clvalue(o);
373+ case LUA_TTHREAD: return thvalue(o);
374+ case LUA_TUSERDATA:
375+ case LUA_TLIGHTUSERDATA:
376+ return lua_touserdata(L, idx);
377+ default: return NULL;
378+ }
379+ }
380+}
381+
382+
196383
197384 /*
198385 ** push functions (C -> stack)
@@ -200,22 +387,27 @@ LUA_API const void *lua_topointer (lua_State *L, int index) { · 1 unmodified line
200387
201388
202389 LUA_API void lua_pushnil (lua_State *L) {
203− ttype(L->top) = LUA_TNIL;
390+ lua_lock(L);
391+ setnilvalue(L->top);
204392 api_incr_top(L);
393+ lua_unlock(L);
205394 }
206395
207396
208−LUA_API void lua_pushnumber (lua_State *L, double n) {
209− nvalue(L->top) = n;
210− ttype(L->top) = LUA_TNUMBER;
397+LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
398+ lua_lock(L);
399+ setnvalue(L->top, n);
211400 api_incr_top(L);
401+ lua_unlock(L);
212402 }
213403
214404
215405 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
216− tsvalue(L->top) = luaS_newlstr(L, s, len);
217− ttype(L->top) = LUA_TSTRING;
406+ lua_lock(L);
407+ luaC_checkGC(L);
408+ setsvalue2s(L->top, luaS_newlstr(L, s, len));
218409 api_incr_top(L);
410+ lua_unlock(L);
219411 }
220412
221413
@@ -227,159 +419,338 @@ LUA_API void lua_pushstring (lua_State *L, const char *s) { · 5 unmodified lines
227419 }
228420
229421
230−LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
231− luaV_Cclosure(L, fn, n);
422+LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
423+ va_list argp) {
424+ const char *ret;
425+ lua_lock(L);
426+ luaC_checkGC(L);
427+ ret = luaO_pushvfstring(L, fmt, argp);
428+ lua_unlock(L);
429+ return ret;
232430 }
233431
234432
235−LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
236− /* ORDER LUA_T */
237− if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(tag)))
238− luaO_verror(L, "invalid tag for a userdata (%d)", tag);
239− tsvalue(L->top) = luaS_createudata(L, u, tag);
240− ttype(L->top) = LUA_TUSERDATA;
241− api_incr_top(L);
433+LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
434+ const char *ret;
435+ va_list argp;
436+ lua_lock(L);
437+ luaC_checkGC(L);
438+ va_start(argp, fmt);
439+ ret = luaO_pushvfstring(L, fmt, argp);
440+ va_end(argp);
441+ lua_unlock(L);
442+ return ret;
242443 }
243444
244445
245−
246−/*
247−** get functions (Lua -> stack)
248−*/
446+LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
447+ Closure *cl;
448+ lua_lock(L);
449+ luaC_checkGC(L);
450+ api_checknelems(L, n);
451+ cl = luaF_newCclosure(L, n);
452+ cl->c.f = fn;
453+ L->top -= n;
454+ while (n--)
455+ setobj2n(&cl->c.upvalue[n], L->top+n);
456+ setclvalue(L->top, cl);
457+ api_incr_top(L);
458+ lua_unlock(L);
459+}
249460
250461
251−LUA_API void lua_getglobal (lua_State *L, const char *name) {
252− StkId top = L->top;
253− *top = *luaV_getglobal(L, luaS_new(L, name));
254− L->top = top;
462+LUA_API void lua_pushboolean (lua_State *L, int b) {
463+ lua_lock(L);
464+ setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
255465 api_incr_top(L);
466+ lua_unlock(L);
256467 }
257468
258469
259−LUA_API void lua_gettable (lua_State *L, int index) {
260− StkId t = Index(L, index);
261− StkId top = L->top;
262− *(top-1) = *luaV_gettable(L, t);
263− L->top = top; /* tag method may change top */
470+LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
471+ lua_lock(L);
472+ setpvalue(L->top, p);
473+ api_incr_top(L);
474+ lua_unlock(L);
264475 }
265476
266477
267−LUA_API void lua_rawget (lua_State *L, int index) {
268− StkId t = Index(L, index);
269− LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
270− *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1);
271−}
272478
479+/*
480+** get functions (Lua -> stack)
481+*/
273482
274−LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
275− StkId o = Index(L, index);
276− LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
277− *L->top = *luaH_getnum(hvalue(o), n);
278− api_incr_top(L);
483+
484+LUA_API void lua_gettable (lua_State *L, int idx) {
485+ StkId t;
486+ lua_lock(L);
487+ t = luaA_index(L, idx);
488+ setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
489+ lua_unlock(L);
279490 }
280491
281492
282−LUA_API void lua_getglobals (lua_State *L) {
283− hvalue(L->top) = L->gt;
284− ttype(L->top) = LUA_TTABLE;
285− api_incr_top(L);
493+LUA_API void lua_rawget (lua_State *L, int idx) {
494+ StkId t;
495+ lua_lock(L);
496+ t = luaA_index(L, idx);
497+ api_check(L, ttistable(t));
498+ setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
499+ lua_unlock(L);
286500 }
287501
288502
289−LUA_API int lua_getref (lua_State *L, int ref) {
290− if (ref == LUA_REFNIL)
291− ttype(L->top) = LUA_TNIL;
292− else if (0 <= ref && ref < L->refSize &&
293− (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
294− *L->top = L->refArray[ref].o;
295− else
296− return 0;
503+LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
504+ StkId o;
505+ lua_lock(L);
506+ o = luaA_index(L, idx);
507+ api_check(L, ttistable(o));
508+ setobj2s(L->top, luaH_getnum(hvalue(o), n));
297509 api_incr_top(L);
298− return 1;
510+ lua_unlock(L);
299511 }
300512
301513
302514 LUA_API void lua_newtable (lua_State *L) {
303− hvalue(L->top) = luaH_new(L, 0);
304− ttype(L->top) = LUA_TTABLE;
515+ lua_lock(L);
516+ luaC_checkGC(L);
517+ sethvalue(L->top, luaH_new(L, 0, 0));
305518 api_incr_top(L);
519+ lua_unlock(L);
520+}
521+
522+
523+LUA_API int lua_getmetatable (lua_State *L, int objindex) {
524+ const TObject *obj;
525+ Table *mt = NULL;
526+ int res;
527+ lua_lock(L);
528+ obj = luaA_indexAcceptable(L, objindex);
529+ if (obj != NULL) {
530+ switch (ttype(obj)) {
531+ case LUA_TTABLE:
532+ mt = hvalue(obj)->metatable;
533+ break;
534+ case LUA_TUSERDATA:
535+ mt = uvalue(obj)->uv.metatable;
536+ break;
537+ }
538+ }
539+ if (mt == NULL || mt == hvalue(defaultmeta(L)))
540+ res = 0;
541+ else {
542+ sethvalue(L->top, mt);
543+ api_incr_top(L);
544+ res = 1;
545+ }
546+ lua_unlock(L);
547+ return res;
306548 }
307549
308550
551+LUA_API void lua_getfenv (lua_State *L, int idx) {
552+ StkId o;
553+ lua_lock(L);
554+ o = luaA_index(L, idx);
555+ setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
556+ api_incr_top(L);
557+ lua_unlock(L);
558+}
559+
309560
310561 /*
311562 ** set functions (stack -> Lua)
312563 */
313564
314565
315−LUA_API void lua_setglobal (lua_State *L, const char *name) {
316− StkId top = L->top;
317− luaV_setglobal(L, luaS_new(L, name));
318− L->top = top-1; /* remove element from the top */
566+LUA_API void lua_settable (lua_State *L, int idx) {
567+ StkId t;
568+ lua_lock(L);
569+ api_checknelems(L, 2);
570+ t = luaA_index(L, idx);
571+ luaV_settable(L, t, L->top - 2, L->top - 1);
572+ L->top -= 2; /* pop index and value */
573+ lua_unlock(L);
319574 }
320575
321576
322−LUA_API void lua_settable (lua_State *L, int index) {
323− StkId t = Index(L, index);
324− StkId top = L->top;
325− luaV_settable(L, t, top-2);
326− L->top = top-2; /* pop index and value */
577+LUA_API void lua_rawset (lua_State *L, int idx) {
578+ StkId t;
579+ lua_lock(L);
580+ api_checknelems(L, 2);
581+ t = luaA_index(L, idx);
582+ api_check(L, ttistable(t));
583+ setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
584+ L->top -= 2;
585+ lua_unlock(L);
327586 }
328587
329588
330−LUA_API void lua_rawset (lua_State *L, int index) {
331− StkId t = Index(L, index);
332− LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
333− *luaH_set(L, hvalue(t), L->top-2) = *(L->top-1);
334− L->top -= 2;
589+LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
590+ StkId o;
591+ lua_lock(L);
592+ api_checknelems(L, 1);
593+ o = luaA_index(L, idx);
594+ api_check(L, ttistable(o));
595+ setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
596+ L->top--;
597+ lua_unlock(L);
335598 }
336599
337600
338−LUA_API void lua_rawseti (lua_State *L, int index, int n) {
339− StkId o = Index(L, index);
340− LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
341− *luaH_setint(L, hvalue(o), n) = *(L->top-1);
601+LUA_API int lua_setmetatable (lua_State *L, int objindex) {
602+ TObject *obj, *mt;
603+ int res = 1;
604+ lua_lock(L);
605+ api_checknelems(L, 1);
606+ obj = luaA_index(L, objindex);
607+ mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
608+ api_check(L, ttistable(mt));
609+ switch (ttype(obj)) {
610+ case LUA_TTABLE: {
611+ hvalue(obj)->metatable = hvalue(mt); /* write barrier */
612+ break;
613+ }
614+ case LUA_TUSERDATA: {
615+ uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */
616+ break;
617+ }
618+ default: {
619+ res = 0; /* cannot set */
620+ break;
621+ }
622+ }
342623 L->top--;
624+ lua_unlock(L);
625+ return res;
343626 }
344627
345628
346−LUA_API void lua_setglobals (lua_State *L) {
347− StkId newtable = --L->top;
348− LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected");
349− L->gt = hvalue(newtable);
629+LUA_API int lua_setfenv (lua_State *L, int idx) {
630+ StkId o;
631+ int res = 0;
632+ lua_lock(L);
633+ api_checknelems(L, 1);
634+ o = luaA_index(L, idx);
635+ L->top--;
636+ api_check(L, ttistable(L->top));
637+ if (isLfunction(o)) {
638+ res = 1;
639+ clvalue(o)->l.g = *(L->top);
640+ }
641+ lua_unlock(L);
642+ return res;
350643 }
351644
352645
353−LUA_API int lua_ref (lua_State *L, int lock) {
354− int ref;
355− if (ttype(L->top-1) == LUA_TNIL)
356− ref = LUA_REFNIL;
357− else {
358− if (L->refFree != NONEXT) { /* is there a free place? */
359− ref = L->refFree;
360− L->refFree = L->refArray[ref].st;
361− }
362− else { /* no more free places */
363− luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
364− "reference table overflow", MAX_INT);
365− L->nblocks += sizeof(struct Ref);
366− ref = L->refSize++;
367− }
368− L->refArray[ref].o = *(L->top-1);
369− L->refArray[ref].st = lock ? LOCK : HOLD;
370− }
371− L->top--;
372− return ref;
646+/*
647+** `load' and `call' functions (run Lua code)
648+*/
649+
650+LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
651+ StkId func;
652+ lua_lock(L);
653+ api_checknelems(L, nargs+1);
654+ func = L->top - (nargs+1);
655+ luaD_call(L, func, nresults);
656+ lua_unlock(L);
373657 }
374658
375659
660+
376661 /*
377−** "do" functions (run Lua code)
378−** (most of them are in ldo.c)
662+** Execute a protected call.
379663 */
664+struct CallS { /* data to `f_call' */
665+ StkId func;
666+ int nresults;
667+};
668+
380669
381−LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
382− luaD_call(L, L->top-(nargs+1), nresults);
670+static void f_call (lua_State *L, void *ud) {
671+ struct CallS *c = cast(struct CallS *, ud);
672+ luaD_call(L, c->func, c->nresults);
673+}
674+
675+
676+
677+LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
678+ struct CallS c;
679+ int status;
680+ ptrdiff_t func;
681+ lua_lock(L);
682+ func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
683+ c.func = L->top - (nargs+1); /* function to be called */
684+ c.nresults = nresults;
685+ status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
686+ lua_unlock(L);
687+ return status;
688+}
689+
690+
691+/*
692+** Execute a protected C call.
693+*/
694+struct CCallS { /* data to `f_Ccall' */
695+ lua_CFunction func;
696+ void *ud;
697+};
698+
699+
700+static void f_Ccall (lua_State *L, void *ud) {
701+ struct CCallS *c = cast(struct CCallS *, ud);
702+ Closure *cl;
703+ cl = luaF_newCclosure(L, 0);
704+ cl->c.f = c->func;
705+ setclvalue(L->top, cl); /* push function */
706+ incr_top(L);
707+ setpvalue(L->top, c->ud); /* push only argument */
708+ incr_top(L);
709+ luaD_call(L, L->top - 2, 0);
710+}
711+
712+
713+LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
714+ struct CCallS c;
715+ int status;
716+ lua_lock(L);
717+ c.func = func;
718+ c.ud = ud;
719+ status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
720+ lua_unlock(L);
721+ return status;
722+}
723+
724+
725+LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
726+ const char *chunkname) {
727+ ZIO z;
728+ int status;
729+ int c;
730+ lua_lock(L);
731+ if (!chunkname) chunkname = "?";
732+ luaZ_init(&z, reader, data, chunkname);
733+ c = luaZ_lookahead(&z);
734+ status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
735+ lua_unlock(L);
736+ return status;
737+}
738+
739+
740+LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
741+ int status;
742+ TObject *o;
743+ lua_lock(L);
744+ api_checknelems(L, 1);
745+ o = L->top - 1;
746+ if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
747+ luaU_dump(L, clvalue(o)->l.p, writer, data);
748+ status = 1;
749+ }
750+ else
751+ status = 0;
752+ lua_unlock(L);
753+ return status;
383754 }
384755
385756
@@ -388,23 +759,34 @@ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { · 2 unmodified lines
388759 */
389760
390761 /* GC values are expressed in Kbytes: #bytes/2^10 */
391−#define GCscale(x) ((int)((x)>>10))
392−#define GCunscale(x) ((unsigned long)(x)<<10)
762+#define GCscalel(x) ((x)>>10)
763+#define GCscale(x) (cast(int, GCscalel(x)))
764+#define GCunscale(x) (cast(lu_mem, x)<<10)
393765
394766 LUA_API int lua_getgcthreshold (lua_State *L) {
395− return GCscale(L->GCthreshold);
767+ int threshold;
768+ lua_lock(L);
769+ threshold = GCscale(G(L)->GCthreshold);
770+ lua_unlock(L);
771+ return threshold;
396772 }
397773
398774 LUA_API int lua_getgccount (lua_State *L) {
399− return GCscale(L->nblocks);
775+ int count;
776+ lua_lock(L);
777+ count = GCscale(G(L)->nblocks);
778+ lua_unlock(L);
779+ return count;
400780 }
401781
402782 LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
403− if (newthreshold > GCscale(ULONG_MAX))
404− L->GCthreshold = ULONG_MAX;
783+ lua_lock(L);
784+ if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
785+ G(L)->GCthreshold = MAX_LUMEM;
405786 else
406− L->GCthreshold = GCunscale(newthreshold);
787+ G(L)->GCthreshold = GCunscale(newthreshold);
407788 luaC_checkGC(L);
789+ lua_unlock(L);
408790 }
409791
410792
@@ -412,83 +794,129 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { · 1 unmodified line
412794 ** miscellaneous functions
413795 */
414796
415−LUA_API void lua_settag (lua_State *L, int tag) {
416− luaT_realtag(L, tag);
417− switch (ttype(L->top-1)) {
418− case LUA_TTABLE:
419− hvalue(L->top-1)->htag = tag;
420− break;
421− case LUA_TUSERDATA:
422− tsvalue(L->top-1)->u.d.tag = tag;
423− break;
424− default:
425− luaO_verror(L, "cannot change the tag of a %.20s",
426− luaO_typename(L->top-1));
427− }
797+
798+LUA_API const char *lua_version (void) {
799+ return LUA_VERSION;
428800 }
429801
430802
431−LUA_API void lua_unref (lua_State *L, int ref) {
432− if (ref >= 0) {
433− LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref");
434− L->refArray[ref].st = L->refFree;
435− L->refFree = ref;
436− }
803+LUA_API int lua_error (lua_State *L) {
804+ lua_lock(L);
805+ api_checknelems(L, 1);
806+ luaG_errormsg(L);
807+ lua_unlock(L);
808+ return 0; /* to avoid warnings */
437809 }
438810
439811
440−LUA_API int lua_next (lua_State *L, int index) {
441− StkId t = luaA_index(L, index);
442− Node *n;
443− LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
444− n = luaH_next(L, hvalue(t), luaA_index(L, -1));
445− if (n) {
446− *(L->top-1) = *key(n);
447− *L->top = *val(n);
812+LUA_API int lua_next (lua_State *L, int idx) {
813+ StkId t;
814+ int more;
815+ lua_lock(L);
816+ t = luaA_index(L, idx);
817+ api_check(L, ttistable(t));
818+ more = luaH_next(L, hvalue(t), L->top - 1);
819+ if (more) {
448820 api_incr_top(L);
449− return 1;
450821 }
451− else { /* no more elements */
822+ else /* no more elements */
452823 L->top -= 1; /* remove key */
453− return 0;
824+ lua_unlock(L);
825+ return more;
826+}
827+
828+
829+LUA_API void lua_concat (lua_State *L, int n) {
830+ lua_lock(L);
831+ luaC_checkGC(L);
832+ api_checknelems(L, n);
833+ if (n >= 2) {
834+ luaV_concat(L, n, L->top - L->base - 1);
835+ L->top -= (n-1);
836+ }
837+ else if (n == 0) { /* push empty string */
838+ setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
839+ api_incr_top(L);
840+ }
841+ /* else n == 1; nothing to do */
842+ lua_unlock(L);
843+}
844+
845+
846+LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
847+ Udata *u;
848+ lua_lock(L);
849+ luaC_checkGC(L);
850+ u = luaS_newudata(L, size);
851+ setuvalue(L->top, u);
852+ api_incr_top(L);
853+ lua_unlock(L);
854+ return u + 1;
855+}
856+
857+
858+LUA_API int lua_pushupvalues (lua_State *L) {
859+ Closure *func;
860+ int n, i;
861+ lua_lock(L);
862+ api_check(L, iscfunction(L->base - 1));
863+ func = clvalue(L->base - 1);
864+ n = func->c.nupvalues;
865+ luaD_checkstack(L, n + LUA_MINSTACK);
866+ for (i=0; i<n; i++) {
867+ setobj2s(L->top, &func->c.upvalue[i]);
868+ L->top++;
454869 }
870+ lua_unlock(L);
871+ return n;
455872 }
456873
457874
458−LUA_API int lua_getn (lua_State *L, int index) {
459− Hash *h = hvalue(luaA_index(L, index));
460− const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */
461− if (ttype(value) == LUA_TNUMBER)
462− return (int)nvalue(value);
875+static const char *aux_upvalue (lua_State *L, int funcindex, int n,
876+ TObject **val) {
877+ Closure *f;
878+ StkId fi = luaA_index(L, funcindex);
879+ if (!ttisfunction(fi)) return NULL;
880+ f = clvalue(fi);
881+ if (f->c.isC) {
882+ if (n > f->c.nupvalues) return NULL;
883+ *val = &f->c.upvalue[n-1];
884+ return "";
885+ }
463886 else {
464− Number max = 0;
465− int i = h->size;
466− Node *n = h->node;
467− while (i--) {
468− if (ttype(key(n)) == LUA_TNUMBER &&
469− ttype(val(n)) != LUA_TNIL &&
470− nvalue(key(n)) > max)
471− max = nvalue(key(n));
472− n++;
473− }
474− return (int)max;
887+ Proto *p = f->l.p;
888+ if (n > p->sizeupvalues) return NULL;
889+ *val = f->l.upvals[n-1]->v;
890+ return getstr(p->upvalues[n-1]);
475891 }
476892 }
477893
478894
479−LUA_API void lua_concat (lua_State *L, int n) {
480− StkId top = L->top;
481− luaV_strconc(L, n, top);
482− L->top = top-(n-1);
483− luaC_checkGC(L);
895+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
896+ const char *name;
897+ TObject *val;
898+ lua_lock(L);
899+ name = aux_upvalue(L, funcindex, n, &val);
900+ if (name) {
901+ setobj2s(L->top, val);
902+ api_incr_top(L);
903+ }
904+ lua_unlock(L);
905+ return name;
484906 }
485907
486908
487−LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
488− TString *ts = luaS_newudata(L, (size==0) ? 1 : size, NULL);
489− tsvalue(L->top) = ts;
490− ttype(L->top) = LUA_TUSERDATA;
491− api_incr_top(L);
492− return ts->u.d.value;
909+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
910+ const char *name;
911+ TObject *val;
912+ lua_lock(L);
913+ api_checknelems(L, 1);
914+ name = aux_upvalue(L, funcindex, n, &val);
915+ if (name) {
916+ L->top--;
917+ setobj(val, L->top); /* write barrier */
918+ }
919+ lua_unlock(L);
920+ return name;
493921 }
494922
src/lapi.h+1−2
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lapi.h,v 1.20 2000/08/31 14:08:27 roberto Exp $
2+** $Id: lapi.h,v 1.21 2002/03/04 21:29:41 roberto Exp $
33 ** Auxiliary functions from Lua API
44 ** See Copyright Notice in lua.h
55 */
@@ -11,7 +11,6 @@ · 5 unmodified lines
1111 #include "lobject.h"
1212
1313
14−TObject *luaA_index (lua_State *L, int index);
1514 void luaA_pushobject (lua_State *L, const TObject *o);
1615
1716 #endif
src/lcode.c+530−517
@@ -1,66 +1,84 @@
11 /*
2−** $Id: lcode.c,v 1.51 2000/09/29 12:42:13 roberto Exp $
2+** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp $
33 ** Code generator for Lua
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include "stdlib.h"
8+#include <stdlib.h>
9+
10+#define lcode_c
911
1012 #include "lua.h"
1113
1214 #include "lcode.h"
15+#include "ldebug.h"
1316 #include "ldo.h"
1417 #include "llex.h"
1518 #include "lmem.h"
1619 #include "lobject.h"
1720 #include "lopcodes.h"
1821 #include "lparser.h"
22+#include "ltable.h"
1923
2024
21−void luaK_error (LexState *ls, const char *msg) {
22− luaX_error(ls, msg, ls->t.token);
23−}
25+#define hasjumps(e) ((e)->t != (e)->f)
2426
2527
26−/*
27−** Returns the the previous instruction, for optimizations.
28−** If there is a jump target between this and the current instruction,
29−** returns a dummy instruction to avoid wrong optimizations.
30−*/
31−static Instruction previous_instruction (FuncState *fs) {
32− if (fs->pc > fs->lasttarget) /* no jumps to current position? */
33− return fs->f->code[fs->pc-1]; /* returns previous instruction */
34− else
35− return CREATE_0(OP_END); /* no optimizations after an `END' */
28+void luaK_nil (FuncState *fs, int from, int n) {
29+ Instruction *previous;
30+ if (fs->pc > fs->lasttarget && /* no jumps to current position? */
31+ GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
32+ int pfrom = GETARG_A(*previous);
33+ int pto = GETARG_B(*previous);
34+ if (pfrom <= from && from <= pto+1) { /* can connect both? */
35+ if (from+n-1 > pto)
36+ SETARG_B(*previous, from+n-1);
37+ return;
38+ }
39+ }
40+ luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
3641 }
3742
3843
3944 int luaK_jump (FuncState *fs) {
40− int j = luaK_code1(fs, OP_JMP, NO_JUMP);
41− if (j == fs->lasttarget) { /* possible jumps to this jump? */
42− luaK_concat(fs, &j, fs->jlt); /* keep them on hold */
43− fs->jlt = NO_JUMP;
44− }
45+ int jpc = fs->jpc; /* save list of jumps to here */
46+ int j;
47+ fs->jpc = NO_JUMP;
48+ j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
49+ luaK_concat(fs, &j, jpc); /* keep them on hold */
4550 return j;
4651 }
4752
4853
54+static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
55+ luaK_codeABC(fs, op, A, B, C);
56+ return luaK_jump(fs);
57+}
58+
59+
4960 static void luaK_fixjump (FuncState *fs, int pc, int dest) {
5061 Instruction *jmp = &fs->f->code[pc];
51− if (dest == NO_JUMP)
52− SETARG_S(*jmp, NO_JUMP); /* point to itself to represent end of list */
53− else { /* jump is relative to position following jump instruction */
54− int offset = dest-(pc+1);
55− if (abs(offset) > MAXARG_S)
56− luaK_error(fs->ls, "control structure too long");
57− SETARG_S(*jmp, offset);
58− }
62+ int offset = dest-(pc+1);
63+ lua_assert(dest != NO_JUMP);
64+ if (abs(offset) > MAXARG_sBx)
65+ luaX_syntaxerror(fs->ls, "control structure too long");
66+ SETARG_sBx(*jmp, offset);
67+}
68+
69+
70+/*
71+** returns current `pc' and marks it as a jump target (to avoid wrong
72+** optimizations with consecutive instructions not in the same basic block).
73+*/
74+int luaK_getlabel (FuncState *fs) {
75+ fs->lasttarget = fs->pc;
76+ return fs->pc;
5977 }
6078
6179
6280 static int luaK_getjump (FuncState *fs, int pc) {
63− int offset = GETARG_S(fs->f->code[pc]);
81+ int offset = GETARG_sBx(fs->f->code[pc]);
6482 if (offset == NO_JUMP) /* point to itself represents end of list */
6583 return NO_JUMP; /* end of list */
6684 else
@@ -68,634 +86,629 @@ static int luaK_getjump (FuncState *fs, int pc) { · 1 unmodified line
6886 }
6987
7088
89+static Instruction *getjumpcontrol (FuncState *fs, int pc) {
90+ Instruction *pi = &fs->f->code[pc];
91+ if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
92+ return pi-1;
93+ else
94+ return pi;
95+}
96+
97+
7198 /*
72−** returns current `pc' and marks it as a jump target (to avoid wrong
73−** optimizations with consecutive instructions not in the same basic block).
74−** discharge list of jumps to last target.
99+** check whether list has any jump that do not produce a value
100+** (or produce an inverted value)
75101 */
76−int luaK_getlabel (FuncState *fs) {
77− if (fs->pc != fs->lasttarget) {
78− int lasttarget = fs->lasttarget;
79− fs->lasttarget = fs->pc;
80− luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */
81− fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */
102+static int need_value (FuncState *fs, int list, int cond) {
103+ for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
104+ Instruction i = *getjumpcontrol(fs, list);
105+ if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
82106 }
83− return fs->pc;
107+ return 0; /* not found */
84108 }
85109
86110
87−void luaK_deltastack (FuncState *fs, int delta) {
88− fs->stacklevel += delta;
89− if (fs->stacklevel > fs->f->maxstacksize) {
90− if (fs->stacklevel > MAXSTACK)
91− luaK_error(fs->ls, "function or expression too complex");
92− fs->f->maxstacksize = fs->stacklevel;
93− }
111+static void patchtestreg (Instruction *i, int reg) {
112+ if (reg == NO_REG) reg = GETARG_B(*i);
113+ SETARG_A(*i, reg);
94114 }
95115
96116
97−void luaK_kstr (LexState *ls, int c) {
98− luaK_code1(ls->fs, OP_PUSHSTRING, c);
117+static void luaK_patchlistaux (FuncState *fs, int list,
118+ int ttarget, int treg, int ftarget, int freg, int dtarget) {
119+ while (list != NO_JUMP) {
120+ int next = luaK_getjump(fs, list);
121+ Instruction *i = getjumpcontrol(fs, list);
122+ if (GET_OPCODE(*i) != OP_TEST) {
123+ lua_assert(dtarget != NO_JUMP);
124+ luaK_fixjump(fs, list, dtarget); /* jump to default target */
125+ }
126+ else {
127+ if (GETARG_C(*i)) {
128+ lua_assert(ttarget != NO_JUMP);
129+ patchtestreg(i, treg);
130+ luaK_fixjump(fs, list, ttarget);
131+ }
132+ else {
133+ lua_assert(ftarget != NO_JUMP);
134+ patchtestreg(i, freg);
135+ luaK_fixjump(fs, list, ftarget);
136+ }
137+ }
138+ list = next;
139+ }
99140 }
100141
101142
102−static int number_constant (FuncState *fs, Number r) {
103− /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
104− Proto *f = fs->f;
105− int c = f->nknum;
106− int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
107− while (--c >= lim)
108− if (f->knum[c] == r) return c;
109− /* not found; create a new entry */
110− luaM_growvector(fs->L, f->knum, f->nknum, 1, Number,
111− "constant table overflow", MAXARG_U);
112− c = f->nknum++;
113− f->knum[c] = r;
114− return c;
115−}
116−
117−
118−void luaK_number (FuncState *fs, Number f) {
119− if (f <= (Number)MAXARG_S && (Number)(int)f == f)
120− luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */
121− else
122− luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f));
143+static void luaK_dischargejpc (FuncState *fs) {
144+ luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
145+ fs->jpc = NO_JUMP;
123146 }
124147
125148
126−void luaK_adjuststack (FuncState *fs, int n) {
127− if (n > 0)
128− luaK_code1(fs, OP_POP, n);
129− else
130− luaK_code1(fs, OP_PUSHNIL, -n);
149+void luaK_patchlist (FuncState *fs, int list, int target) {
150+ if (target == fs->pc)
151+ luaK_patchtohere(fs, list);
152+ else {
153+ lua_assert(target < fs->pc);
154+ luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
155+ }
131156 }
132157
133158
134−int luaK_lastisopen (FuncState *fs) {
135− /* check whether last instruction is an open function call */
136− Instruction i = previous_instruction(fs);
137− if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)
138− return 1;
139− else return 0;
159+void luaK_patchtohere (FuncState *fs, int list) {
160+ luaK_getlabel(fs);
161+ luaK_concat(fs, &fs->jpc, list);
140162 }
141163
142164
143−void luaK_setcallreturns (FuncState *fs, int nresults) {
144− if (luaK_lastisopen(fs)) { /* expression is an open function call? */
145− SETARG_B(fs->f->code[fs->pc-1], nresults); /* set number of results */
146− luaK_deltastack(fs, nresults); /* push results */
165+void luaK_concat (FuncState *fs, int *l1, int l2) {
166+ if (l2 == NO_JUMP) return;
167+ else if (*l1 == NO_JUMP)
168+ *l1 = l2;
169+ else {
170+ int list = *l1;
171+ int next;
172+ while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */
173+ list = next;
174+ luaK_fixjump(fs, list, l2);
147175 }
148176 }
149177
150178
151−static int discharge (FuncState *fs, expdesc *var) {
152− switch (var->k) {
153− case VLOCAL:
154− luaK_code1(fs, OP_GETLOCAL, var->u.index);
155− break;
156− case VGLOBAL:
157− luaK_code1(fs, OP_GETGLOBAL, var->u.index);
158− break;
159− case VINDEXED:
160− luaK_code0(fs, OP_GETTABLE);
161− break;
162− case VEXP:
163− return 0; /* nothing to do */
179+void luaK_checkstack (FuncState *fs, int n) {
180+ int newstack = fs->freereg + n;
181+ if (newstack > fs->f->maxstacksize) {
182+ if (newstack >= MAXSTACK)
183+ luaX_syntaxerror(fs->ls, "function or expression too complex");
184+ fs->f->maxstacksize = cast(lu_byte, newstack);
164185 }
165− var->k = VEXP;
166− var->u.l.t = var->u.l.f = NO_JUMP;
167− return 1;
168186 }
169187
170188
171−static void discharge1 (FuncState *fs, expdesc *var) {
172− discharge(fs, var);
173− /* if it has jumps then it is already discharged */
174− if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP)
175− luaK_setcallreturns(fs, 1); /* call must return 1 value */
189+void luaK_reserveregs (FuncState *fs, int n) {
190+ luaK_checkstack(fs, n);
191+ fs->freereg += n;
176192 }
177193
178194
179−void luaK_storevar (LexState *ls, const expdesc *var) {
180− FuncState *fs = ls->fs;
181− switch (var->k) {
182− case VLOCAL:
183− luaK_code1(fs, OP_SETLOCAL, var->u.index);
184− break;
185− case VGLOBAL:
186− luaK_code1(fs, OP_SETGLOBAL, var->u.index);
187− break;
188− case VINDEXED: /* table is at top-3; pop 3 elements after operation */
189− luaK_code2(fs, OP_SETTABLE, 3, 3);
190− break;
191− default:
192− LUA_INTERNALERROR("invalid var kind to store");
195+static void freereg (FuncState *fs, int reg) {
196+ if (reg >= fs->nactvar && reg < MAXSTACK) {
197+ fs->freereg--;
198+ lua_assert(reg == fs->freereg);
193199 }
194200 }
195201
196202
197−static OpCode invertjump (OpCode op) {
198− switch (op) {
199− case OP_JMPNE: return OP_JMPEQ;
200− case OP_JMPEQ: return OP_JMPNE;
201− case OP_JMPLT: return OP_JMPGE;
202− case OP_JMPLE: return OP_JMPGT;
203− case OP_JMPGT: return OP_JMPLE;
204− case OP_JMPGE: return OP_JMPLT;
205− case OP_JMPT: case OP_JMPONT: return OP_JMPF;
206− case OP_JMPF: case OP_JMPONF: return OP_JMPT;
207− default:
208− LUA_INTERNALERROR("invalid jump instruction");
209− return OP_END; /* to avoid warnings */
210− }
203+static void freeexp (FuncState *fs, expdesc *e) {
204+ if (e->k == VNONRELOC)
205+ freereg(fs, e->info);
211206 }
212207
213208
214−static void luaK_patchlistaux (FuncState *fs, int list, int target,
215− OpCode special, int special_target) {
216− Instruction *code = fs->f->code;
217− while (list != NO_JUMP) {
218− int next = luaK_getjump(fs, list);
219− Instruction *i = &code[list];
220− OpCode op = GET_OPCODE(*i);
221− if (op == special) /* this `op' already has a value */
222− luaK_fixjump(fs, list, special_target);
223− else {
224− luaK_fixjump(fs, list, target); /* do the patch */
225− if (op == OP_JMPONT) /* remove eventual values */
226− SET_OPCODE(*i, OP_JMPT);
227− else if (op == OP_JMPONF)
228− SET_OPCODE(*i, OP_JMPF);
229− }
230− list = next;
209+static int addk (FuncState *fs, TObject *k, TObject *v) {
210+ const TObject *idx = luaH_get(fs->h, k);
211+ if (ttisnumber(idx)) {
212+ lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
213+ return cast(int, nvalue(idx));
214+ }
215+ else { /* constant not found; create a new entry */
216+ Proto *f = fs->f;
217+ luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
218+ MAXARG_Bx, "constant table overflow");
219+ setobj2n(&f->k[fs->nk], v);
220+ setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
221+ return fs->nk++;
231222 }
232223 }
233224
234225
235−void luaK_patchlist (FuncState *fs, int list, int target) {
236− if (target == fs->lasttarget) /* same target that list `jlt'? */
237− luaK_concat(fs, &fs->jlt, list); /* delay fixing */
238− else
239− luaK_patchlistaux(fs, list, target, OP_END, 0);
226+int luaK_stringK (FuncState *fs, TString *s) {
227+ TObject o;
228+ setsvalue(&o, s);
229+ return addk(fs, &o, &o);
240230 }
241231
242232
243−static int need_value (FuncState *fs, int list, OpCode hasvalue) {
244− /* check whether list has a jump without a value */
245− for (; list != NO_JUMP; list = luaK_getjump(fs, list))
246− if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1;
247− return 0; /* not found */
233+int luaK_numberK (FuncState *fs, lua_Number r) {
234+ TObject o;
235+ setnvalue(&o, r);
236+ return addk(fs, &o, &o);
248237 }
249238
250239
251−void luaK_concat (FuncState *fs, int *l1, int l2) {
252− if (*l1 == NO_JUMP)
253− *l1 = l2;
254− else {
255− int list = *l1;
256− for (;;) { /* traverse `l1' */
257− int next = luaK_getjump(fs, list);
258− if (next == NO_JUMP) { /* end of list? */
259− luaK_fixjump(fs, list, l2);
260− return;
261− }
262− list = next;
263− }
264− }
240+static int nil_constant (FuncState *fs) {
241+ TObject k, v;
242+ setnilvalue(&v);
243+ sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */
244+ return addk(fs, &k, &v);
265245 }
266246
267247
268−static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
269− int prevpos; /* position of last instruction */
270− Instruction *previous;
271− int *golist, *exitlist;
272− if (!invert) {
273− golist = &v->u.l.f; /* go if false */
274− exitlist = &v->u.l.t; /* exit if true */
275− }
276− else {
277− golist = &v->u.l.t; /* go if true */
278− exitlist = &v->u.l.f; /* exit if false */
279− }
280− discharge1(fs, v);
281− prevpos = fs->pc-1;
282− previous = &fs->f->code[prevpos];
283− LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here");
284− if (!ISJUMP(GET_OPCODE(*previous)))
285− prevpos = luaK_code1(fs, jump, NO_JUMP);
286− else { /* last instruction is already a jump */
287− if (invert)
288− SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
248+void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
249+ if (e->k == VCALL) { /* expression is an open function call? */
250+ SETARG_C(getcode(fs, e), nresults+1);
251+ if (nresults == 1) { /* `regular' expression? */
252+ e->k = VNONRELOC;
253+ e->info = GETARG_A(getcode(fs, e));
254+ }
289255 }
290− luaK_concat(fs, exitlist, prevpos); /* insert last jump in `exitlist' */
291− luaK_patchlist(fs, *golist, luaK_getlabel(fs));
292− *golist = NO_JUMP;
293256 }
294257
295258
296−void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {
297− luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);
259+void luaK_dischargevars (FuncState *fs, expdesc *e) {
260+ switch (e->k) {
261+ case VLOCAL: {
262+ e->k = VNONRELOC;
263+ break;
264+ }
265+ case VUPVAL: {
266+ e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);
267+ e->k = VRELOCABLE;
268+ break;
269+ }
270+ case VGLOBAL: {
271+ e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);
272+ e->k = VRELOCABLE;
273+ break;
274+ }
275+ case VINDEXED: {
276+ freereg(fs, e->aux);
277+ freereg(fs, e->info);
278+ e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);
279+ e->k = VRELOCABLE;
280+ break;
281+ }
282+ case VCALL: {
283+ luaK_setcallreturns(fs, e, 1);
284+ break;
285+ }
286+ default: break; /* there is one value available (somewhere) */
287+ }
298288 }
299289
300290
301−static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
302− luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);
291+static int code_label (FuncState *fs, int A, int b, int jump) {
292+ luaK_getlabel(fs); /* those instructions may be jump targets */
293+ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
303294 }
304295
305296
306−static int code_label (FuncState *fs, OpCode op, int arg) {
307− luaK_getlabel(fs); /* those instructions may be jump targets */
308− return luaK_code1(fs, op, arg);
309−}
310−
311−
312−void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
313− FuncState *fs = ls->fs;
314− if (!discharge(fs, v)) { /* `v' is an expression? */
315− OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
316− if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
317− /* expression has no jumps */
318− if (onlyone)
319− luaK_setcallreturns(fs, 1); /* call must return 1 value */
320− }
321− else { /* expression has jumps */
322− int final; /* position after whole expression */
323− int j = NO_JUMP; /* eventual jump over values */
324− int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */
325− int p_1 = NO_JUMP; /* position of an eventual PUSHINT */
326− if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF)
327− || need_value(fs, v->u.l.t, OP_JMPONT)) {
328− /* expression needs values */
329− if (ISJUMP(previous))
330− luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */
331− else {
332− j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */
333− /* correct stack for compiler and symbolic execution */
334− luaK_adjuststack(fs, 1);
335− }
336− p_nil = code_label(fs, OP_PUSHNILJMP, 0);
337− p_1 = code_label(fs, OP_PUSHINT, 1);
338− luaK_patchlist(fs, j, luaK_getlabel(fs));
339− }
340− final = luaK_getlabel(fs);
341− luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final);
342− luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final);
343− v->u.l.f = v->u.l.t = NO_JUMP;
297+static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
298+ luaK_dischargevars(fs, e);
299+ switch (e->k) {
300+ case VNIL: {
301+ luaK_nil(fs, reg, 1);
302+ break;
303+ }
304+ case VFALSE: case VTRUE: {
305+ luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
306+ break;
307+ }
308+ case VK: {
309+ luaK_codeABx(fs, OP_LOADK, reg, e->info);
310+ break;
311+ }
312+ case VRELOCABLE: {
313+ Instruction *pc = &getcode(fs, e);
314+ SETARG_A(*pc, reg);
315+ break;
316+ }
317+ case VNONRELOC: {
318+ if (reg != e->info)
319+ luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);
320+ break;
321+ }
322+ default: {
323+ lua_assert(e->k == VVOID || e->k == VJMP);
324+ return; /* nothing to do... */
344325 }
345326 }
327+ e->info = reg;
328+ e->k = VNONRELOC;
346329 }
347330
348331
349−void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) {
350− FuncState *fs = ls->fs;
351− if (op == OPR_MINUS) {
352− luaK_tostack(ls, v, 1);
353− luaK_code0(fs, OP_MINUS);
332+static void discharge2anyreg (FuncState *fs, expdesc *e) {
333+ if (e->k != VNONRELOC) {
334+ luaK_reserveregs(fs, 1);
335+ discharge2reg(fs, e, fs->freereg-1);
354336 }
355− else { /* op == NOT */
356− Instruction *previous;
357− discharge1(fs, v);
358− previous = &fs->f->code[fs->pc-1];
359− if (ISJUMP(GET_OPCODE(*previous)))
360− SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
361− else
362− luaK_code0(fs, OP_NOT);
363− /* interchange true and false lists */
364− { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; }
337+}
338+
339+
340+static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
341+ discharge2reg(fs, e, reg);
342+ if (e->k == VJMP)
343+ luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */
344+ if (hasjumps(e)) {
345+ int final; /* position after whole expression */
346+ int p_f = NO_JUMP; /* position of an eventual LOAD false */
347+ int p_t = NO_JUMP; /* position of an eventual LOAD true */
348+ if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
349+ int fj = NO_JUMP; /* first jump (over LOAD ops.) */
350+ if (e->k != VJMP)
351+ fj = luaK_jump(fs);
352+ p_f = code_label(fs, reg, 0, 1);
353+ p_t = code_label(fs, reg, 1, 0);
354+ luaK_patchtohere(fs, fj);
355+ }
356+ final = luaK_getlabel(fs);
357+ luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
358+ luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
365359 }
360+ e->f = e->t = NO_JUMP;
361+ e->info = reg;
362+ e->k = VNONRELOC;
366363 }
367364
368365
369−void luaK_infix (LexState *ls, BinOpr op, expdesc *v) {
370− FuncState *fs = ls->fs;
371− switch (op) {
372− case OPR_AND:
373− luaK_goiftrue(fs, v, 1);
374− break;
375− case OPR_OR:
376− luaK_goiffalse(fs, v, 1);
377− break;
378− default:
379− luaK_tostack(ls, v, 1); /* all other binary operators need a value */
366+void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
367+ luaK_dischargevars(fs, e);
368+ freeexp(fs, e);
369+ luaK_reserveregs(fs, 1);
370+ luaK_exp2reg(fs, e, fs->freereg - 1);
371+}
372+
373+
374+int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
375+ luaK_dischargevars(fs, e);
376+ if (e->k == VNONRELOC) {
377+ if (!hasjumps(e)) return e->info; /* exp is already in a register */
378+ if (e->info >= fs->nactvar) { /* reg. is not a local? */
379+ luaK_exp2reg(fs, e, e->info); /* put value on it */
380+ return e->info;
381+ }
380382 }
383+ luaK_exp2nextreg(fs, e); /* default */
384+ return e->info;
381385 }
382386
383387
388+void luaK_exp2val (FuncState *fs, expdesc *e) {
389+ if (hasjumps(e))
390+ luaK_exp2anyreg(fs, e);
391+ else
392+ luaK_dischargevars(fs, e);
393+}
384394
385−static const struct {
386− OpCode opcode; /* opcode for each binary operator */
387− int arg; /* default argument for the opcode */
388−} codes[] = { /* ORDER OPR */
389− {OP_ADD, 0}, {OP_SUB, 0}, {OP_MULT, 0}, {OP_DIV, 0},
390− {OP_POW, 0}, {OP_CONCAT, 2},
391− {OP_JMPNE, NO_JUMP}, {OP_JMPEQ, NO_JUMP},
392− {OP_JMPLT, NO_JUMP}, {OP_JMPLE, NO_JUMP},
393− {OP_JMPGT, NO_JUMP}, {OP_JMPGE, NO_JUMP}
394−};
395395
396+int luaK_exp2RK (FuncState *fs, expdesc *e) {
397+ luaK_exp2val(fs, e);
398+ switch (e->k) {
399+ case VNIL: {
400+ if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */
401+ e->info = nil_constant(fs);
402+ e->k = VK;
403+ return e->info + MAXSTACK;
404+ }
405+ else break;
406+ }
407+ case VK: {
408+ if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */
409+ return e->info + MAXSTACK;
410+ else break;
411+ }
412+ default: break;
413+ }
414+ /* not a constant in the right range: put it in a register */
415+ return luaK_exp2anyreg(fs, e);
416+}
396417
397−void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) {
398− FuncState *fs = ls->fs;
399− switch (op) {
400− case OPR_AND: {
401− LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed");
402− discharge1(fs, v2);
403− v1->u.l.t = v2->u.l.t;
404− luaK_concat(fs, &v1->u.l.f, v2->u.l.f);
418+
419+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
420+ switch (var->k) {
421+ case VLOCAL: {
422+ freeexp(fs, exp);
423+ luaK_exp2reg(fs, exp, var->info);
424+ return;
425+ }
426+ case VUPVAL: {
427+ int e = luaK_exp2anyreg(fs, exp);
428+ luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);
405429 break;
406430 }
407− case OPR_OR: {
408− LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed");
409− discharge1(fs, v2);
410− v1->u.l.f = v2->u.l.f;
411− luaK_concat(fs, &v1->u.l.t, v2->u.l.t);
431+ case VGLOBAL: {
432+ int e = luaK_exp2anyreg(fs, exp);
433+ luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);
434+ break;
435+ }
436+ case VINDEXED: {
437+ int e = luaK_exp2RK(fs, exp);
438+ luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
412439 break;
413440 }
414441 default: {
415− luaK_tostack(ls, v2, 1); /* `v2' must be a value */
416− luaK_code1(fs, codes[op].opcode, codes[op].arg);
442+ lua_assert(0); /* invalid var kind to store */
443+ break;
417444 }
418445 }
446+ freeexp(fs, exp);
419447 }
420448
421449
422−static void codelineinfo (FuncState *fs) {
423− Proto *f = fs->f;
424− LexState *ls = fs->ls;
425− if (ls->lastline > fs->lastline) {
426− luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int,
427− "line info overflow", MAX_INT);
428− if (ls->lastline > fs->lastline+1)
429− f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
430− f->lineinfo[f->nlineinfo++] = fs->pc;
431− fs->lastline = ls->lastline;
432− }
450+void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
451+ int func;
452+ luaK_exp2anyreg(fs, e);
453+ freeexp(fs, e);
454+ func = fs->freereg;
455+ luaK_reserveregs(fs, 2);
456+ luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));
457+ freeexp(fs, key);
458+ e->info = func;
459+ e->k = VNONRELOC;
433460 }
434461
435462
436−int luaK_code0 (FuncState *fs, OpCode o) {
437− return luaK_code2(fs, o, 0, 0);
463+static void invertjump (FuncState *fs, expdesc *e) {
464+ Instruction *pc = getjumpcontrol(fs, e->info);
465+ lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
466+ GET_OPCODE(*pc) != OP_TEST);
467+ SETARG_A(*pc, !(GETARG_A(*pc)));
438468 }
439469
440470
441−int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
442− return luaK_code2(fs, o, arg1, 0);
471+static int jumponcond (FuncState *fs, expdesc *e, int cond) {
472+ if (e->k == VRELOCABLE) {
473+ Instruction ie = getcode(fs, e);
474+ if (GET_OPCODE(ie) == OP_NOT) {
475+ fs->pc--; /* remove previous OP_NOT */
476+ return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
477+ }
478+ /* else go through */
479+ }
480+ discharge2anyreg(fs, e);
481+ freeexp(fs, e);
482+ return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
443483 }
444484
445485
446−int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
447− Instruction i = previous_instruction(fs);
448− int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop;
449− int optm = 0; /* 1 when there is an optimization */
450− switch (o) {
451− case OP_CLOSURE: {
452− delta = -arg2+1;
486+void luaK_goiftrue (FuncState *fs, expdesc *e) {
487+ int pc; /* pc of last jump */
488+ luaK_dischargevars(fs, e);
489+ switch (e->k) {
490+ case VK: case VTRUE: {
491+ pc = NO_JUMP; /* always true; do nothing */
453492 break;
454493 }
455− case OP_SETTABLE: {
456− delta = -arg2;
494+ case VFALSE: {
495+ pc = luaK_jump(fs); /* always jump */
457496 break;
458497 }
459− case OP_SETLIST: {
460− if (arg2 == 0) return NO_JUMP; /* nothing to do */
461− delta = -arg2;
498+ case VJMP: {
499+ invertjump(fs, e);
500+ pc = e->info;
462501 break;
463502 }
464− case OP_SETMAP: {
465− if (arg1 == 0) return NO_JUMP; /* nothing to do */
466− delta = -2*arg1;
503+ default: {
504+ pc = jumponcond(fs, e, 0);
467505 break;
468506 }
469− case OP_RETURN: {
470− if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
471− SET_OPCODE(i, OP_TAILCALL);
472− SETARG_B(i, arg1);
473− optm = 1;
474− }
507+ }
508+ luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
509+}
510+
511+
512+void luaK_goiffalse (FuncState *fs, expdesc *e) {
513+ int pc; /* pc of last jump */
514+ luaK_dischargevars(fs, e);
515+ switch (e->k) {
516+ case VNIL: case VFALSE: {
517+ pc = NO_JUMP; /* always false; do nothing */
475518 break;
476519 }
477− case OP_PUSHNIL: {
478− if (arg1 == 0) return NO_JUMP; /* nothing to do */
479− delta = arg1;
480− switch(GET_OPCODE(i)) {
481− case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
482− default: break;
483− }
520+ case VTRUE: {
521+ pc = luaK_jump(fs); /* always jump */
484522 break;
485523 }
486− case OP_POP: {
487− if (arg1 == 0) return NO_JUMP; /* nothing to do */
488− delta = -arg1;
489− switch(GET_OPCODE(i)) {
490− case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
491− default: break;
492− }
524+ case VJMP: {
525+ pc = e->info;
493526 break;
494527 }
495− case OP_GETTABLE: {
496− switch(GET_OPCODE(i)) {
497− case OP_PUSHSTRING: /* `t.x' */
498− SET_OPCODE(i, OP_GETDOTTED);
499− optm = 1;
500− break;
501− case OP_GETLOCAL: /* `t[i]' */
502− SET_OPCODE(i, OP_GETINDEXED);
503− optm = 1;
504− break;
505− default: break;
506− }
528+ default: {
529+ pc = jumponcond(fs, e, 1);
507530 break;
508531 }
509− case OP_ADD: {
510− switch(GET_OPCODE(i)) {
511− case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */
512− default: break;
513− }
532+ }
533+ luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
534+}
535+
536+
537+static void codenot (FuncState *fs, expdesc *e) {
538+ luaK_dischargevars(fs, e);
539+ switch (e->k) {
540+ case VNIL: case VFALSE: {
541+ e->k = VTRUE;
514542 break;
515543 }
516− case OP_SUB: {
517− switch(GET_OPCODE(i)) {
518− case OP_PUSHINT: /* `a-k' */
519− i = CREATE_S(OP_ADDI, -GETARG_S(i));
520− optm = 1;
521− break;
522− default: break;
523− }
544+ case VK: case VTRUE: {
545+ e->k = VFALSE;
524546 break;
525547 }
526− case OP_CONCAT: {
527− delta = -arg1+1;
528− switch(GET_OPCODE(i)) {
529− case OP_CONCAT: /* `a..b..c' */
530− SETARG_U(i, GETARG_U(i)+1);
531− optm = 1;
532− break;
533− default: break;
534− }
548+ case VJMP: {
549+ invertjump(fs, e);
535550 break;
536551 }
537− case OP_MINUS: {
538− switch(GET_OPCODE(i)) {
539− case OP_PUSHINT: /* `-k' */
540− SETARG_S(i, -GETARG_S(i));
541− optm = 1;
542− break;
543− case OP_PUSHNUM: /* `-k' */
544− SET_OPCODE(i, OP_PUSHNEGNUM);
545− optm = 1;
546− break;
547− default: break;
548− }
552+ case VRELOCABLE:
553+ case VNONRELOC: {
554+ discharge2anyreg(fs, e);
555+ freeexp(fs, e);
556+ e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);
557+ e->k = VRELOCABLE;
549558 break;
550559 }
551− case OP_JMPNE: {
552− if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */
553− i = CREATE_S(OP_JMPT, NO_JUMP);
554− optm = 1;
555− }
560+ default: {
561+ lua_assert(0); /* cannot happen */
556562 break;
557563 }
558− case OP_JMPEQ: {
559− if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */
560− i = CREATE_0(OP_NOT);
561− delta = -1; /* just undo effect of previous PUSHNIL */
562− optm = 1;
563− }
564− break;
564+ }
565+ /* interchange true and false lists */
566+ { int temp = e->f; e->f = e->t; e->t = temp; }
567+}
568+
569+
570+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
571+ t->aux = luaK_exp2RK(fs, k);
572+ t->k = VINDEXED;
573+}
574+
575+
576+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
577+ if (op == OPR_MINUS) {
578+ luaK_exp2val(fs, e);
579+ if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
580+ e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info]));
581+ else {
582+ luaK_exp2anyreg(fs, e);
583+ freeexp(fs, e);
584+ e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
585+ e->k = VRELOCABLE;
565586 }
566− case OP_JMPT:
567− case OP_JMPONT: {
568− switch (GET_OPCODE(i)) {
569− case OP_NOT: {
570− i = CREATE_S(OP_JMPF, NO_JUMP);
571− optm = 1;
572− break;
573− }
574− case OP_PUSHINT: {
575− if (o == OP_JMPT) { /* JMPONT must keep original integer value */
576− i = CREATE_S(OP_JMP, NO_JUMP);
577− optm = 1;
578− }
579− break;
580− }
581− case OP_PUSHNIL: {
582− if (GETARG_U(i) == 1) {
583− fs->pc--; /* erase previous instruction */
584− luaK_deltastack(fs, -1); /* correct stack */
585− return NO_JUMP;
586− }
587− break;
588− }
589− default: break;
590− }
587+ }
588+ else /* op == NOT */
589+ codenot(fs, e);
590+}
591+
592+
593+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
594+ switch (op) {
595+ case OPR_AND: {
596+ luaK_goiftrue(fs, v);
597+ luaK_patchtohere(fs, v->t);
598+ v->t = NO_JUMP;
591599 break;
592600 }
593− case OP_JMPF:
594− case OP_JMPONF: {
595− switch (GET_OPCODE(i)) {
596− case OP_NOT: {
597− i = CREATE_S(OP_JMPT, NO_JUMP);
598− optm = 1;
599− break;
600− }
601− case OP_PUSHINT: { /* `while 1 do ...' */
602− fs->pc--; /* erase previous instruction */
603− luaK_deltastack(fs, -1); /* correct stack */
604− return NO_JUMP;
605− }
606− case OP_PUSHNIL: { /* `repeat ... until nil' */
607− if (GETARG_U(i) == 1) {
608− i = CREATE_S(OP_JMP, NO_JUMP);
609− optm = 1;
610− }
611− break;
612− }
613− default: break;
614− }
601+ case OPR_OR: {
602+ luaK_goiffalse(fs, v);
603+ luaK_patchtohere(fs, v->f);
604+ v->f = NO_JUMP;
615605 break;
616606 }
617− case OP_GETDOTTED:
618− case OP_GETINDEXED:
619− case OP_TAILCALL:
620− case OP_ADDI: {
621− LUA_INTERNALERROR("instruction used only for optimizations");
607+ case OPR_CONCAT: {
608+ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
622609 break;
623610 }
624611 default: {
625− LUA_ASSERT(delta != VD, "invalid delta");
612+ luaK_exp2RK(fs, v);
626613 break;
627614 }
628615 }
629− luaK_deltastack(fs, delta);
630− if (optm) { /* optimize: put instruction in place of last one */
631− fs->f->code[fs->pc-1] = i; /* change previous instruction */
632− return fs->pc-1; /* do not generate new instruction */
616+}
617+
618+
619+static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
620+ int o1, int o2) {
621+ if (op <= OPR_POW) { /* arithmetic operator? */
622+ OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */
623+ res->info = luaK_codeABC(fs, opc, 0, o1, o2);
624+ res->k = VRELOCABLE;
633625 }
634− /* else build new instruction */
635− switch ((enum Mode)luaK_opproperties[o].mode) {
636− case iO: i = CREATE_0(o); break;
637− case iU: i = CREATE_U(o, arg1); break;
638− case iS: i = CREATE_S(o, arg1); break;
639− case iAB: i = CREATE_AB(o, arg1, arg2); break;
626+ else { /* test operator */
627+ static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
628+ int cond = 1;
629+ if (op >= OPR_GT) { /* `>' or `>='? */
630+ int temp; /* exchange args and replace by `<' or `<=' */
631+ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
632+ }
633+ else if (op == OPR_NE) cond = 0;
634+ res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);
635+ res->k = VJMP;
640636 }
641− codelineinfo(fs);
637+}
638+
639+
640+void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
641+ switch (op) {
642+ case OPR_AND: {
643+ lua_assert(e1->t == NO_JUMP); /* list must be closed */
644+ luaK_dischargevars(fs, e2);
645+ luaK_concat(fs, &e1->f, e2->f);
646+ e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;
647+ break;
648+ }
649+ case OPR_OR: {
650+ lua_assert(e1->f == NO_JUMP); /* list must be closed */
651+ luaK_dischargevars(fs, e2);
652+ luaK_concat(fs, &e1->t, e2->t);
653+ e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;
654+ break;
655+ }
656+ case OPR_CONCAT: {
657+ luaK_exp2val(fs, e2);
658+ if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
659+ lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);
660+ freeexp(fs, e1);
661+ SETARG_B(getcode(fs, e2), e1->info);
662+ e1->k = e2->k; e1->info = e2->info;
663+ }
664+ else {
665+ luaK_exp2nextreg(fs, e2);
666+ freeexp(fs, e2);
667+ freeexp(fs, e1);
668+ e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
669+ e1->k = VRELOCABLE;
670+ }
671+ break;
672+ }
673+ default: {
674+ int o1 = luaK_exp2RK(fs, e1);
675+ int o2 = luaK_exp2RK(fs, e2);
676+ freeexp(fs, e2);
677+ freeexp(fs, e1);
678+ codebinop(fs, e1, op, o1, o2);
679+ }
680+ }
681+}
682+
683+
684+void luaK_fixline (FuncState *fs, int line) {
685+ fs->f->lineinfo[fs->pc - 1] = line;
686+}
687+
688+
689+int luaK_code (FuncState *fs, Instruction i, int line) {
690+ Proto *f = fs->f;
691+ luaK_dischargejpc(fs); /* `pc' will change */
642692 /* put new instruction in code array */
643− luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
644− "code size overflow", MAX_INT);
645− fs->f->code[fs->pc] = i;
693+ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
694+ MAX_INT, "code size overflow");
695+ f->code[fs->pc] = i;
696+ /* save corresponding line information */
697+ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
698+ MAX_INT, "code size overflow");
699+ f->lineinfo[fs->pc] = line;
646700 return fs->pc++;
647701 }
648702
649703
650−const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
651− {iO, 0, 0}, /* OP_END */
652− {iU, 0, 0}, /* OP_RETURN */
653− {iAB, 0, 0}, /* OP_CALL */
654− {iAB, 0, 0}, /* OP_TAILCALL */
655− {iU, VD, 0}, /* OP_PUSHNIL */
656− {iU, VD, 0}, /* OP_POP */
657− {iS, 1, 0}, /* OP_PUSHINT */
658− {iU, 1, 0}, /* OP_PUSHSTRING */
659− {iU, 1, 0}, /* OP_PUSHNUM */
660− {iU, 1, 0}, /* OP_PUSHNEGNUM */
661− {iU, 1, 0}, /* OP_PUSHUPVALUE */
662− {iU, 1, 0}, /* OP_GETLOCAL */
663− {iU, 1, 0}, /* OP_GETGLOBAL */
664− {iO, 1, 2}, /* OP_GETTABLE */
665− {iU, 1, 1}, /* OP_GETDOTTED */
666− {iU, 1, 1}, /* OP_GETINDEXED */
667− {iU, 2, 1}, /* OP_PUSHSELF */
668− {iU, 1, 0}, /* OP_CREATETABLE */
669− {iU, 0, 1}, /* OP_SETLOCAL */
670− {iU, 0, 1}, /* OP_SETGLOBAL */
671− {iAB, VD, 0}, /* OP_SETTABLE */
672− {iAB, VD, 0}, /* OP_SETLIST */
673− {iU, VD, 0}, /* OP_SETMAP */
674− {iO, 1, 2}, /* OP_ADD */
675− {iS, 1, 1}, /* OP_ADDI */
676− {iO, 1, 2}, /* OP_SUB */
677− {iO, 1, 2}, /* OP_MULT */
678− {iO, 1, 2}, /* OP_DIV */
679− {iO, 1, 2}, /* OP_POW */
680− {iU, VD, 0}, /* OP_CONCAT */
681− {iO, 1, 1}, /* OP_MINUS */
682− {iO, 1, 1}, /* OP_NOT */
683− {iS, 0, 2}, /* OP_JMPNE */
684− {iS, 0, 2}, /* OP_JMPEQ */
685− {iS, 0, 2}, /* OP_JMPLT */
686− {iS, 0, 2}, /* OP_JMPLE */
687− {iS, 0, 2}, /* OP_JMPGT */
688− {iS, 0, 2}, /* OP_JMPGE */
689− {iS, 0, 1}, /* OP_JMPT */
690− {iS, 0, 1}, /* OP_JMPF */
691− {iS, 0, 1}, /* OP_JMPONT */
692− {iS, 0, 1}, /* OP_JMPONF */
693− {iS, 0, 0}, /* OP_JMP */
694− {iO, 0, 0}, /* OP_PUSHNILJMP */
695− {iS, 0, 0}, /* OP_FORPREP */
696− {iS, 0, 3}, /* OP_FORLOOP */
697− {iS, 2, 0}, /* OP_LFORPREP */
698− {iS, 0, 3}, /* OP_LFORLOOP */
699− {iAB, VD, 0} /* OP_CLOSURE */
700−};
704+int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
705+ lua_assert(getOpMode(o) == iABC);
706+ return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
707+}
708+
709+
710+int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
711+ lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
712+ return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
713+}
701714
src/lcode.h+31−27
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lcode.h,v 1.16 2000/08/09 14:49:13 roberto Exp $
2+** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp $
33 ** Code generator for Lua
44 ** See Copyright Notice in lua.h
55 */
@@ -26,45 +26,49 @@ · 20 unmodified lines
2626 typedef enum BinOpr {
2727 OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
2828 OPR_CONCAT,
29− OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
29+ OPR_NE, OPR_EQ,
30+ OPR_LT, OPR_LE, OPR_GT, OPR_GE,
3031 OPR_AND, OPR_OR,
3132 OPR_NOBINOPR
3233 } BinOpr;
3334
34−typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
35−
35+#define binopistest(op) ((op) >= OPR_NE)
3636
37−enum Mode {iO, iU, iS, iAB}; /* instruction format */
37+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
3838
39−#define VD 100 /* flag for variable delta */
4039
41−extern const struct OpProperties {
42− char mode;
43− unsigned char push;
44− unsigned char pop;
45−} luaK_opproperties[];
40+#define getcode(fs,e) ((fs)->f->code[(e)->info])
4641
42+#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
4743
48−void luaK_error (LexState *ls, const char *msg);
49−int luaK_code0 (FuncState *fs, OpCode o);
50−int luaK_code1 (FuncState *fs, OpCode o, int arg1);
51−int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
44+int luaK_code (FuncState *fs, Instruction i, int line);
45+int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46+int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
47+void luaK_fixline (FuncState *fs, int line);
48+void luaK_nil (FuncState *fs, int from, int n);
49+void luaK_reserveregs (FuncState *fs, int n);
50+void luaK_checkstack (FuncState *fs, int n);
51+int luaK_stringK (FuncState *fs, TString *s);
52+int luaK_numberK (FuncState *fs, lua_Number r);
53+void luaK_dischargevars (FuncState *fs, expdesc *e);
54+int luaK_exp2anyreg (FuncState *fs, expdesc *e);
55+void luaK_exp2nextreg (FuncState *fs, expdesc *e);
56+void luaK_exp2val (FuncState *fs, expdesc *e);
57+int luaK_exp2RK (FuncState *fs, expdesc *e);
58+void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
59+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60+void luaK_goiftrue (FuncState *fs, expdesc *e);
61+void luaK_goiffalse (FuncState *fs, expdesc *e);
62+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
63+void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
5264 int luaK_jump (FuncState *fs);
5365 void luaK_patchlist (FuncState *fs, int list, int target);
66+void luaK_patchtohere (FuncState *fs, int list);
5467 void luaK_concat (FuncState *fs, int *l1, int l2);
55−void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
5668 int luaK_getlabel (FuncState *fs);
57−void luaK_deltastack (FuncState *fs, int delta);
58−void luaK_kstr (LexState *ls, int c);
59−void luaK_number (FuncState *fs, Number f);
60−void luaK_adjuststack (FuncState *fs, int n);
61−int luaK_lastisopen (FuncState *fs);
62−void luaK_setcallreturns (FuncState *fs, int nresults);
63−void luaK_tostack (LexState *ls, expdesc *v, int onlyone);
64−void luaK_storevar (LexState *ls, const expdesc *var);
65−void luaK_prefix (LexState *ls, UnOpr op, expdesc *v);
66−void luaK_infix (LexState *ls, BinOpr op, expdesc *v);
67−void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2);
69+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
70+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
71+void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
6872
6973
7074 #endif
src/ldebug.c+409−290
@@ -1,11 +1,14 @@
11 /*
2−** $Id: ldebug.c,v 1.50 2000/10/30 12:38:50 roberto Exp $
2+** $Id: ldebug.c,v 1.150 2003/03/19 21:24:04 roberto Exp $
33 ** Debug Interface
44 ** See Copyright Notice in lua.h
55 */
66
77
88 #include <stdlib.h>
9+#include <string.h>
10+
11+#define ldebug_c
912
1013 #include "lua.h"
1114
@@ -20,447 +23,563 @@ · 8 unmodified lines
2023 #include "lstring.h"
2124 #include "ltable.h"
2225 #include "ltm.h"
23−#include "luadebug.h"
26+#include "lvm.h"
2427
2528
2629
27−static const char *getfuncname (lua_State *L, StkId f, const char **name);
30+static const char *getfuncname (CallInfo *ci, const char **name);
2831
2932
30−static void setnormalized (TObject *d, const TObject *s) {
31− if (ttype(s) == LUA_TMARK) {
32− clvalue(d) = infovalue(s)->func;
33− ttype(d) = LUA_TFUNCTION;
34− }
35− else *d = *s;
36−}
33+#define isLua(ci) (!((ci)->state & CI_C))
3734
3835
39−static int isLmark (StkId o) {
40− return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC);
36+static int currentpc (CallInfo *ci) {
37+ if (!isLua(ci)) return -1; /* function is not a Lua function? */
38+ if (ci->state & CI_HASFRAME) /* function has a frame? */
39+ ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */
40+ /* function's pc is saved */
41+ return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
4142 }
4243
4344
44−LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
45− lua_Hook oldhook = L->callhook;
46− L->callhook = func;
47− return oldhook;
45+static int currentline (CallInfo *ci) {
46+ int pc = currentpc(ci);
47+ if (pc < 0)
48+ return -1; /* only active lua functions have current-line information */
49+ else
50+ return getline(ci_func(ci)->l.p, pc);
4851 }
4952
5053
51−LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
52− lua_Hook oldhook = L->linehook;
53− L->linehook = func;
54− return oldhook;
54+void luaG_inithooks (lua_State *L) {
55+ CallInfo *ci;
56+ for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */
57+ currentpc(ci);
58+ L->hookinit = 1;
5559 }
5660
5761
58−static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
59− int i;
60− for (i = (top-1) - L->stack; i>=0; i--) {
61− if (is_T_MARK(L->stack[i].ttype)) {
62− if (level == 0)
63− return L->stack+i;
64− level--;
65− }
62+/*
63+** this function can be called asynchronous (e.g. during a signal)
64+*/
65+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
66+ if (func == NULL || mask == 0) { /* turn off hooks? */
67+ mask = 0;
68+ func = NULL;
6669 }
67− return NULL;
70+ L->hook = func;
71+ L->basehookcount = count;
72+ resethookcount(L);
73+ L->hookmask = cast(lu_byte, mask);
74+ L->hookinit = 0;
75+ return 1;
6876 }
6977
7078
71−LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
72− StkId f = aux_stackedfunction(L, level, L->top);
73− if (f == NULL) return 0; /* there is no such level */
74− else {
75− ar->_func = f;
76− return 1;
77− }
79+LUA_API lua_Hook lua_gethook (lua_State *L) {
80+ return L->hook;
7881 }
7982
8083
81−static int nups (StkId f) {
82− switch (ttype(f)) {
83− case LUA_TFUNCTION:
84− return clvalue(f)->nupvalues;
85− case LUA_TMARK:
86− return infovalue(f)->func->nupvalues;
87− default:
88− return 0;
89− }
84+LUA_API int lua_gethookmask (lua_State *L) {
85+ return L->hookmask;
9086 }
9187
9288
93−int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
94− int refi;
95− if (lineinfo == NULL || pc == -1)
96− return -1; /* no line info or function is not active */
97− refi = prefi ? *prefi : 0;
98− if (lineinfo[refi] < 0)
99− refline += -lineinfo[refi++];
100− LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
101− while (lineinfo[refi] > pc) {
102− refline--;
103− refi--;
104− if (lineinfo[refi] < 0)
105− refline -= -lineinfo[refi--];
106− LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
107− }
108− for (;;) {
109− int nextline = refline + 1;
110− int nextref = refi + 1;
111− if (lineinfo[nextref] < 0)
112− nextline += -lineinfo[nextref++];
113− LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
114− if (lineinfo[nextref] > pc)
115− break;
116− refline = nextline;
117− refi = nextref;
118− }
119− if (prefi) *prefi = refi;
120− return refline;
89+LUA_API int lua_gethookcount (lua_State *L) {
90+ return L->basehookcount;
12191 }
12292
12393
124−static int currentpc (StkId f) {
125− CallInfo *ci = infovalue(f);
126− LUA_ASSERT(isLmark(f), "function has no pc");
127− if (ci->pc)
128− return (*ci->pc - ci->func->f.l->code) - 1;
129− else
130− return -1; /* function is not active */
131−}
132−
133−
134−static int currentline (StkId f) {
135− if (!isLmark(f))
136− return -1; /* only active lua functions have current-line information */
94+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
95+ int status;
96+ CallInfo *ci;
97+ lua_lock(L);
98+ for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
99+ level--;
100+ if (!(ci->state & CI_C)) /* Lua function? */
101+ level -= ci->u.l.tailcalls; /* skip lost tail calls */
102+ }
103+ if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */
104+ else if (level < 0) { /* level is of a lost tail call */
105+ status = 1;
106+ ar->i_ci = 0;
107+ }
137108 else {
138− CallInfo *ci = infovalue(f);
139− int *lineinfo = ci->func->f.l->lineinfo;
140− return luaG_getline(lineinfo, currentpc(f), 1, NULL);
109+ status = 1;
110+ ar->i_ci = ci - L->base_ci;
141111 }
112+ lua_unlock(L);
113+ return status;
142114 }
143115
144116
145−
146−static Proto *getluaproto (StkId f) {
147− return (isLmark(f) ? infovalue(f)->func->f.l : NULL);
117+static Proto *getluaproto (CallInfo *ci) {
118+ return (isLua(ci) ? ci_func(ci)->l.p : NULL);
148119 }
149120
150121
151122 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
152123 const char *name;
153− StkId f = ar->_func;
154− Proto *fp = getluaproto(f);
155− if (!fp) return NULL; /* `f' is not a Lua function? */
156− name = luaF_getlocalname(fp, n, currentpc(f));
157− if (!name) return NULL;
158− luaA_pushobject(L, (f+1)+(n-1)); /* push value */
124+ CallInfo *ci;
125+ Proto *fp;
126+ lua_lock(L);
127+ name = NULL;
128+ ci = L->base_ci + ar->i_ci;
129+ fp = getluaproto(ci);
130+ if (fp) { /* is a Lua function? */
131+ name = luaF_getlocalname(fp, n, currentpc(ci));
132+ if (name)
133+ luaA_pushobject(L, ci->base+(n-1)); /* push value */
134+ }
135+ lua_unlock(L);
159136 return name;
160137 }
161138
162139
163140 LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
164141 const char *name;
165− StkId f = ar->_func;
166− Proto *fp = getluaproto(f);
142+ CallInfo *ci;
143+ Proto *fp;
144+ lua_lock(L);
145+ name = NULL;
146+ ci = L->base_ci + ar->i_ci;
147+ fp = getluaproto(ci);
167148 L->top--; /* pop new value */
168− if (!fp) return NULL; /* `f' is not a Lua function? */
169− name = luaF_getlocalname(fp, n, currentpc(f));
170− if (!name || name[0] == '(') return NULL; /* `(' starts private locals */
171− *((f+1)+(n-1)) = *L->top;
149+ if (fp) { /* is a Lua function? */
150+ name = luaF_getlocalname(fp, n, currentpc(ci));
151+ if (!name || name[0] == '(') /* `(' starts private locals */
152+ name = NULL;
153+ else
154+ setobjs2s(ci->base+(n-1), L->top);
155+ }
156+ lua_unlock(L);
172157 return name;
173158 }
174159
175160
176−static void infoLproto (lua_Debug *ar, Proto *f) {
177− ar->source = f->source->str;
178− ar->linedefined = f->lineDefined;
179− ar->what = "Lua";
180−}
181−
182−
183−static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
184− Closure *cl = NULL;
185− switch (ttype(func)) {
186− case LUA_TFUNCTION:
187− cl = clvalue(func);
188− break;
189− case LUA_TMARK:
190− cl = infovalue(func)->func;
191− break;
192− default:
193− lua_error(L, "value for `lua_getinfo' is not a function");
194− }
195− if (cl->isC) {
196− ar->source = "=C";
161+static void funcinfo (lua_Debug *ar, StkId func) {
162+ Closure *cl = clvalue(func);
163+ if (cl->c.isC) {
164+ ar->source = "=[C]";
197165 ar->linedefined = -1;
198166 ar->what = "C";
199167 }
200− else
201− infoLproto(ar, cl->f.l);
202− luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src));
203− if (ar->linedefined == 0)
204− ar->what = "main";
205−}
206−
207−
208−static const char *travtagmethods (lua_State *L, const TObject *o) {
209− if (ttype(o) == LUA_TFUNCTION) {
210− int e;
211− for (e=0; e<TM_N; e++) {
212− int t;
213− for (t=0; t<=L->last_tag; t++)
214− if (clvalue(o) == luaT_gettm(L, t, e))
215− return luaT_eventname[e];
216− }
168+ else {
169+ ar->source = getstr(cl->l.p->source);
170+ ar->linedefined = cl->l.p->lineDefined;
171+ ar->what = (ar->linedefined == 0) ? "main" : "Lua";
217172 }
218− return NULL;
173+ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
219174 }
220175
221176
222177 static const char *travglobals (lua_State *L, const TObject *o) {
223− Hash *g = L->gt;
224− int i;
225− for (i=0; i<g->size; i++) {
226− if (luaO_equalObj(o, val(node(g, i))) &&
227− ttype(key(node(g, i))) == LUA_TSTRING)
228− return tsvalue(key(node(g, i)))->str;
178+ Table *g = hvalue(gt(L));
179+ int i = sizenode(g);
180+ while (i--) {
181+ Node *n = gnode(g, i);
182+ if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n)))
183+ return getstr(tsvalue(gkey(n)));
229184 }
230185 return NULL;
231186 }
232187
233188
234−static void getname (lua_State *L, StkId f, lua_Debug *ar) {
235− TObject o;
236− setnormalized(&o, f);
237− /* try to find a name for given function */
238− if ((ar->name = travglobals(L, &o)) != NULL)
239− ar->namewhat = "global";
240− /* not found: try tag methods */
241− else if ((ar->name = travtagmethods(L, &o)) != NULL)
242− ar->namewhat = "tag-method";
243− else ar->namewhat = ""; /* not found at all */
189+static void info_tailcall (lua_State *L, lua_Debug *ar) {
190+ ar->name = ar->namewhat = "";
191+ ar->what = "tail";
192+ ar->linedefined = ar->currentline = -1;
193+ ar->source = "=(tail call)";
194+ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
195+ ar->nups = 0;
196+ setnilvalue(L->top);
244197 }
245198
246199
247−LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
248− StkId func;
249− int isactive = (*what != '>');
250− if (isactive)
251− func = ar->_func;
252− else {
253− what++; /* skip the '>' */
254− func = L->top - 1;
255− }
200+static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
201+ StkId f, CallInfo *ci) {
202+ int status = 1;
256203 for (; *what; what++) {
257204 switch (*what) {
258205 case 'S': {
259− funcinfo(L, ar, func);
206+ funcinfo(ar, f);
260207 break;
261208 }
262209 case 'l': {
263− ar->currentline = currentline(func);
210+ ar->currentline = (ci) ? currentline(ci) : -1;
264211 break;
265212 }
266213 case 'u': {
267− ar->nups = nups(func);
214+ ar->nups = clvalue(f)->c.nupvalues;
268215 break;
269216 }
270217 case 'n': {
271− ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL;
272− if (ar->namewhat == NULL)
273− getname(L, func, ar);
218+ ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL;
219+ if (ar->namewhat == NULL) {
220+ /* try to find a global name */
221+ if ((ar->name = travglobals(L, f)) != NULL)
222+ ar->namewhat = "global";
223+ else ar->namewhat = ""; /* not found */
224+ }
274225 break;
275226 }
276227 case 'f': {
277− setnormalized(L->top, func);
278− incr_top; /* push function */
228+ setobj2s(L->top, f);
279229 break;
280230 }
281− default: return 0; /* invalid option */
231+ default: status = 0; /* invalid option */
282232 }
283233 }
284− if (!isactive) L->top--; /* pop function */
285− return 1;
234+ return status;
235+}
236+
237+
238+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
239+ int status = 1;
240+ lua_lock(L);
241+ if (*what == '>') {
242+ StkId f = L->top - 1;
243+ if (!ttisfunction(f))
244+ luaG_runerror(L, "value for `lua_getinfo' is not a function");
245+ status = auxgetinfo(L, what + 1, ar, f, NULL);
246+ L->top--; /* pop function */
247+ }
248+ else if (ar->i_ci != 0) { /* no tail call? */
249+ CallInfo *ci = L->base_ci + ar->i_ci;
250+ lua_assert(ttisfunction(ci->base - 1));
251+ status = auxgetinfo(L, what, ar, ci->base - 1, ci);
252+ }
253+ else
254+ info_tailcall(L, ar);
255+ if (strchr(what, 'f')) incr_top(L);
256+ lua_unlock(L);
257+ return status;
286258 }
287259
288260
289261 /*
290262 ** {======================================================
291−** Symbolic Execution
263+** Symbolic Execution and code checker
292264 ** =======================================================
293265 */
294266
267+#define check(x) if (!(x)) return 0;
268+
269+#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
270+
271+#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
272+
273+
295274
296−static int pushpc (int *stack, int pc, int top, int n) {
297− while (n--)
298− stack[top++] = pc-1;
299− return top;
275+static int precheck (const Proto *pt) {
276+ check(pt->maxstacksize <= MAXSTACK);
277+ check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
278+ lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
279+ check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
280+ return 1;
300281 }
301282
302283
303−static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
304− int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
305− const Instruction *code = pt->code;
306− int top = pt->numparams;
307− int pc = 0;
308− if (pt->is_vararg) /* varargs? */
309− top++; /* `arg' */
310− while (pc < lastpc) {
311− const Instruction i = code[pc++];
312− LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack");
313− switch (GET_OPCODE(i)) {
314− case OP_RETURN: {
315− LUA_ASSERT(top >= GETARG_U(i), "wrong stack");
316− top = GETARG_U(i);
284+static int checkopenop (const Proto *pt, int pc) {
285+ Instruction i = pt->code[pc+1];
286+ switch (GET_OPCODE(i)) {
287+ case OP_CALL:
288+ case OP_TAILCALL:
289+ case OP_RETURN: {
290+ check(GETARG_B(i) == 0);
291+ return 1;
292+ }
293+ case OP_SETLISTO: return 1;
294+ default: return 0; /* invalid instruction after an open call */
295+ }
296+}
297+
298+
299+static int checkRK (const Proto *pt, int r) {
300+ return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));
301+}
302+
303+
304+static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
305+ int pc;
306+ int last; /* stores position of last instruction that changed `reg' */
307+ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
308+ check(precheck(pt));
309+ for (pc = 0; pc < lastpc; pc++) {
310+ const Instruction i = pt->code[pc];
311+ OpCode op = GET_OPCODE(i);
312+ int a = GETARG_A(i);
313+ int b = 0;
314+ int c = 0;
315+ checkreg(pt, a);
316+ switch (getOpMode(op)) {
317+ case iABC: {
318+ b = GETARG_B(i);
319+ c = GETARG_C(i);
320+ if (testOpMode(op, OpModeBreg)) {
321+ checkreg(pt, b);
322+ }
323+ else if (testOpMode(op, OpModeBrk))
324+ check(checkRK(pt, b));
325+ if (testOpMode(op, OpModeCrk))
326+ check(checkRK(pt, c));
317327 break;
318328 }
319− case OP_TAILCALL: {
320− LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
321− top = GETARG_B(i);
329+ case iABx: {
330+ b = GETARG_Bx(i);
331+ if (testOpMode(op, OpModeK)) check(b < pt->sizek);
332+ break;
333+ }
334+ case iAsBx: {
335+ b = GETARG_sBx(i);
322336 break;
323337 }
324− case OP_CALL: {
325− int nresults = GETARG_B(i);
326− if (nresults == MULT_RET) nresults = 1;
327− LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
328− top = pushpc(stack, pc, GETARG_A(i), nresults);
338+ }
339+ if (testOpMode(op, OpModesetA)) {
340+ if (a == reg) last = pc; /* change register `a' */
341+ }
342+ if (testOpMode(op, OpModeT)) {
343+ check(pc+2 < pt->sizecode); /* check skip */
344+ check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
345+ }
346+ switch (op) {
347+ case OP_LOADBOOL: {
348+ check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
329349 break;
330350 }
331− case OP_PUSHNIL: {
332− top = pushpc(stack, pc, top, GETARG_U(i));
351+ case OP_LOADNIL: {
352+ if (a <= reg && reg <= b)
353+ last = pc; /* set registers from `a' to `b' */
333354 break;
334355 }
335− case OP_POP: {
336− top -= GETARG_U(i);
356+ case OP_GETUPVAL:
357+ case OP_SETUPVAL: {
358+ check(b < pt->nups);
337359 break;
338360 }
339− case OP_SETTABLE:
340− case OP_SETLIST: {
341− top -= GETARG_B(i);
361+ case OP_GETGLOBAL:
362+ case OP_SETGLOBAL: {
363+ check(ttisstring(&pt->k[b]));
342364 break;
343365 }
344− case OP_SETMAP: {
345− top -= 2*GETARG_U(i);
366+ case OP_SELF: {
367+ checkreg(pt, a+1);
368+ if (reg == a+1) last = pc;
346369 break;
347370 }
348371 case OP_CONCAT: {
349− top -= GETARG_U(i);
350− stack[top++] = pc-1;
372+ /* `c' is a register, and at least two operands */
373+ check(c < MAXSTACK && b < c);
351374 break;
352375 }
353− case OP_CLOSURE: {
354− top -= GETARG_B(i);
355− stack[top++] = pc-1;
376+ case OP_TFORLOOP:
377+ checkreg(pt, a+c+5);
378+ if (reg >= a) last = pc; /* affect all registers above base */
379+ /* go through */
380+ case OP_FORLOOP:
381+ checkreg(pt, a+2);
382+ /* go through */
383+ case OP_JMP: {
384+ int dest = pc+1+b;
385+ check(0 <= dest && dest < pt->sizecode);
386+ /* not full check and jump is forward and do not skip `lastpc'? */
387+ if (reg != NO_REG && pc < dest && dest <= lastpc)
388+ pc += b; /* do the jump */
356389 break;
357390 }
358− case OP_JMPONT:
359− case OP_JMPONF: {
360− int newpc = pc + GETARG_S(i);
361− /* jump is forward and do not skip `lastpc'? */
362− if (pc < newpc && newpc <= lastpc) {
363− stack[top-1] = pc-1; /* value comes from `and'/`or' */
364− pc = newpc; /* do the jump */
391+ case OP_CALL:
392+ case OP_TAILCALL: {
393+ if (b != 0) {
394+ checkreg(pt, a+b-1);
365395 }
366− else
367− top--; /* do not jump; pop value */
396+ c--; /* c = num. returns */
397+ if (c == LUA_MULTRET) {
398+ check(checkopenop(pt, pc));
399+ }
400+ else if (c != 0)
401+ checkreg(pt, a+c-1);
402+ if (reg >= a) last = pc; /* affect all registers above base */
368403 break;
369404 }
370− default: {
371− OpCode op = GET_OPCODE(i);
372− LUA_ASSERT(luaK_opproperties[op].push != VD,
373− "invalid opcode for default");
374− top -= luaK_opproperties[op].pop;
375− LUA_ASSERT(top >= 0, "wrong stack");
376− top = pushpc(stack, pc, top, luaK_opproperties[op].push);
405+ case OP_RETURN: {
406+ b--; /* b = num. returns */
407+ if (b > 0) checkreg(pt, a+b-1);
408+ break;
409+ }
410+ case OP_SETLIST: {
411+ checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1);
412+ break;
413+ }
414+ case OP_CLOSURE: {
415+ int nup;
416+ check(b < pt->sizep);
417+ nup = pt->p[b]->nups;
418+ check(pc + nup < pt->sizecode);
419+ for (; nup>0; nup--) {
420+ OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
421+ check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
422+ }
423+ break;
377424 }
425+ default: break;
378426 }
379427 }
380− return code[stack[stackpos]];
428+ return pt->code[last];
381429 }
382430
431+#undef check
432+#undef checkjump
433+#undef checkreg
383434
384−static const char *getobjname (lua_State *L, StkId obj, const char **name) {
385− StkId func = aux_stackedfunction(L, 0, obj);
386− if (!isLmark(func))
387− return NULL; /* not an active Lua function */
388− else {
389− Proto *p = infovalue(func)->func->f.l;
390− int pc = currentpc(func);
391− int stackpos = obj - (func+1); /* func+1 == function base */
392− Instruction i = luaG_symbexec(p, pc, stackpos);
393− LUA_ASSERT(pc != -1, "function must be active");
435+/* }====================================================== */
436+
437+
438+int luaG_checkcode (const Proto *pt) {
439+ return luaG_symbexec(pt, pt->sizecode, NO_REG);
440+}
441+
442+
443+static const char *kname (Proto *p, int c) {
444+ c = c - MAXSTACK;
445+ if (c >= 0 && ttisstring(&p->k[c]))
446+ return svalue(&p->k[c]);
447+ else
448+ return "?";
449+}
450+
451+
452+static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
453+ if (isLua(ci)) { /* a Lua function? */
454+ Proto *p = ci_func(ci)->l.p;
455+ int pc = currentpc(ci);
456+ Instruction i;
457+ *name = luaF_getlocalname(p, stackpos+1, pc);
458+ if (*name) /* is a local? */
459+ return "local";
460+ i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */
461+ lua_assert(pc != -1);
394462 switch (GET_OPCODE(i)) {
395463 case OP_GETGLOBAL: {
396− *name = p->kstr[GETARG_U(i)]->str;
464+ int g = GETARG_Bx(i); /* global index */
465+ lua_assert(ttisstring(&p->k[g]));
466+ *name = svalue(&p->k[g]);
397467 return "global";
398468 }
399− case OP_GETLOCAL: {
400− *name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
401− LUA_ASSERT(*name, "local must exist");
402− return "local";
469+ case OP_MOVE: {
470+ int a = GETARG_A(i);
471+ int b = GETARG_B(i); /* move from `b' to `a' */
472+ if (b < a)
473+ return getobjname(ci, b, name); /* get name for `b' */
474+ break;
403475 }
404− case OP_PUSHSELF:
405− case OP_GETDOTTED: {
406− *name = p->kstr[GETARG_U(i)]->str;
476+ case OP_GETTABLE: {
477+ int k = GETARG_C(i); /* key index */
478+ *name = kname(p, k);
407479 return "field";
408480 }
409− default:
410− return NULL; /* no useful name found */
481+ case OP_SELF: {
482+ int k = GETARG_C(i); /* key index */
483+ *name = kname(p, k);
484+ return "method";
485+ }
486+ default: break;
411487 }
412488 }
489+ return NULL; /* no useful name found */
413490 }
414491
415492
416−static const char *getfuncname (lua_State *L, StkId f, const char **name) {
417− StkId func = aux_stackedfunction(L, 0, f); /* calling function */
418− if (!isLmark(func))
419− return NULL; /* not an active Lua function */
420− else {
421− Proto *p = infovalue(func)->func->f.l;
422− int pc = currentpc(func);
423− Instruction i;
424− if (pc == -1) return NULL; /* function is not activated */
425− i = p->code[pc];
426− switch (GET_OPCODE(i)) {
427− case OP_CALL: case OP_TAILCALL:
428− return getobjname(L, (func+1)+GETARG_A(i), name);
429− default:
430− return NULL; /* no useful name found */
431− }
432− }
493+static const char *getfuncname (CallInfo *ci, const char **name) {
494+ Instruction i;
495+ if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
496+ return NULL; /* calling function is not Lua (or is unknown) */
497+ ci--; /* calling function */
498+ i = ci_func(ci)->l.p->code[currentpc(ci)];
499+ if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)
500+ return getobjname(ci, GETARG_A(i), name);
501+ else
502+ return NULL; /* no useful name can be found */
433503 }
434504
435505
436−/* }====================================================== */
506+/* only ANSI way to check whether a pointer points to an array */
507+static int isinstack (CallInfo *ci, const TObject *o) {
508+ StkId p;
509+ for (p = ci->base; p < ci->top; p++)
510+ if (o == p) return 1;
511+ return 0;
512+}
437513
438514
439−void luaG_typeerror (lua_State *L, StkId o, const char *op) {
440− const char *name;
441− const char *kind = getobjname(L, o, &name);
442− const char *t = luaO_typename(o);
515+void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
516+ const char *name = NULL;
517+ const char *t = luaT_typenames[ttype(o)];
518+ const char *kind = (isinstack(L->ci, o)) ?
519+ getobjname(L->ci, o - L->base, &name) : NULL;
443520 if (kind)
444− luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
521+ luaG_runerror(L, "attempt to %s %s `%s' (a %s value)",
445522 op, kind, name, t);
446523 else
447− luaO_verror(L, "attempt to %.30s a %.10s value", op, t);
524+ luaG_runerror(L, "attempt to %s a %s value", op, t);
525+}
526+
527+
528+void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
529+ if (ttisstring(p1)) p1 = p2;
530+ lua_assert(!ttisstring(p1));
531+ luaG_typeerror(L, p1, "concatenate");
448532 }
449533
450534
451−void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) {
452− if (ttype(p1) == t) p1++;
453− LUA_ASSERT(ttype(p1) != t, "must be an error");
454− luaG_typeerror(L, p1, op);
535+void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) {
536+ TObject temp;
537+ if (luaV_tonumber(p1, &temp) == NULL)
538+ p2 = p1; /* first operand is wrong */
539+ luaG_typeerror(L, p2, "perform arithmetic on");
455540 }
456541
457542
458−void luaG_ordererror (lua_State *L, StkId top) {
459− const char *t1 = luaO_typename(top-2);
460− const char *t2 = luaO_typename(top-1);
543+int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
544+ const char *t1 = luaT_typenames[ttype(p1)];
545+ const char *t2 = luaT_typenames[ttype(p2)];
461546 if (t1[2] == t2[2])
462− luaO_verror(L, "attempt to compare two %.10s values", t1);
547+ luaG_runerror(L, "attempt to compare two %s values", t1);
463548 else
464− luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2);
549+ luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
550+ return 0;
551+}
552+
553+
554+static void addinfo (lua_State *L, const char *msg) {
555+ CallInfo *ci = L->ci;
556+ if (isLua(ci)) { /* is Lua code? */
557+ char buff[LUA_IDSIZE]; /* add file:line information */
558+ int line = currentline(ci);
559+ luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
560+ luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
561+ }
562+}
563+
564+
565+void luaG_errormsg (lua_State *L) {
566+ if (L->errfunc != 0) { /* is there an error handling function? */
567+ StkId errfunc = restorestack(L, L->errfunc);
568+ if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
569+ setobjs2s(L->top, L->top - 1); /* move argument */
570+ setobjs2s(L->top - 1, errfunc); /* push function */
571+ incr_top(L);
572+ luaD_call(L, L->top - 2, 1); /* call it */
573+ }
574+ luaD_throw(L, LUA_ERRRUN);
575+}
576+
577+
578+void luaG_runerror (lua_State *L, const char *fmt, ...) {
579+ va_list argp;
580+ va_start(argp, fmt);
581+ addinfo(L, luaO_pushvfstring(L, fmt, argp));
582+ va_end(argp);
583+ luaG_errormsg(L);
465584 }
466585
src/ldebug.h+16−6
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp $
2+** $Id: ldebug.h,v 1.32 2002/11/18 11:01:55 roberto Exp $
33 ** Auxiliary functions from Debug Interface module
44 ** See Copyright Notice in lua.h
55 */
@@ -9,13 +9,23 @@ · 3 unmodified lines
99
1010
1111 #include "lstate.h"
12−#include "luadebug.h"
1312
1413
15−void luaG_typeerror (lua_State *L, StkId o, const char *op);
16−void luaG_binerror (lua_State *L, StkId p1, int t, const char *op);
17−int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
18−void luaG_ordererror (lua_State *L, StkId top);
14+#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15+
16+#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
17+
18+#define resethookcount(L) (L->hookcount = L->basehookcount)
19+
20+
21+void luaG_inithooks (lua_State *L);
22+void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
23+void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
24+void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
25+int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
26+void luaG_runerror (lua_State *L, const char *fmt, ...);
27+void luaG_errormsg (lua_State *L);
28+int luaG_checkcode (const Proto *pt);
1929
2030
2131 #endif
src/ldo.c+347−277
@@ -1,22 +1,25 @@
11 /*
2−** $Id: ldo.c,v 1.109a 2000/10/30 12:38:50 roberto Exp $
2+** $Id: ldo.c,v 1.217 2003/04/03 13:35:34 roberto Exp $
33 ** Stack and Call structure of Lua
44 ** See Copyright Notice in lua.h
55 */
66
77
88 #include <setjmp.h>
9−#include <stdio.h>
109 #include <stdlib.h>
1110 #include <string.h>
1211
12+#define ldo_c
13+
1314 #include "lua.h"
1415
1516 #include "ldebug.h"
1617 #include "ldo.h"
18+#include "lfunc.h"
1719 #include "lgc.h"
1820 #include "lmem.h"
1921 #include "lobject.h"
22+#include "lopcodes.h"
2023 #include "lparser.h"
2124 #include "lstate.h"
2225 #include "lstring.h"
@@ -27,362 +30,429 @@ · 4 unmodified lines
2730 #include "lzio.h"
2831
2932
30−/* space to handle stack overflow errors */
31−#define EXTRA_STACK (2*LUA_MINSTACK)
3233
3334
34−void luaD_init (lua_State *L, int stacksize) {
35− L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
36− L->nblocks += stacksize*sizeof(TObject);
37− L->stack_last = L->stack+(stacksize-1);
38− L->stacksize = stacksize;
39− L->Cbase = L->top = L->stack;
40−}
35+/*
36+** {======================================================
37+** Error-recovery functions (based on long jumps)
38+** =======================================================
39+*/
4140
4241
43−void luaD_checkstack (lua_State *L, int n) {
44− if (L->stack_last - L->top <= n) { /* stack overflow? */
45− if (L->stack_last-L->stack > (L->stacksize-1)) {
46− /* overflow while handling overflow */
47− luaD_breakrun(L, LUA_ERRERR); /* break run without error message */
42+/* chain list of long jump buffers */
43+struct lua_longjmp {
44+ struct lua_longjmp *previous;
45+ jmp_buf b;
46+ volatile int status; /* error code */
47+};
48+
49+
50+static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
51+ switch (errcode) {
52+ case LUA_ERRMEM: {
53+ setsvalue2s(oldtop, luaS_new(L, MEMERRMSG));
54+ break;
55+ }
56+ case LUA_ERRERR: {
57+ setsvalue2s(oldtop, luaS_new(L, "error in error handling"));
58+ break;
4859 }
49− else {
50− L->stack_last += EXTRA_STACK; /* to be used by error message */
51− lua_error(L, "stack overflow");
60+ case LUA_ERRSYNTAX:
61+ case LUA_ERRRUN: {
62+ setobjs2s(oldtop, L->top - 1); /* error message on current top */
63+ break;
5264 }
5365 }
66+ L->top = oldtop + 1;
67+}
68+
69+
70+void luaD_throw (lua_State *L, int errcode) {
71+ if (L->errorJmp) {
72+ L->errorJmp->status = errcode;
73+ longjmp(L->errorJmp->b, 1);
74+ }
75+ else {
76+ G(L)->panic(L);
77+ exit(EXIT_FAILURE);
78+ }
79+}
80+
81+
82+int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
83+ struct lua_longjmp lj;
84+ lj.status = 0;
85+ lj.previous = L->errorJmp; /* chain new error handler */
86+ L->errorJmp = &lj;
87+ if (setjmp(lj.b) == 0)
88+ (*f)(L, ud);
89+ L->errorJmp = lj.previous; /* restore old error handler */
90+ return lj.status;
5491 }
5592
5693
5794 static void restore_stack_limit (lua_State *L) {
58− if (L->top - L->stack < L->stacksize - 1)
59− L->stack_last = L->stack + (L->stacksize-1);
95+ L->stack_last = L->stack+L->stacksize-1;
96+ if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */
97+ int inuse = (L->ci - L->base_ci);
98+ if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */
99+ luaD_reallocCI(L, LUA_MAXCALLS);
100+ }
60101 }
61102
103+/* }====================================================== */
62104
63−/*
64−** Adjust stack. Set top to base+extra, pushing NILs if needed.
65−** (we cannot add base+extra unless we are sure it fits in the stack;
66−** otherwise the result of such operation on pointers is undefined)
67−*/
68−void luaD_adjusttop (lua_State *L, StkId base, int extra) {
69− int diff = extra-(L->top-base);
70− if (diff <= 0)
71− L->top = base+extra;
72− else {
73− luaD_checkstack(L, diff);
74− while (diff--)
75− ttype(L->top++) = LUA_TNIL;
105+
106+static void correctstack (lua_State *L, TObject *oldstack) {
107+ CallInfo *ci;
108+ GCObject *up;
109+ L->top = (L->top - oldstack) + L->stack;
110+ for (up = L->openupval; up != NULL; up = up->gch.next)
111+ gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack;
112+ for (ci = L->base_ci; ci <= L->ci; ci++) {
113+ ci->top = (ci->top - oldstack) + L->stack;
114+ ci->base = (ci->base - oldstack) + L->stack;
76115 }
116+ L->base = L->ci->base;
77117 }
78118
79119
80−/*
81−** Open a hole inside the stack at `pos'
82−*/
83−static void luaD_openstack (lua_State *L, StkId pos) {
84− int i = L->top-pos;
85− while (i--) pos[i+1] = pos[i];
86− incr_top;
120+void luaD_reallocstack (lua_State *L, int newsize) {
121+ TObject *oldstack = L->stack;
122+ luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject);
123+ L->stacksize = newsize;
124+ L->stack_last = L->stack+newsize-1-EXTRA_STACK;
125+ correctstack(L, oldstack);
87126 }
88127
89128
90−static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
91− StkId old_Cbase = L->Cbase;
92− StkId old_top = L->Cbase = L->top;
93− luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
94− L->allowhooks = 0; /* cannot call hooks inside a hook */
95− (*hook)(L, ar);
96− LUA_ASSERT(L->allowhooks == 0, "invalid allow");
97− L->allowhooks = 1;
98− L->top = old_top;
99− L->Cbase = old_Cbase;
129+void luaD_reallocCI (lua_State *L, int newsize) {
130+ CallInfo *oldci = L->base_ci;
131+ luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
132+ L->size_ci = cast(unsigned short, newsize);
133+ L->ci = (L->ci - oldci) + L->base_ci;
134+ L->end_ci = L->base_ci + L->size_ci;
100135 }
101136
102137
103−void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
104− if (L->allowhooks) {
105− lua_Debug ar;
106− ar._func = func;
107− ar.event = "line";
108− ar.currentline = line;
109− dohook(L, &ar, linehook);
138+void luaD_growstack (lua_State *L, int n) {
139+ if (n <= L->stacksize) /* double size is enough? */
140+ luaD_reallocstack(L, 2*L->stacksize);
141+ else
142+ luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK);
143+}
144+
145+
146+static void luaD_growCI (lua_State *L) {
147+ if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
148+ luaD_throw(L, LUA_ERRERR);
149+ else {
150+ luaD_reallocCI(L, 2*L->size_ci);
151+ if (L->size_ci > LUA_MAXCALLS)
152+ luaG_runerror(L, "stack overflow");
110153 }
111154 }
112155
113156
114−static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
115− const char *event) {
116− if (L->allowhooks) {
157+void luaD_callhook (lua_State *L, int event, int line) {
158+ lua_Hook hook = L->hook;
159+ if (hook && L->allowhook) {
160+ ptrdiff_t top = savestack(L, L->top);
161+ ptrdiff_t ci_top = savestack(L, L->ci->top);
117162 lua_Debug ar;
118− ar._func = func;
119163 ar.event = event;
120− infovalue(func)->pc = NULL; /* function is not active */
121− dohook(L, &ar, callhook);
164+ ar.currentline = line;
165+ if (event == LUA_HOOKTAILRET)
166+ ar.i_ci = 0; /* tail call; no debug information about it */
167+ else
168+ ar.i_ci = L->ci - L->base_ci;
169+ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
170+ L->ci->top = L->top + LUA_MINSTACK;
171+ L->allowhook = 0; /* cannot call hooks inside a hook */
172+ lua_unlock(L);
173+ (*hook)(L, &ar);
174+ lua_lock(L);
175+ lua_assert(!L->allowhook);
176+ L->allowhook = 1;
177+ L->ci->top = restorestack(L, ci_top);
178+ L->top = restorestack(L, top);
122179 }
123180 }
124181
125182
126−static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
127− int nup = cl->nupvalues; /* number of upvalues */
128− StkId old_Cbase = L->Cbase;
129− int n;
130− L->Cbase = base; /* new base for C function */
131− luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
132− for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
133− *(L->top++) = cl->upvalue[n];
134− n = (*cl->f.c)(L); /* do the actual call */
135− L->Cbase = old_Cbase; /* restore old C base */
136− return L->top - n; /* return index of first result */
183+static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
184+ int i;
185+ Table *htab;
186+ TObject nname;
187+ int actual = L->top - base; /* actual number of arguments */
188+ if (actual < nfixargs) {
189+ luaD_checkstack(L, nfixargs - actual);
190+ for (; actual < nfixargs; ++actual)
191+ setnilvalue(L->top++);
192+ }
193+ actual -= nfixargs; /* number of extra arguments */
194+ htab = luaH_new(L, actual, 1); /* create `arg' table */
195+ for (i=0; i<actual; i++) /* put extra arguments into `arg' table */
196+ setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i);
197+ /* store counter in field `n' */
198+ setsvalue(&nname, luaS_newliteral(L, "n"));
199+ setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual));
200+ L->top -= actual; /* remove extra elements from the stack */
201+ sethvalue(L->top, htab);
202+ incr_top(L);
137203 }
138204
139205
140−void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) {
141− StkId base = L->top - nParams;
142− luaD_openstack(L, base);
143− clvalue(base) = f;
144− ttype(base) = LUA_TFUNCTION;
145− luaD_call(L, base, nResults);
206+static StkId tryfuncTM (lua_State *L, StkId func) {
207+ const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
208+ StkId p;
209+ ptrdiff_t funcr = savestack(L, func);
210+ if (!ttisfunction(tm))
211+ luaG_typeerror(L, func, "call");
212+ /* Open a hole inside the stack at `func' */
213+ for (p = L->top; p > func; p--) setobjs2s(p, p-1);
214+ incr_top(L);
215+ func = restorestack(L, funcr); /* previous call may change stack */
216+ setobj2s(func, tm); /* tag method is the new function to be called */
217+ return func;
146218 }
147219
148220
149−/*
150−** Call a function (C or Lua). The function to be called is at *func.
151−** The arguments are on the stack, right after the function.
152−** When returns, the results are on the stack, starting at the original
153−** function position.
154−** The number of results is nResults, unless nResults=LUA_MULTRET.
155−*/
156−void luaD_call (lua_State *L, StkId func, int nResults) {
157− lua_Hook callhook;
158− StkId firstResult;
159− CallInfo ci;
160− Closure *cl;
161− if (ttype(func) != LUA_TFUNCTION) {
162− /* `func' is not a function; check the `function' tag method */
163− Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION);
164− if (tm == NULL)
165− luaG_typeerror(L, func, "call");
166− luaD_openstack(L, func);
167− clvalue(func) = tm; /* tag method is the new function to be called */
168− ttype(func) = LUA_TFUNCTION;
221+StkId luaD_precall (lua_State *L, StkId func) {
222+ LClosure *cl;
223+ ptrdiff_t funcr = savestack(L, func);
224+ if (!ttisfunction(func)) /* `func' is not a function? */
225+ func = tryfuncTM(L, func); /* check the `function' tag method */
226+ if (L->ci + 1 == L->end_ci) luaD_growCI(L);
227+ else condhardstacktests(luaD_reallocCI(L, L->size_ci));
228+ cl = &clvalue(func)->l;
229+ if (!cl->isC) { /* Lua function? prepare its call */
230+ CallInfo *ci;
231+ Proto *p = cl->p;
232+ if (p->is_vararg) /* varargs? */
233+ adjust_varargs(L, p->numparams, func+1);
234+ luaD_checkstack(L, p->maxstacksize);
235+ ci = ++L->ci; /* now `enter' new function */
236+ L->base = L->ci->base = restorestack(L, funcr) + 1;
237+ ci->top = L->base + p->maxstacksize;
238+ ci->u.l.savedpc = p->code; /* starting point */
239+ ci->u.l.tailcalls = 0;
240+ ci->state = CI_SAVEDPC;
241+ while (L->top < ci->top)
242+ setnilvalue(L->top++);
243+ L->top = ci->top;
244+ return NULL;
169245 }
170− cl = clvalue(func);
171− ci.func = cl;
172− infovalue(func) = &ci;
173− ttype(func) = LUA_TMARK;
174− callhook = L->callhook;
175− if (callhook)
176− luaD_callHook(L, func, callhook, "call");
177− firstResult = (cl->isC ? callCclosure(L, cl, func+1) :
178− luaV_execute(L, cl, func+1));
179− if (callhook) /* same hook that was active at entry */
180− luaD_callHook(L, func, callhook, "return");
181− LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag");
182− /* move results to `func' (to erase parameters and function) */
183− if (nResults == LUA_MULTRET) {
184− while (firstResult < L->top) /* copy all results */
185− *func++ = *firstResult++;
186− L->top = func;
246+ else { /* if is a C function, call it */
247+ CallInfo *ci;
248+ int n;
249+ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
250+ ci = ++L->ci; /* now `enter' new function */
251+ L->base = L->ci->base = restorestack(L, funcr) + 1;
252+ ci->top = L->top + LUA_MINSTACK;
253+ ci->state = CI_C; /* a C function */
254+ if (L->hookmask & LUA_MASKCALL)
255+ luaD_callhook(L, LUA_HOOKCALL, -1);
256+ lua_unlock(L);
257+#ifdef LUA_COMPATUPVALUES
258+ lua_pushupvalues(L);
259+#endif
260+ n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */
261+ lua_lock(L);
262+ return L->top - n;
187263 }
188− else { /* copy at most `nResults' */
189− for (; nResults > 0 && firstResult < L->top; nResults--)
190− *func++ = *firstResult++;
191− L->top = func;
192− for (; nResults > 0; nResults--) { /* if there are not enough results */
193− ttype(L->top) = LUA_TNIL; /* adjust the stack */
194− incr_top; /* must check stack space */
195− }
196− }
197− luaC_checkGC(L);
198264 }
199265
200266
201−/*
202−** Execute a protected call.
203−*/
204−struct CallS { /* data to `f_call' */
205− StkId func;
206− int nresults;
207−};
208−
209−static void f_call (lua_State *L, void *ud) {
210− struct CallS *c = (struct CallS *)ud;
211− luaD_call(L, c->func, c->nresults);
267+static StkId callrethooks (lua_State *L, StkId firstResult) {
268+ ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
269+ luaD_callhook(L, LUA_HOOKRET, -1);
270+ if (!(L->ci->state & CI_C)) { /* Lua function? */
271+ while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
272+ luaD_callhook(L, LUA_HOOKTAILRET, -1);
273+ }
274+ return restorestack(L, fr);
212275 }
213276
214277
215−LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
216− StkId func = L->top - (nargs+1); /* function to be called */
217− struct CallS c;
218− int status;
219− c.func = func; c.nresults = nresults;
220− status = luaD_runprotected(L, f_call, &c);
221− if (status != 0) /* an error occurred? */
222− L->top = func; /* remove parameters from the stack */
223− return status;
278+void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
279+ StkId res;
280+ if (L->hookmask & LUA_MASKRET)
281+ firstResult = callrethooks(L, firstResult);
282+ res = L->base - 1; /* res == final position of 1st result */
283+ L->ci--;
284+ L->base = L->ci->base; /* restore base */
285+ /* move results to correct place */
286+ while (wanted != 0 && firstResult < L->top) {
287+ setobjs2s(res++, firstResult++);
288+ wanted--;
289+ }
290+ while (wanted-- > 0)
291+ setnilvalue(res++);
292+ L->top = res;
224293 }
225294
226295
227296 /*
228−** Execute a protected parser.
229−*/
230−struct ParserS { /* data to `f_parser' */
231− ZIO *z;
232− int bin;
233−};
234−
235−static void f_parser (lua_State *L, void *ud) {
236− struct ParserS *p = (struct ParserS *)ud;
237− Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
238− luaV_Lclosure(L, tf, 0);
297+** Call a function (C or Lua). The function to be called is at *func.
298+** The arguments are on the stack, right after the function.
299+** When returns, all the results are on the stack, starting at the original
300+** function position.
301+*/
302+void luaD_call (lua_State *L, StkId func, int nResults) {
303+ StkId firstResult;
304+ lua_assert(!(L->ci->state & CI_CALLING));
305+ if (++L->nCcalls >= LUA_MAXCCALLS) {
306+ if (L->nCcalls == LUA_MAXCCALLS)
307+ luaG_runerror(L, "C stack overflow");
308+ else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
309+ luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
310+ }
311+ firstResult = luaD_precall(L, func);
312+ if (firstResult == NULL) /* is a Lua function? */
313+ firstResult = luaV_execute(L); /* call it */
314+ luaD_poscall(L, nResults, firstResult);
315+ L->nCcalls--;
316+ luaC_checkGC(L);
239317 }
240318
241319
242−static int protectedparser (lua_State *L, ZIO *z, int bin) {
243− struct ParserS p;
244− unsigned long old_blocks;
245− int status;
246− p.z = z; p.bin = bin;
247− /* before parsing, give a (good) chance to GC */
248− if (L->nblocks/8 >= L->GCthreshold/10)
249− luaC_collectgarbage(L);
250− old_blocks = L->nblocks;
251− status = luaD_runprotected(L, f_parser, &p);
252− if (status == 0) {
253− /* add new memory to threshold (as it probably will stay) */
254− L->GCthreshold += (L->nblocks - old_blocks);
320+static void resume (lua_State *L, void *ud) {
321+ StkId firstResult;
322+ int nargs = *cast(int *, ud);
323+ CallInfo *ci = L->ci;
324+ if (ci == L->base_ci) { /* no activation record? */
325+ if (nargs >= L->top - L->base)
326+ luaG_runerror(L, "cannot resume dead coroutine");
327+ luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */
255328 }
256− else if (status == LUA_ERRRUN) /* an error occurred: correct error code */
257− status = LUA_ERRSYNTAX;
258− return status;
329+ else if (ci->state & CI_YIELD) { /* inside a yield? */
330+ if (ci->state & CI_C) { /* `common' yield? */
331+ /* finish interrupted execution of `OP_CALL' */
332+ int nresults;
333+ lua_assert((ci-1)->state & CI_SAVEDPC);
334+ lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
335+ GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
336+ nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
337+ luaD_poscall(L, nresults, L->top - nargs); /* complete it */
338+ if (nresults >= 0) L->top = L->ci->top;
339+ }
340+ else { /* yielded inside a hook: just continue its execution */
341+ ci->state &= ~CI_YIELD;
342+ }
343+ }
344+ else
345+ luaG_runerror(L, "cannot resume non-suspended coroutine");
346+ firstResult = luaV_execute(L);
347+ if (firstResult != NULL) /* return? */
348+ luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
259349 }
260350
261351
262−static int parse_file (lua_State *L, const char *filename) {
263− ZIO z;
352+LUA_API int lua_resume (lua_State *L, int nargs) {
264353 int status;
265− int bin; /* flag for file mode */
266− int c; /* look ahead char */
267− FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
268− if (f == NULL) return LUA_ERRFILE; /* unable to open file */
269− c = fgetc(f);
270− ungetc(c, f);
271− bin = (c == ID_CHUNK);
272− if (bin && f != stdin) {
273− f = freopen(filename, "rb", f); /* set binary mode */
274− if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */
354+ lu_byte old_allowhooks;
355+ lua_lock(L);
356+ old_allowhooks = L->allowhook;
357+ lua_assert(L->errfunc == 0 && L->nCcalls == 0);
358+ status = luaD_rawrunprotected(L, resume, &nargs);
359+ if (status != 0) { /* error? */
360+ L->ci = L->base_ci; /* go back to initial level */
361+ L->base = L->ci->base;
362+ L->nCcalls = 0;
363+ luaF_close(L, L->base); /* close eventual pending closures */
364+ seterrorobj(L, status, L->base);
365+ L->allowhook = old_allowhooks;
366+ restore_stack_limit(L);
275367 }
276− lua_pushstring(L, "@");
277− lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
278− lua_concat(L, 2);
279− c = lua_gettop(L);
280− filename = lua_tostring(L, c); /* filename = '@'..filename */
281− luaZ_Fopen(&z, f, filename);
282− status = protectedparser(L, &z, bin);
283− lua_remove(L, c); /* remove `filename' from the stack */
284− if (f != stdin)
285− fclose(f);
286− return status;
287−}
288−
289−
290−LUA_API int lua_dofile (lua_State *L, const char *filename) {
291− int status = parse_file(L, filename);
292− if (status == 0) /* parse OK? */
293− status = lua_call(L, 0, LUA_MULTRET); /* call main */
368+ lua_unlock(L);
294369 return status;
295370 }
296371
297372
298−static int parse_buffer (lua_State *L, const char *buff, size_t size,
299− const char *name) {
300− ZIO z;
301− if (!name) name = "?";
302− luaZ_mopen(&z, buff, size, name);
303− return protectedparser(L, &z, buff[0]==ID_CHUNK);
373+LUA_API int lua_yield (lua_State *L, int nresults) {
374+ CallInfo *ci;
375+ lua_lock(L);
376+ ci = L->ci;
377+ if (L->nCcalls > 0)
378+ luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
379+ if (ci->state & CI_C) { /* usual yield */
380+ if ((ci-1)->state & CI_C)
381+ luaG_runerror(L, "cannot yield a C function");
382+ if (L->top - nresults > L->base) { /* is there garbage in the stack? */
383+ int i;
384+ for (i=0; i<nresults; i++) /* move down results */
385+ setobjs2s(L->base + i, L->top - nresults + i);
386+ L->top = L->base + nresults;
387+ }
388+ } /* else it's an yield inside a hook: nothing to do */
389+ ci->state |= CI_YIELD;
390+ lua_unlock(L);
391+ return -1;
304392 }
305393
306394
307−LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
308− int status = parse_buffer(L, buff, size, name);
309− if (status == 0) /* parse OK? */
310− status = lua_call(L, 0, LUA_MULTRET); /* call main */
395+int luaD_pcall (lua_State *L, Pfunc func, void *u,
396+ ptrdiff_t old_top, ptrdiff_t ef) {
397+ int status;
398+ unsigned short oldnCcalls = L->nCcalls;
399+ ptrdiff_t old_ci = saveci(L, L->ci);
400+ lu_byte old_allowhooks = L->allowhook;
401+ ptrdiff_t old_errfunc = L->errfunc;
402+ L->errfunc = ef;
403+ status = luaD_rawrunprotected(L, func, u);
404+ if (status != 0) { /* an error occurred? */
405+ StkId oldtop = restorestack(L, old_top);
406+ luaF_close(L, oldtop); /* close eventual pending closures */
407+ seterrorobj(L, status, oldtop);
408+ L->nCcalls = oldnCcalls;
409+ L->ci = restoreci(L, old_ci);
410+ L->base = L->ci->base;
411+ L->allowhook = old_allowhooks;
412+ restore_stack_limit(L);
413+ }
414+ L->errfunc = old_errfunc;
311415 return status;
312416 }
313417
314418
315−LUA_API int lua_dostring (lua_State *L, const char *str) {
316− return lua_dobuffer(L, str, strlen(str), str);
317−}
318−
319419
320420 /*
321−** {======================================================
322−** Error-recover functions (based on long jumps)
323−** =======================================================
421+** Execute a protected parser.
324422 */
325−
326−/* chain list of long jump buffers */
327−struct lua_longjmp {
328− jmp_buf b;
329− struct lua_longjmp *previous;
330− volatile int status; /* error code */
423+struct SParser { /* data to `f_parser' */
424+ ZIO *z;
425+ Mbuffer buff; /* buffer to be used by the scanner */
426+ int bin;
331427 };
332428
333−
334−static void message (lua_State *L, const char *s) {
335− const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE);
336− if (ttype(em) == LUA_TFUNCTION) {
337− *L->top = *em;
338− incr_top;
339− lua_pushstring(L, s);
340− luaD_call(L, L->top-2, 0);
341− }
342−}
343−
344−
345−/*
346−** Reports an error, and jumps up to the available recovery label
347−*/
348−LUA_API void lua_error (lua_State *L, const char *s) {
349− if (s) message(L, s);
350− luaD_breakrun(L, LUA_ERRRUN);
351−}
352−
353−
354−void luaD_breakrun (lua_State *L, int errcode) {
355− if (L->errorJmp) {
356− L->errorJmp->status = errcode;
357− longjmp(L->errorJmp->b, 1);
358− }
359− else {
360− if (errcode != LUA_ERRMEM)
361− message(L, "unable to recover; exiting\n");
362− exit(EXIT_FAILURE);
363− }
429+static void f_parser (lua_State *L, void *ud) {
430+ struct SParser *p;
431+ Proto *tf;
432+ Closure *cl;
433+ luaC_checkGC(L);
434+ p = cast(struct SParser *, ud);
435+ tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
436+ cl = luaF_newLclosure(L, 0, gt(L));
437+ cl->l.p = tf;
438+ setclvalue(L->top, cl);
439+ incr_top(L);
364440 }
365441
366442
367−int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
368− StkId oldCbase = L->Cbase;
369− StkId oldtop = L->top;
370− struct lua_longjmp lj;
371− int allowhooks = L->allowhooks;
372− lj.status = 0;
373− lj.previous = L->errorJmp; /* chain new error handler */
374− L->errorJmp = &lj;
375− if (setjmp(lj.b) == 0)
376− (*f)(L, ud);
377− else { /* an error occurred: restore the state */
378− L->allowhooks = allowhooks;
379− L->Cbase = oldCbase;
380− L->top = oldtop;
381− restore_stack_limit(L);
443+int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
444+ struct SParser p;
445+ int status;
446+ ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */
447+ p.z = z; p.bin = bin;
448+ luaZ_initbuffer(L, &p.buff);
449+ status = luaD_rawrunprotected(L, f_parser, &p);
450+ luaZ_freebuffer(L, &p.buff);
451+ if (status != 0) { /* error? */
452+ StkId oldtop = restorestack(L, oldtopr);
453+ seterrorobj(L, status, oldtop);
382454 }
383− L->errorJmp = lj.previous; /* restore old error handler */
384− return lj.status;
455+ return status;
385456 }
386457
387−/* }====================================================== */
388458
src/ldo.h+40−13
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp $
2+** $Id: ldo.h,v 1.56 2002/12/04 17:29:32 roberto Exp $
33 ** Stack and Call structure of Lua
44 ** See Copyright Notice in lua.h
55 */
@@ -10,24 +10,51 @@ · 4 unmodified lines
1010
1111 #include "lobject.h"
1212 #include "lstate.h"
13+#include "lzio.h"
1314
1415
1516 /*
16−** macro to increment stack top.
17−** There must be always an empty slot at the L->stack.top
18−*/
19−#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
17+** macro to control inclusion of some hard tests on stack reallocation
18+*/
19+#ifndef HARDSTACKTESTS
20+#define condhardstacktests(x) { /* empty */ }
21+#else
22+#define condhardstacktests(x) x
23+#endif
2024
2125
22−void luaD_init (lua_State *L, int stacksize);
23−void luaD_adjusttop (lua_State *L, StkId base, int extra);
24−void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
25−void luaD_call (lua_State *L, StkId func, int nResults);
26−void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
27−void luaD_checkstack (lua_State *L, int n);
26+#define luaD_checkstack(L,n) \
27+ if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TObject)) \
28+ luaD_growstack(L, n); \
29+ else condhardstacktests(luaD_reallocstack(L, L->stacksize));
30+
31+
32+#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
2833
29−void luaD_breakrun (lua_State *L, int errcode);
30−int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);
34+#define savestack(L,p) ((char *)(p) - (char *)L->stack)
35+#define restorestack(L,n) ((TObject *)((char *)L->stack + (n)))
36+
37+#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
38+#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
39+
40+
41+/* type of protected functions, to be ran by `runprotected' */
42+typedef void (*Pfunc) (lua_State *L, void *ud);
43+
44+void luaD_resetprotection (lua_State *L);
45+int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
46+void luaD_callhook (lua_State *L, int event, int line);
47+StkId luaD_precall (lua_State *L, StkId func);
48+void luaD_call (lua_State *L, StkId func, int nResults);
49+int luaD_pcall (lua_State *L, Pfunc func, void *u,
50+ ptrdiff_t oldtop, ptrdiff_t ef);
51+void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
52+void luaD_reallocCI (lua_State *L, int newsize);
53+void luaD_reallocstack (lua_State *L, int newsize);
54+void luaD_growstack (lua_State *L, int n);
55+
56+void luaD_throw (lua_State *L, int errcode);
57+int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
3158
3259
3360 #endif
src/ldump.c+170−0
@@ -0,0 +1,170 @@
1+/*
2+** $Id: ldump.c,v 1.4 2003/02/11 23:52:12 lhf Exp $
3+** save bytecodes
4+** See Copyright Notice in lua.h
5+*/
6+
7+#include <stddef.h>
8+
9+#define ldump_c
10+
11+#include "lua.h"
12+
13+#include "lobject.h"
14+#include "lopcodes.h"
15+#include "lstate.h"
16+#include "lundump.h"
17+
18+#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D)
19+#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
20+
21+typedef struct {
22+ lua_State* L;
23+ lua_Chunkwriter write;
24+ void* data;
25+} DumpState;
26+
27+static void DumpBlock(const void* b, size_t size, DumpState* D)
28+{
29+ lua_unlock(D->L);
30+ (*D->write)(D->L,b,size,D->data);
31+ lua_lock(D->L);
32+}
33+
34+static void DumpByte(int y, DumpState* D)
35+{
36+ char x=(char)y;
37+ DumpBlock(&x,sizeof(x),D);
38+}
39+
40+static void DumpInt(int x, DumpState* D)
41+{
42+ DumpBlock(&x,sizeof(x),D);
43+}
44+
45+static void DumpSize(size_t x, DumpState* D)
46+{
47+ DumpBlock(&x,sizeof(x),D);
48+}
49+
50+static void DumpNumber(lua_Number x, DumpState* D)
51+{
52+ DumpBlock(&x,sizeof(x),D);
53+}
54+
55+static void DumpString(TString* s, DumpState* D)
56+{
57+ if (s==NULL || getstr(s)==NULL)
58+ DumpSize(0,D);
59+ else
60+ {
61+ size_t size=s->tsv.len+1; /* include trailing '\0' */
62+ DumpSize(size,D);
63+ DumpBlock(getstr(s),size,D);
64+ }
65+}
66+
67+static void DumpCode(const Proto* f, DumpState* D)
68+{
69+ DumpInt(f->sizecode,D);
70+ DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
71+}
72+
73+static void DumpLocals(const Proto* f, DumpState* D)
74+{
75+ int i,n=f->sizelocvars;
76+ DumpInt(n,D);
77+ for (i=0; i<n; i++)
78+ {
79+ DumpString(f->locvars[i].varname,D);
80+ DumpInt(f->locvars[i].startpc,D);
81+ DumpInt(f->locvars[i].endpc,D);
82+ }
83+}
84+
85+static void DumpLines(const Proto* f, DumpState* D)
86+{
87+ DumpInt(f->sizelineinfo,D);
88+ DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
89+}
90+
91+static void DumpUpvalues(const Proto* f, DumpState* D)
92+{
93+ int i,n=f->sizeupvalues;
94+ DumpInt(n,D);
95+ for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
96+}
97+
98+static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
99+
100+static void DumpConstants(const Proto* f, DumpState* D)
101+{
102+ int i,n;
103+ DumpInt(n=f->sizek,D);
104+ for (i=0; i<n; i++)
105+ {
106+ const TObject* o=&f->k[i];
107+ DumpByte(ttype(o),D);
108+ switch (ttype(o))
109+ {
110+ case LUA_TNUMBER:
111+ DumpNumber(nvalue(o),D);
112+ break;
113+ case LUA_TSTRING:
114+ DumpString(tsvalue(o),D);
115+ break;
116+ case LUA_TNIL:
117+ break;
118+ default:
119+ lua_assert(0); /* cannot happen */
120+ break;
121+ }
122+ }
123+ DumpInt(n=f->sizep,D);
124+ for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
125+}
126+
127+static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
128+{
129+ DumpString((f->source==p) ? NULL : f->source,D);
130+ DumpInt(f->lineDefined,D);
131+ DumpByte(f->nups,D);
132+ DumpByte(f->numparams,D);
133+ DumpByte(f->is_vararg,D);
134+ DumpByte(f->maxstacksize,D);
135+ DumpLines(f,D);
136+ DumpLocals(f,D);
137+ DumpUpvalues(f,D);
138+ DumpConstants(f,D);
139+ DumpCode(f,D);
140+}
141+
142+static void DumpHeader(DumpState* D)
143+{
144+ DumpLiteral(LUA_SIGNATURE,D);
145+ DumpByte(VERSION,D);
146+ DumpByte(luaU_endianness(),D);
147+ DumpByte(sizeof(int),D);
148+ DumpByte(sizeof(size_t),D);
149+ DumpByte(sizeof(Instruction),D);
150+ DumpByte(SIZE_OP,D);
151+ DumpByte(SIZE_A,D);
152+ DumpByte(SIZE_B,D);
153+ DumpByte(SIZE_C,D);
154+ DumpByte(sizeof(lua_Number),D);
155+ DumpNumber(TEST_NUMBER,D);
156+}
157+
158+/*
159+** dump function as precompiled chunk
160+*/
161+void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
162+{
163+ DumpState D;
164+ D.L=L;
165+ D.write=w;
166+ D.data=data;
167+ DumpHeader(&D);
168+ DumpFunction(Main,NULL,&D);
169+}
170+
src/lfunc.c+78−52
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lfunc.c,v 1.34 2000/10/30 12:20:29 roberto Exp $
2+** $Id: lfunc.c,v 1.67 2003/03/18 12:50:04 roberto Exp $
33 ** Auxiliary functions to manipulate prototypes and closures
44 ** See Copyright Notice in lua.h
55 */
@@ -7,87 +7,113 @@ · 1 unmodified line
77
88 #include <stdlib.h>
99
10+#define lfunc_c
11+
1012 #include "lua.h"
1113
1214 #include "lfunc.h"
15+#include "lgc.h"
1316 #include "lmem.h"
17+#include "lobject.h"
1418 #include "lstate.h"
1519
1620
17−#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1))
21+#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
22+ cast(int, sizeof(TObject)*((n)-1)))
23+
24+#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
25+ cast(int, sizeof(TObject *)*((n)-1)))
26+
1827
1928
20−Closure *luaF_newclosure (lua_State *L, int nelems) {
21− int size = sizeclosure(nelems);
22− Closure *c = (Closure *)luaM_malloc(L, size);
23− c->next = L->rootcl;
24− L->rootcl = c;
25− c->mark = c;
26− c->nupvalues = nelems;
27− L->nblocks += size;
29+Closure *luaF_newCclosure (lua_State *L, int nelems) {
30+ Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
31+ luaC_link(L, valtogco(c), LUA_TFUNCTION);
32+ c->c.isC = 1;
33+ c->c.nupvalues = cast(lu_byte, nelems);
2834 return c;
2935 }
3036
3137
38+Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) {
39+ Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
40+ luaC_link(L, valtogco(c), LUA_TFUNCTION);
41+ c->l.isC = 0;
42+ c->l.g = *e;
43+ c->l.nupvalues = cast(lu_byte, nelems);
44+ return c;
45+}
46+
47+
48+UpVal *luaF_findupval (lua_State *L, StkId level) {
49+ GCObject **pp = &L->openupval;
50+ UpVal *p;
51+ UpVal *v;
52+ while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
53+ if (p->v == level) return p;
54+ pp = &p->next;
55+ }
56+ v = luaM_new(L, UpVal); /* not found: create a new one */
57+ v->tt = LUA_TUPVAL;
58+ v->marked = 1; /* open upvalues should not be collected */
59+ v->v = level; /* current value lives in the stack */
60+ v->next = *pp; /* chain it in the proper position */
61+ *pp = valtogco(v);
62+ return v;
63+}
64+
65+
66+void luaF_close (lua_State *L, StkId level) {
67+ UpVal *p;
68+ while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) {
69+ setobj(&p->value, p->v); /* save current value (write barrier) */
70+ p->v = &p->value; /* now current value lives here */
71+ L->openupval = p->next; /* remove from `open' list */
72+ luaC_link(L, valtogco(p), LUA_TUPVAL);
73+ }
74+}
75+
76+
3277 Proto *luaF_newproto (lua_State *L) {
3378 Proto *f = luaM_new(L, Proto);
34− f->knum = NULL;
35− f->nknum = 0;
36− f->kstr = NULL;
37− f->nkstr = 0;
38− f->kproto = NULL;
39− f->nkproto = 0;
79+ luaC_link(L, valtogco(f), LUA_TPROTO);
80+ f->k = NULL;
81+ f->sizek = 0;
82+ f->p = NULL;
83+ f->sizep = 0;
4084 f->code = NULL;
41− f->ncode = 0;
85+ f->sizecode = 0;
86+ f->sizelineinfo = 0;
87+ f->sizeupvalues = 0;
88+ f->nups = 0;
89+ f->upvalues = NULL;
4290 f->numparams = 0;
4391 f->is_vararg = 0;
4492 f->maxstacksize = 0;
45− f->marked = 0;
4693 f->lineinfo = NULL;
47− f->nlineinfo = 0;
48− f->nlocvars = 0;
94+ f->sizelocvars = 0;
4995 f->locvars = NULL;
5096 f->lineDefined = 0;
5197 f->source = NULL;
52− f->next = L->rootproto; /* chain in list of protos */
53− L->rootproto = f;
5498 return f;
5599 }
56100
57101
58−static size_t protosize (Proto *f) {
59− return sizeof(Proto)
60− + f->nknum*sizeof(Number)
61− + f->nkstr*sizeof(TString *)
62− + f->nkproto*sizeof(Proto *)
63− + f->ncode*sizeof(Instruction)
64− + f->nlocvars*sizeof(struct LocVar)
65− + f->nlineinfo*sizeof(int);
66−}
67−
68−
69−void luaF_protook (lua_State *L, Proto *f, int pc) {
70− f->ncode = pc; /* signal that proto was properly created */
71− L->nblocks += protosize(f);
72−}
73−
74−
75102 void luaF_freeproto (lua_State *L, Proto *f) {
76− if (f->ncode > 0) /* function was properly created? */
77− L->nblocks -= protosize(f);
78− luaM_free(L, f->code);
79− luaM_free(L, f->locvars);
80− luaM_free(L, f->kstr);
81− luaM_free(L, f->knum);
82− luaM_free(L, f->kproto);
83− luaM_free(L, f->lineinfo);
84− luaM_free(L, f);
103+ luaM_freearray(L, f->code, f->sizecode, Instruction);
104+ luaM_freearray(L, f->p, f->sizep, Proto *);
105+ luaM_freearray(L, f->k, f->sizek, TObject);
106+ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
107+ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
108+ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
109+ luaM_freelem(L, f);
85110 }
86111
87112
88113 void luaF_freeclosure (lua_State *L, Closure *c) {
89− L->nblocks -= sizeclosure(c->nupvalues);
90− luaM_free(L, c);
114+ int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
115+ sizeLclosure(c->l.nupvalues);
116+ luaM_free(L, c, size);
91117 }
92118
93119
@@ -97,11 +123,11 @@ void luaF_freeclosure (lua_State *L, Closure *c) { · 3 unmodified lines
97123 */
98124 const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
99125 int i;
100− for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
126+ for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
101127 if (pc < f->locvars[i].endpc) { /* is variable active? */
102128 local_number--;
103129 if (local_number == 0)
104− return f->locvars[i].varname->str;
130+ return getstr(f->locvars[i].varname);
105131 }
106132 }
107133 return NULL; /* not found */
src/lfunc.h+5−4
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lfunc.h,v 1.13 2000/09/29 12:42:13 roberto Exp $
2+** $Id: lfunc.h,v 1.21 2003/03/18 12:50:04 roberto Exp $
33 ** Auxiliary functions to manipulate prototypes and closures
44 ** See Copyright Notice in lua.h
55 */
@@ -11,10 +11,11 @@ · 5 unmodified lines
1111 #include "lobject.h"
1212
1313
14−
1514 Proto *luaF_newproto (lua_State *L);
16−void luaF_protook (lua_State *L, Proto *f, int pc);
17−Closure *luaF_newclosure (lua_State *L, int nelems);
15+Closure *luaF_newCclosure (lua_State *L, int nelems);
16+Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e);
17+UpVal *luaF_findupval (lua_State *L, StkId level);
18+void luaF_close (lua_State *L, StkId level);
1819 void luaF_freeproto (lua_State *L, Proto *f);
1920 void luaF_freeclosure (lua_State *L, Closure *c);
2021
src/lgc.c+377−237
@@ -1,11 +1,16 @@
11 /*
2−** $Id: lgc.c,v 1.72+ 2000/10/26 12:47:05 roberto Exp $
2+** $Id: lgc.c,v 1.171 2003/04/03 13:35:34 roberto Exp $
33 ** Garbage Collector
44 ** See Copyright Notice in lua.h
55 */
66
7+#include <string.h>
8+
9+#define lgc_c
10+
711 #include "lua.h"
812
13+#include "ldebug.h"
914 #include "ldo.h"
1015 #include "lfunc.h"
1116 #include "lgc.h"
@@ -18,336 +23,471 @@ · 6 unmodified lines
1823
1924
2025 typedef struct GCState {
21− Hash *tmark; /* list of marked tables to be visited */
22− Closure *cmark; /* list of marked closures to be visited */
26+ GCObject *tmark; /* list of marked objects to be traversed */
27+ GCObject *wk; /* list of traversed key-weak tables (to be cleared) */
28+ GCObject *wv; /* list of traversed value-weak tables */
29+ GCObject *wkv; /* list of traversed key-value weak tables */
30+ global_State *g;
2331 } GCState;
2432
2533
34+/*
35+** some userful bit tricks
36+*/
37+#define setbit(x,b) ((x) |= (1<<(b)))
38+#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b))))
39+#define testbit(x,b) ((x) & (1<<(b)))
2640
27−static void markobject (GCState *st, TObject *o);
41+#define unmark(x) resetbit((x)->gch.marked, 0)
42+#define ismarked(x) ((x)->gch.marked & ((1<<4)|1))
2843
44+#define stringmark(s) setbit((s)->tsv.marked, 0)
2945
30−/* mark a string; marks larger than 1 cannot be changed */
31−#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;}
3246
47+#define isfinalized(u) (!testbit((u)->uv.marked, 1))
48+#define markfinalized(u) resetbit((u)->uv.marked, 1)
3349
3450
35−static void protomark (Proto *f) {
36− if (!f->marked) {
37− int i;
38− f->marked = 1;
39− strmark(f->source);
40− for (i=0; i<f->nkstr; i++)
41− strmark(f->kstr[i]);
42− for (i=0; i<f->nkproto; i++)
43− protomark(f->kproto[i]);
44− for (i=0; i<f->nlocvars; i++) /* mark local-variable names */
45− strmark(f->locvars[i].varname);
46− }
47−}
51+#define KEYWEAKBIT 1
52+#define VALUEWEAKBIT 2
53+#define KEYWEAK (1<<KEYWEAKBIT)
54+#define VALUEWEAK (1<<VALUEWEAKBIT)
4855
4956
50−static void markstack (lua_State *L, GCState *st) {
51− StkId o;
52− for (o=L->stack; o<L->top; o++)
53− markobject(st, o);
54−}
5557
58+#define markobject(st,o) { checkconsistency(o); \
59+ if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
5660
57−static void marklock (lua_State *L, GCState *st) {
58− int i;
59− for (i=0; i<L->refSize; i++) {
60− if (L->refArray[i].st == LOCK)
61− markobject(st, &L->refArray[i].o);
61+#define condmarkobject(st,o,c) { checkconsistency(o); \
62+ if (iscollectable(o) && !ismarked(gcvalue(o)) && (c)) \
63+ reallymarkobject(st,gcvalue(o)); }
64+
65+#define markvalue(st,t) { if (!ismarked(valtogco(t))) \
66+ reallymarkobject(st, valtogco(t)); }
67+
68+
69+
70+static void reallymarkobject (GCState *st, GCObject *o) {
71+ lua_assert(!ismarked(o));
72+ setbit(o->gch.marked, 0); /* mark object */
73+ switch (o->gch.tt) {
74+ case LUA_TUSERDATA: {
75+ markvalue(st, gcotou(o)->uv.metatable);
76+ break;
77+ }
78+ case LUA_TFUNCTION: {
79+ gcotocl(o)->c.gclist = st->tmark;
80+ st->tmark = o;
81+ break;
82+ }
83+ case LUA_TTABLE: {
84+ gcotoh(o)->gclist = st->tmark;
85+ st->tmark = o;
86+ break;
87+ }
88+ case LUA_TTHREAD: {
89+ gcototh(o)->gclist = st->tmark;
90+ st->tmark = o;
91+ break;
92+ }
93+ case LUA_TPROTO: {
94+ gcotop(o)->gclist = st->tmark;
95+ st->tmark = o;
96+ break;
97+ }
98+ default: lua_assert(o->gch.tt == LUA_TSTRING);
6299 }
63100 }
64101
65102
66−static void markclosure (GCState *st, Closure *cl) {
67− if (!ismarked(cl)) {
68− if (!cl->isC)
69− protomark(cl->f.l);
70− cl->mark = st->cmark; /* chain it for later traversal */
71− st->cmark = cl;
103+static void marktmu (GCState *st) {
104+ GCObject *u;
105+ for (u = st->g->tmudata; u; u = u->gch.next) {
106+ unmark(u); /* may be marked, if left from previous GC */
107+ reallymarkobject(st, u);
72108 }
73109 }
74110
75111
76−static void marktagmethods (lua_State *L, GCState *st) {
77− int e;
78− for (e=0; e<TM_N; e++) {
79− int t;
80− for (t=0; t<=L->last_tag; t++) {
81− Closure *cl = luaT_gettm(L, t, e);
82− if (cl) markclosure(st, cl);
112+/* move `dead' udata that need finalization to list `tmudata' */
113+void luaC_separateudata (lua_State *L) {
114+ GCObject **p = &G(L)->rootudata;
115+ GCObject *curr;
116+ GCObject *collected = NULL; /* to collect udata with gc event */
117+ GCObject **lastcollected = &collected;
118+ while ((curr = *p) != NULL) {
119+ lua_assert(curr->gch.tt == LUA_TUSERDATA);
120+ if (ismarked(curr) || isfinalized(gcotou(curr)))
121+ p = &curr->gch.next; /* don't bother with them */
122+
123+ else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
124+ markfinalized(gcotou(curr)); /* don't need finalization */
125+ p = &curr->gch.next;
126+ }
127+ else { /* must call its gc method */
128+ *p = curr->gch.next;
129+ curr->gch.next = NULL; /* link `curr' at the end of `collected' list */
130+ *lastcollected = curr;
131+ lastcollected = &curr->gch.next;
83132 }
84133 }
134+ /* insert collected udata with gc event into `tmudata' list */
135+ *lastcollected = G(L)->tmudata;
136+ G(L)->tmudata = collected;
85137 }
86138
87139
88−static void markobject (GCState *st, TObject *o) {
89− switch (ttype(o)) {
90− case LUA_TUSERDATA: case LUA_TSTRING:
91− strmark(tsvalue(o));
92− break;
93− case LUA_TMARK:
94− markclosure(st, infovalue(o)->func);
95− break;
96− case LUA_TFUNCTION:
97− markclosure(st, clvalue(o));
98− break;
99− case LUA_TTABLE: {
100− if (!ismarked(hvalue(o))) {
101− hvalue(o)->mark = st->tmark; /* chain it in list of marked */
102− st->tmark = hvalue(o);
103− }
104− break;
105− }
106− default: break; /* numbers, etc */
107− }
140+static void removekey (Node *n) {
141+ setnilvalue(gval(n)); /* remove corresponding value ... */
142+ if (iscollectable(gkey(n)))
143+ setttype(gkey(n), LUA_TNONE); /* dead key; remove it */
108144 }
109145
110146
111−static void markall (lua_State *L) {
112− GCState st;
113− st.cmark = NULL;
114− st.tmark = L->gt; /* put table of globals in mark list */
115− L->gt->mark = NULL;
116− marktagmethods(L, &st); /* mark tag methods */
117− markstack(L, &st); /* mark stack objects */
118− marklock(L, &st); /* mark locked objects */
119− for (;;) { /* mark tables and closures */
120− if (st.cmark) {
121− int i;
122− Closure *f = st.cmark; /* get first closure from list */
123− st.cmark = f->mark; /* remove it from list */
124− for (i=0; i<f->nupvalues; i++) /* mark its upvalues */
125− markobject(&st, &f->upvalue[i]);
147+static void traversetable (GCState *st, Table *h) {
148+ int i;
149+ int weakkey = 0;
150+ int weakvalue = 0;
151+ const TObject *mode;
152+ markvalue(st, h->metatable);
153+ lua_assert(h->lsizenode || h->node == st->g->dummynode);
154+ mode = gfasttm(st->g, h->metatable, TM_MODE);
155+ if (mode && ttisstring(mode)) { /* is there a weak mode? */
156+ weakkey = (strchr(svalue(mode), 'k') != NULL);
157+ weakvalue = (strchr(svalue(mode), 'v') != NULL);
158+ if (weakkey || weakvalue) { /* is really weak? */
159+ GCObject **weaklist;
160+ h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
161+ h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
162+ (weakvalue << VALUEWEAKBIT));
163+ weaklist = (weakkey && weakvalue) ? &st->wkv :
164+ (weakkey) ? &st->wk :
165+ &st->wv;
166+ h->gclist = *weaklist; /* must be cleared after GC, ... */
167+ *weaklist = valtogco(h); /* ... so put in the appropriate list */
126168 }
127− else if (st.tmark) {
128− int i;
129− Hash *h = st.tmark; /* get first table from list */
130− st.tmark = h->mark; /* remove it from list */
131− for (i=0; i<h->size; i++) {
132− Node *n = node(h, i);
133− if (ttype(key(n)) != LUA_TNIL) {
134− if (ttype(val(n)) == LUA_TNIL)
135− luaH_remove(h, key(n)); /* dead element; try to remove it */
136− markobject(&st, &n->key);
137− markobject(&st, &n->val);
138− }
139− }
169+ }
170+ if (!weakvalue) {
171+ i = h->sizearray;
172+ while (i--)
173+ markobject(st, &h->array[i]);
174+ }
175+ i = sizenode(h);
176+ while (i--) {
177+ Node *n = gnode(h, i);
178+ if (!ttisnil(gval(n))) {
179+ lua_assert(!ttisnil(gkey(n)));
180+ condmarkobject(st, gkey(n), !weakkey);
181+ condmarkobject(st, gval(n), !weakvalue);
140182 }
141− else break; /* nothing else to mark */
142183 }
143184 }
144185
145186
146−static int hasmark (const TObject *o) {
147− /* valid only for locked objects */
148− switch (o->ttype) {
149− case LUA_TSTRING: case LUA_TUSERDATA:
150− return tsvalue(o)->marked;
151− case LUA_TTABLE:
152− return ismarked(hvalue(o));
153− case LUA_TFUNCTION:
154− return ismarked(clvalue(o));
155− default: /* number */
156− return 1;
187+static void traverseproto (GCState *st, Proto *f) {
188+ int i;
189+ stringmark(f->source);
190+ for (i=0; i<f->sizek; i++) { /* mark literal strings */
191+ if (ttisstring(f->k+i))
192+ stringmark(tsvalue(f->k+i));
157193 }
194+ for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */
195+ stringmark(f->upvalues[i]);
196+ for (i=0; i<f->sizep; i++) /* mark nested protos */
197+ markvalue(st, f->p[i]);
198+ for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
199+ stringmark(f->locvars[i].varname);
200+ lua_assert(luaG_checkcode(f));
158201 }
159202
160203
161−/* macro for internal debugging; check if a link of free refs is valid */
162−#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
163204
164−static void invalidaterefs (lua_State *L) {
165− int n = L->refSize;
166− int i;
167− for (i=0; i<n; i++) {
168− struct Ref *r = &L->refArray[i];
169− if (r->st == HOLD && !hasmark(&r->o))
170− r->st = COLLECTED;
171− LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
172− (r->st == HOLD && hasmark(&r->o)) ||
173− r->st == COLLECTED ||
174− r->st == NONEXT ||
175− (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
176− "inconsistent ref table");
205+static void traverseclosure (GCState *st, Closure *cl) {
206+ if (cl->c.isC) {
207+ int i;
208+ for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
209+ markobject(st, &cl->c.upvalue[i]);
210+ }
211+ else {
212+ int i;
213+ lua_assert(cl->l.nupvalues == cl->l.p->nups);
214+ markvalue(st, hvalue(&cl->l.g));
215+ markvalue(st, cl->l.p);
216+ for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
217+ UpVal *u = cl->l.upvals[i];
218+ if (!u->marked) {
219+ markobject(st, &u->value);
220+ u->marked = 1;
221+ }
222+ }
177223 }
178− LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
179224 }
180225
181226
227+static void checkstacksizes (lua_State *L, StkId max) {
228+ int used = L->ci - L->base_ci; /* number of `ci' in use */
229+ if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
230+ luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
231+ else condhardstacktests(luaD_reallocCI(L, L->size_ci));
232+ used = max - L->stack; /* part of stack in use */
233+ if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
234+ luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
235+ else condhardstacktests(luaD_reallocstack(L, L->stacksize));
236+}
182237
183−static void collectproto (lua_State *L) {
184− Proto **p = &L->rootproto;
185− Proto *next;
186− while ((next = *p) != NULL) {
187− if (next->marked) {
188− next->marked = 0;
189− p = &next->next;
190− }
191− else {
192− *p = next->next;
193− luaF_freeproto(L, next);
194− }
238+
239+static void traversestack (GCState *st, lua_State *L1) {
240+ StkId o, lim;
241+ CallInfo *ci;
242+ markobject(st, gt(L1));
243+ lim = L1->top;
244+ for (ci = L1->base_ci; ci <= L1->ci; ci++) {
245+ lua_assert(ci->top <= L1->stack_last);
246+ lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC));
247+ if (!(ci->state & CI_C) && lim < ci->top)
248+ lim = ci->top;
195249 }
250+ for (o = L1->stack; o < L1->top; o++)
251+ markobject(st, o);
252+ for (; o <= lim; o++)
253+ setnilvalue(o);
254+ checkstacksizes(L1, lim);
196255 }
197256
198257
199−static void collectclosure (lua_State *L) {
200− Closure **p = &L->rootcl;
201− Closure *next;
202− while ((next = *p) != NULL) {
203− if (ismarked(next)) {
204− next->mark = next; /* unmark */
205− p = &next->next;
258+static void propagatemarks (GCState *st) {
259+ while (st->tmark) { /* traverse marked objects */
260+ switch (st->tmark->gch.tt) {
261+ case LUA_TTABLE: {
262+ Table *h = gcotoh(st->tmark);
263+ st->tmark = h->gclist;
264+ traversetable(st, h);
265+ break;
266+ }
267+ case LUA_TFUNCTION: {
268+ Closure *cl = gcotocl(st->tmark);
269+ st->tmark = cl->c.gclist;
270+ traverseclosure(st, cl);
271+ break;
272+ }
273+ case LUA_TTHREAD: {
274+ lua_State *th = gcototh(st->tmark);
275+ st->tmark = th->gclist;
276+ traversestack(st, th);
277+ break;
278+ }
279+ case LUA_TPROTO: {
280+ Proto *p = gcotop(st->tmark);
281+ st->tmark = p->gclist;
282+ traverseproto(st, p);
283+ break;
284+ }
285+ default: lua_assert(0);
206286 }
207− else {
208− *p = next->next;
209− luaF_freeclosure(L, next);
287+ }
288+}
289+
290+
291+static int valismarked (const TObject *o) {
292+ if (ttisstring(o))
293+ stringmark(tsvalue(o)); /* strings are `values', so are never weak */
294+ return !iscollectable(o) || testbit(o->value.gc->gch.marked, 0);
295+}
296+
297+
298+/*
299+** clear collected keys from weaktables
300+*/
301+static void cleartablekeys (GCObject *l) {
302+ while (l) {
303+ Table *h = gcotoh(l);
304+ int i = sizenode(h);
305+ lua_assert(h->marked & KEYWEAK);
306+ while (i--) {
307+ Node *n = gnode(h, i);
308+ if (!valismarked(gkey(n))) /* key was collected? */
309+ removekey(n); /* remove entry from table */
210310 }
311+ l = h->gclist;
211312 }
212313 }
213314
214315
215−static void collecttable (lua_State *L) {
216− Hash **p = &L->roottable;
217− Hash *next;
218− while ((next = *p) != NULL) {
219− if (ismarked(next)) {
220− next->mark = next; /* unmark */
221− p = &next->next;
316+/*
317+** clear collected values from weaktables
318+*/
319+static void cleartablevalues (GCObject *l) {
320+ while (l) {
321+ Table *h = gcotoh(l);
322+ int i = h->sizearray;
323+ lua_assert(h->marked & VALUEWEAK);
324+ while (i--) {
325+ TObject *o = &h->array[i];
326+ if (!valismarked(o)) /* value was collected? */
327+ setnilvalue(o); /* remove value */
222328 }
223− else {
224− *p = next->next;
225− luaH_free(L, next);
329+ i = sizenode(h);
330+ while (i--) {
331+ Node *n = gnode(h, i);
332+ if (!valismarked(gval(n))) /* value was collected? */
333+ removekey(n); /* remove entry from table */
226334 }
335+ l = h->gclist;
227336 }
228337 }
229338
230339
231−static void checktab (lua_State *L, stringtable *tb) {
232− if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10)
233− luaS_resize(L, tb, tb->size/2); /* table is too big */
340+static void freeobj (lua_State *L, GCObject *o) {
341+ switch (o->gch.tt) {
342+ case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break;
343+ case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break;
344+ case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break;
345+ case LUA_TTABLE: luaH_free(L, gcotoh(o)); break;
346+ case LUA_TTHREAD: {
347+ lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread);
348+ luaE_freethread(L, gcototh(o));
349+ break;
350+ }
351+ case LUA_TSTRING: {
352+ luaM_free(L, o, sizestring(gcotots(o)->tsv.len));
353+ break;
354+ }
355+ case LUA_TUSERDATA: {
356+ luaM_free(L, o, sizeudata(gcotou(o)->uv.len));
357+ break;
358+ }
359+ default: lua_assert(0);
360+ }
234361 }
235362
236363
237−static void collectstrings (lua_State *L, int all) {
238− int i;
239− for (i=0; i<L->strt.size; i++) { /* for each list */
240− TString **p = &L->strt.hash[i];
241− TString *next;
242− while ((next = *p) != NULL) {
243− if (next->marked && !all) { /* preserve? */
244− if (next->marked < FIXMARK) /* does not change FIXMARKs */
245− next->marked = 0;
246− p = &next->nexthash;
247− }
248− else { /* collect */
249− *p = next->nexthash;
250− L->strt.nuse--;
251− L->nblocks -= sizestring(next->len);
252− luaM_free(L, next);
253− }
364+static int sweeplist (lua_State *L, GCObject **p, int limit) {
365+ GCObject *curr;
366+ int count = 0; /* number of collected items */
367+ while ((curr = *p) != NULL) {
368+ if (curr->gch.marked > limit) {
369+ unmark(curr);
370+ p = &curr->gch.next;
371+ }
372+ else {
373+ count++;
374+ *p = curr->gch.next;
375+ freeobj(L, curr);
254376 }
255377 }
256− checktab(L, &L->strt);
378+ return count;
257379 }
258380
259381
260−static void collectudata (lua_State *L, int all) {
382+static void sweepstrings (lua_State *L, int all) {
261383 int i;
262− for (i=0; i<L->udt.size; i++) { /* for each list */
263− TString **p = &L->udt.hash[i];
264− TString *next;
265− while ((next = *p) != NULL) {
266− LUA_ASSERT(next->marked <= 1, "udata cannot be fixed");
267− if (next->marked && !all) { /* preserve? */
268− next->marked = 0;
269− p = &next->nexthash;
270− }
271− else { /* collect */
272− int tag = next->u.d.tag;
273− *p = next->nexthash;
274− next->nexthash = L->TMtable[tag].collected; /* chain udata */
275− L->TMtable[tag].collected = next;
276− L->nblocks -= sizestring(next->len);
277− L->udt.nuse--;
278− }
279− }
384+ for (i=0; i<G(L)->strt.size; i++) { /* for each list */
385+ G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all);
280386 }
281− checktab(L, &L->udt);
282387 }
283388
284389
285−#define MINBUFFER 256
286−static void checkMbuffer (lua_State *L) {
287− if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
288− size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */
289− L->nblocks += (newsize - L->Mbuffsize)*sizeof(char);
290− L->Mbuffsize = newsize;
291− luaM_reallocvector(L, L->Mbuffer, newsize, char);
390+static void checkSizes (lua_State *L) {
391+ /* check size of string hash */
392+ if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) &&
393+ G(L)->strt.size > MINSTRTABSIZE*2)
394+ luaS_resize(L, G(L)->strt.size/2); /* table is too big */
395+ /* check size of buffer */
396+ if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
397+ size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2;
398+ luaZ_resizebuffer(L, &G(L)->buff, newsize);
292399 }
400+ G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
293401 }
294402
295403
296−static void callgcTM (lua_State *L, const TObject *o) {
297− Closure *tm = luaT_gettmbyObj(L, o, TM_GC);
404+static void do1gcTM (lua_State *L, Udata *udata) {
405+ const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC);
298406 if (tm != NULL) {
299− int oldah = L->allowhooks;
300− L->allowhooks = 0; /* stop debug hooks during GC tag methods */
301− luaD_checkstack(L, 2);
302− clvalue(L->top) = tm;
303− ttype(L->top) = LUA_TFUNCTION;
304− *(L->top+1) = *o;
407+ setobj2s(L->top, tm);
408+ setuvalue(L->top+1, udata);
305409 L->top += 2;
306− luaD_call(L, L->top-2, 0);
307− L->allowhooks = oldah; /* restore hooks */
410+ luaD_call(L, L->top - 2, 0);
308411 }
309412 }
310413
311414
312−static void callgcTMudata (lua_State *L) {
313− int tag;
314− TObject o;
315− ttype(&o) = LUA_TUSERDATA;
316− L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */
317− for (tag=L->last_tag; tag>=0; tag--) { /* for each tag (in reverse order) */
318− TString *udata;
319− while ((udata = L->TMtable[tag].collected) != NULL) {
320− L->TMtable[tag].collected = udata->nexthash; /* remove it from list */
321− tsvalue(&o) = udata;
322− callgcTM(L, &o);
323− luaM_free(L, udata);
324− }
415+void luaC_callGCTM (lua_State *L) {
416+ lu_byte oldah = L->allowhook;
417+ L->allowhook = 0; /* stop debug hooks during GC tag methods */
418+ L->top++; /* reserve space to keep udata while runs its gc method */
419+ while (G(L)->tmudata != NULL) {
420+ GCObject *o = G(L)->tmudata;
421+ Udata *udata = gcotou(o);
422+ G(L)->tmudata = udata->uv.next; /* remove udata from `tmudata' */
423+ udata->uv.next = G(L)->rootudata; /* return it to `root' list */
424+ G(L)->rootudata = o;
425+ setuvalue(L->top - 1, udata); /* keep a reference to it */
426+ unmark(o);
427+ markfinalized(udata);
428+ do1gcTM(L, udata);
325429 }
430+ L->top--;
431+ L->allowhook = oldah; /* restore hooks */
326432 }
327433
328434
329−void luaC_collect (lua_State *L, int all) {
330− collectudata(L, all);
331− callgcTMudata(L);
332− collectstrings(L, all);
333− collecttable(L);
334− collectproto(L);
335− collectclosure(L);
435+void luaC_sweep (lua_State *L, int all) {
436+ if (all) all = 256; /* larger than any mark */
437+ sweeplist(L, &G(L)->rootudata, all);
438+ sweepstrings(L, all);
439+ sweeplist(L, &G(L)->rootgc, all);
440+}
441+
442+
443+/* mark root set */
444+static void markroot (GCState *st, lua_State *L) {
445+ global_State *g = st->g;
446+ markobject(st, defaultmeta(L));
447+ markobject(st, registry(L));
448+ traversestack(st, g->mainthread);
449+ if (L != g->mainthread) /* another thread is running? */
450+ markvalue(st, L); /* cannot collect it */
451+}
452+
453+
454+static void mark (lua_State *L) {
455+ GCState st;
456+ GCObject *wkv;
457+ st.g = G(L);
458+ st.tmark = NULL;
459+ st.wkv = st.wk = st.wv = NULL;
460+ markroot(&st, L);
461+ propagatemarks(&st); /* mark all reachable objects */
462+ cleartablevalues(st.wkv);
463+ cleartablevalues(st.wv);
464+ wkv = st.wkv; /* keys must be cleared after preserving udata */
465+ st.wkv = NULL;
466+ st.wv = NULL;
467+ luaC_separateudata(L); /* separate userdata to be preserved */
468+ marktmu(&st); /* mark `preserved' userdata */
469+ propagatemarks(&st); /* remark, to propagate `preserveness' */
470+ cleartablekeys(wkv);
471+ /* `propagatemarks' may resuscitate some weak tables; clear them too */
472+ cleartablekeys(st.wk);
473+ cleartablevalues(st.wv);
474+ cleartablekeys(st.wkv);
475+ cleartablevalues(st.wkv);
336476 }
337477
338478
339479 void luaC_collectgarbage (lua_State *L) {
340− markall(L);
341− invalidaterefs(L); /* check unlocked references */
342− luaC_collect(L, 0);
343− checkMbuffer(L);
344− L->GCthreshold = 2*L->nblocks; /* set new threshold */
345− callgcTM(L, &luaO_nilobject);
480+ mark(L);
481+ luaC_sweep(L, 0);
482+ checkSizes(L);
483+ luaC_callGCTM(L);
346484 }
347485
348486
349−void luaC_checkGC (lua_State *L) {
350− if (L->nblocks >= L->GCthreshold)
351− luaC_collectgarbage(L);
487+void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
488+ o->gch.next = G(L)->rootgc;
489+ G(L)->rootgc = o;
490+ o->gch.marked = 0;
491+ o->gch.tt = tt;
352492 }
353493
src/lgc.h+9−3
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lgc.h,v 1.9 2001/02/02 16:23:20 roberto Exp $
2+** $Id: lgc.h,v 1.19 2003/02/28 19:45:15 roberto Exp $
33 ** Garbage Collector
44 ** See Copyright Notice in lua.h
55 */
@@ -11,9 +11,15 @@ · 5 unmodified lines
1111 #include "lobject.h"
1212
1313
14−void luaC_collect (lua_State *L, int all);
14+#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \
15+ if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); }
16+
17+
18+void luaC_separateudata (lua_State *L);
19+void luaC_callGCTM (lua_State *L);
20+void luaC_sweep (lua_State *L, int all);
1521 void luaC_collectgarbage (lua_State *L);
16−void luaC_checkGC (lua_State *L);
22+void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
1723
1824
1925 #endif
src/lib/Makefile+5−6
@@ -4,17 +4,16 @@ LUA= ../.. · 3 unmodified lines
44
55 include $(LUA)/config
66
7−# actually only used in liolib.c
8−EXTRA_DEFS= $(POPEN)
7+EXTRA_DEFS= $(POPEN) $(TMPNAM) $(DEGREES) $(LOADLIB)
98
10−OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o lstrlib.o
11−SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c lstrlib.c
9+OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o ltablib.o lstrlib.o loadlib.o
10+SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c ltablib.c lstrlib.c loadlib.c
1211
1312 T= $(LIB)/liblualib.a
1413
15−all: $T
14+all: $T
1615
17−$T: $(OBJS)
16+$T: $(OBJS)
1817 $(AR) $@ $(OBJS)
1918 $(RANLIB) $@
2019
src/lib/README+6−4
@@ -1,6 +1,8 @@
11 This is the standard Lua library.
2−It is implemented entirely on top of the official Lua API as declared in lua.h,
3−using lauxlib.c, which contains several useful functions for writing libraries.
4−We encourage developers to use lauxlib.c in their own libraries.
2+
53 The code of the standard library can be read as an example of how to export
6−C functions to Lua.
4+C functions to Lua. The easiest library to read is lmathlib.c.
5+
6+The library is implemented entirely on top of the official Lua API as declared
7+in lua.h, using lauxlib.c, which contains several useful functions for writing
8+libraries. We encourage developers to use lauxlib.c in their own libraries.
src/lib/lauxlib.c+433−58
@@ -1,25 +1,101 @@
11 /*
2−** $Id: lauxlib.c,v 1.43 2000/10/30 13:07:48 roberto Exp $
2+** $Id: lauxlib.c,v 1.100 2003/04/07 14:35:00 roberto Exp $
33 ** Auxiliary functions for building Lua libraries
44 ** See Copyright Notice in lua.h
55 */
66
77
8+#include <ctype.h>
9+#include <errno.h>
810 #include <stdarg.h>
911 #include <stdio.h>
1012 #include <string.h>
1113
14+
1215 /* This file uses only the official API of Lua.
1316 ** Any function declared here could be written as an application function.
14−** With care, these functions can be used by other libraries.
1517 */
1618
19+#define lauxlib_c
20+
1721 #include "lua.h"
1822
1923 #include "lauxlib.h"
20−#include "luadebug.h"
2124
2225
26+/* number of prereserved references (for internal use) */
27+#define RESERVED_REFS 2
28+
29+/* reserved references */
30+#define FREELIST_REF 1 /* free list of references */
31+#define ARRAYSIZE_REF 2 /* array sizes */
32+
33+
34+/* convert a stack index to positive */
35+#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
36+ lua_gettop(L) + (i) + 1)
37+
38+
39+/*
40+** {======================================================
41+** Error-report functions
42+** =======================================================
43+*/
44+
45+
46+LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
47+ lua_Debug ar;
48+ lua_getstack(L, 0, &ar);
49+ lua_getinfo(L, "n", &ar);
50+ if (strcmp(ar.namewhat, "method") == 0) {
51+ narg--; /* do not count `self' */
52+ if (narg == 0) /* error is in the self argument itself? */
53+ return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg);
54+ }
55+ if (ar.name == NULL)
56+ ar.name = "?";
57+ return luaL_error(L, "bad argument #%d to `%s' (%s)",
58+ narg, ar.name, extramsg);
59+}
60+
61+
62+LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
63+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
64+ tname, lua_typename(L, lua_type(L,narg)));
65+ return luaL_argerror(L, narg, msg);
66+}
67+
68+
69+static void tag_error (lua_State *L, int narg, int tag) {
70+ luaL_typerror(L, narg, lua_typename(L, tag));
71+}
72+
73+
74+LUALIB_API void luaL_where (lua_State *L, int level) {
75+ lua_Debug ar;
76+ if (lua_getstack(L, level, &ar)) { /* check function at level */
77+ lua_getinfo(L, "Snl", &ar); /* get info about it */
78+ if (ar.currentline > 0) { /* is there info? */
79+ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
80+ return;
81+ }
82+ }
83+ lua_pushliteral(L, ""); /* else, no information available... */
84+}
85+
86+
87+LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
88+ va_list argp;
89+ va_start(argp, fmt);
90+ luaL_where(L, 1);
91+ lua_pushvfstring(L, fmt, argp);
92+ va_end(argp);
93+ lua_concat(L, 2);
94+ return lua_error(L);
95+}
96+
97+/* }====================================================== */
98+
2399
24100 LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
25101 int i;
@@ -29,34 +105,55 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { · 3 unmodified lines
29105 return -1; /* name not found */
30106 }
31107
32−LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
33− lua_Debug ar;
34− lua_getstack(L, 0, &ar);
35− lua_getinfo(L, "n", &ar);
36− if (ar.name == NULL)
37− ar.name = "?";
38− luaL_verror(L, "bad argument #%d to `%.50s' (%.100s)",
39− narg, ar.name, extramsg);
108+
109+LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
110+ lua_pushstring(L, tname);
111+ lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */
112+ if (!lua_isnil(L, -1)) /* name already in use? */
113+ return 0; /* leave previous value on top, but return 0 */
114+ lua_pop(L, 1);
115+ lua_newtable(L); /* create metatable */
116+ lua_pushstring(L, tname);
117+ lua_pushvalue(L, -2);
118+ lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */
119+ lua_pushvalue(L, -1);
120+ lua_pushstring(L, tname);
121+ lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */
122+ return 1;
40123 }
41124
42125
43−static void type_error (lua_State *L, int narg, int t) {
44− char buff[50];
45− sprintf(buff, "%.8s expected, got %.8s", lua_typename(L, t),
46− lua_typename(L, lua_type(L, narg)));
47− luaL_argerror(L, narg, buff);
126+LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) {
127+ lua_pushstring(L, tname);
128+ lua_rawget(L, LUA_REGISTRYINDEX);
129+}
130+
131+
132+LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
133+ const char *tn;
134+ if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */
135+ lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */
136+ tn = lua_tostring(L, -1);
137+ if (tn && (strcmp(tn, tname) == 0)) {
138+ lua_pop(L, 1);
139+ return lua_touserdata(L, ud);
140+ }
141+ else {
142+ lua_pop(L, 1);
143+ return NULL;
144+ }
48145 }
49146
50147
51148 LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
52− if (space > lua_stackspace(L))
53− luaL_verror(L, "stack overflow (%.30s)", mes);
149+ if (!lua_checkstack(L, space))
150+ luaL_error(L, "stack overflow (%s)", mes);
54151 }
55152
56153
57−LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) {
154+LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
58155 if (lua_type(L, narg) != t)
59− type_error(L, narg, t);
156+ tag_error(L, narg, t);
60157 }
61158
62159
@@ -66,55 +163,164 @@ LUALIB_API void luaL_checkany (lua_State *L, int narg) { · 3 unmodified lines
66163 }
67164
68165
69−LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
166+LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
70167 const char *s = lua_tostring(L, narg);
71− if (!s) type_error(L, narg, LUA_TSTRING);
168+ if (!s) tag_error(L, narg, LUA_TSTRING);
72169 if (len) *len = lua_strlen(L, narg);
73170 return s;
74171 }
75172
76173
77−LUALIB_API const char *luaL_opt_lstr (lua_State *L, int narg, const char *def, size_t *len) {
78− if (lua_isnull(L, narg)) {
174+LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
175+ const char *def, size_t *len) {
176+ if (lua_isnoneornil(L, narg)) {
79177 if (len)
80178 *len = (def ? strlen(def) : 0);
81179 return def;
82180 }
83− else return luaL_check_lstr(L, narg, len);
181+ else return luaL_checklstring(L, narg, len);
84182 }
85183
86184
87−LUALIB_API double luaL_check_number (lua_State *L, int narg) {
88− double d = lua_tonumber(L, narg);
185+LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
186+ lua_Number d = lua_tonumber(L, narg);
89187 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
90− type_error(L, narg, LUA_TNUMBER);
188+ tag_error(L, narg, LUA_TNUMBER);
91189 return d;
92190 }
93191
94192
95−LUALIB_API double luaL_opt_number (lua_State *L, int narg, double def) {
96− if (lua_isnull(L, narg)) return def;
97− else return luaL_check_number(L, narg);
193+LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
194+ if (lua_isnoneornil(L, narg)) return def;
195+ else return luaL_checknumber(L, narg);
98196 }
99197
100198
101−LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) {
102− int i;
103− for (i=0; i<n; i++)
104− lua_register(L, l[i].name, l[i].func);
199+LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
200+ if (!lua_getmetatable(L, obj)) /* no metatable? */
201+ return 0;
202+ lua_pushstring(L, event);
203+ lua_rawget(L, -2);
204+ if (lua_isnil(L, -1)) {
205+ lua_pop(L, 2); /* remove metatable and metafield */
206+ return 0;
207+ }
208+ else {
209+ lua_remove(L, -2); /* remove only metatable */
210+ return 1;
211+ }
105212 }
106213
107214
108−LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...) {
109− char buff[500];
110− va_list argp;
111− va_start(argp, fmt);
112− vsprintf(buff, fmt, argp);
113− va_end(argp);
114− lua_error(L, buff);
215+LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
216+ obj = abs_index(L, obj);
217+ if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
218+ return 0;
219+ lua_pushvalue(L, obj);
220+ lua_call(L, 1, 1);
221+ return 1;
115222 }
116223
117224
225+LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
226+ const luaL_reg *l, int nup) {
227+ if (libname) {
228+ lua_pushstring(L, libname);
229+ lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */
230+ if (lua_isnil(L, -1)) { /* no? */
231+ lua_pop(L, 1);
232+ lua_newtable(L); /* create it */
233+ lua_pushstring(L, libname);
234+ lua_pushvalue(L, -2);
235+ lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */
236+ }
237+ lua_insert(L, -(nup+1)); /* move library table to below upvalues */
238+ }
239+ for (; l->name; l++) {
240+ int i;
241+ lua_pushstring(L, l->name);
242+ for (i=0; i<nup; i++) /* copy upvalues to the top */
243+ lua_pushvalue(L, -(nup+1));
244+ lua_pushcclosure(L, l->func, nup);
245+ lua_settable(L, -(nup+3));
246+ }
247+ lua_pop(L, nup); /* remove upvalues */
248+}
249+
250+
251+
252+/*
253+** {======================================================
254+** getn-setn: size for arrays
255+** =======================================================
256+*/
257+
258+static int checkint (lua_State *L, int topop) {
259+ int n = (int)lua_tonumber(L, -1);
260+ if (n == 0 && !lua_isnumber(L, -1)) n = -1;
261+ lua_pop(L, topop);
262+ return n;
263+}
264+
265+
266+static void getsizes (lua_State *L) {
267+ lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
268+ if (lua_isnil(L, -1)) { /* no `size' table? */
269+ lua_pop(L, 1); /* remove nil */
270+ lua_newtable(L); /* create it */
271+ lua_pushvalue(L, -1); /* `size' will be its own metatable */
272+ lua_setmetatable(L, -2);
273+ lua_pushliteral(L, "__mode");
274+ lua_pushliteral(L, "k");
275+ lua_rawset(L, -3); /* metatable(N).__mode = "k" */
276+ lua_pushvalue(L, -1);
277+ lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
278+ }
279+}
280+
281+
282+void luaL_setn (lua_State *L, int t, int n) {
283+ t = abs_index(L, t);
284+ lua_pushliteral(L, "n");
285+ lua_rawget(L, t);
286+ if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
287+ lua_pushliteral(L, "n"); /* use it */
288+ lua_pushnumber(L, (lua_Number)n);
289+ lua_rawset(L, t);
290+ }
291+ else { /* use `sizes' */
292+ getsizes(L);
293+ lua_pushvalue(L, t);
294+ lua_pushnumber(L, (lua_Number)n);
295+ lua_rawset(L, -3); /* sizes[t] = n */
296+ lua_pop(L, 1); /* remove `sizes' */
297+ }
298+}
299+
300+
301+int luaL_getn (lua_State *L, int t) {
302+ int n;
303+ t = abs_index(L, t);
304+ lua_pushliteral(L, "n"); /* try t.n */
305+ lua_rawget(L, t);
306+ if ((n = checkint(L, 1)) >= 0) return n;
307+ getsizes(L); /* else try sizes[t] */
308+ lua_pushvalue(L, t);
309+ lua_rawget(L, -2);
310+ if ((n = checkint(L, 2)) >= 0) return n;
311+ for (n = 1; ; n++) { /* else must count elements */
312+ lua_rawgeti(L, t, n);
313+ if (lua_isnil(L, -1)) break;
314+ lua_pop(L, 1);
315+ }
316+ lua_pop(L, 1);
317+ return n - 1;
318+}
319+
320+/* }====================================================== */
321+
322+
323+
118324 /*
119325 ** {======================================================
120326 ** Generic Buffer manipulation
@@ -122,7 +328,6 @@ LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...) { · 1 unmodified line
122328 */
123329
124330
125−#define buffempty(B) ((B)->p == (B)->buffer)
126331 #define bufflen(B) ((B)->p - (B)->buffer)
127332 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
128333
@@ -135,29 +340,27 @@ static int emptybuffer (luaL_Buffer *B) { · 6 unmodified lines
135340 else {
136341 lua_pushlstring(B->L, B->buffer, l);
137342 B->p = B->buffer;
138− B->level++;
343+ B->lvl++;
139344 return 1;
140345 }
141346 }
142347
143348
144349 static void adjuststack (luaL_Buffer *B) {
145− if (B->level > 1) {
350+ if (B->lvl > 1) {
146351 lua_State *L = B->L;
147352 int toget = 1; /* number of levels to concat */
148353 size_t toplen = lua_strlen(L, -1);
149354 do {
150355 size_t l = lua_strlen(L, -(toget+1));
151− if (B->level - toget + 1 >= LIMIT || toplen > l) {
356+ if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
152357 toplen += l;
153358 toget++;
154359 }
155360 else break;
156− } while (toget < B->level);
157− if (toget >= 2) {
158− lua_concat(L, toget);
159− B->level = B->level - toget + 1;
160− }
361+ } while (toget < B->lvl);
362+ lua_concat(L, toget);
363+ B->lvl = B->lvl - toget + 1;
161364 }
162365 }
163366
@@ -182,11 +385,8 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { · 18 unmodified lines
182385
183386 LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
184387 emptybuffer(B);
185− if (B->level == 0)
186− lua_pushlstring(B->L, NULL, 0);
187− else if (B->level > 1)
188− lua_concat(B->L, B->level);
189− B->level = 1;
388+ lua_concat(B->L, B->lvl);
389+ B->lvl = 1;
190390 }
191391
192392
@@ -201,7 +401,7 @@ LUALIB_API void luaL_addvalue (luaL_Buffer *B) { · 8 unmodified lines
201401 else {
202402 if (emptybuffer(B))
203403 lua_insert(L, -2); /* put buffer before new value */
204− B->level++; /* add new value into B stack */
404+ B->lvl++; /* add new value into B stack */
205405 adjuststack(B);
206406 }
207407 }
@@ -210,7 +410,182 @@ LUALIB_API void luaL_addvalue (luaL_Buffer *B) { · 2 unmodified lines
210410 LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
211411 B->L = L;
212412 B->p = B->buffer;
213− B->level = 0;
413+ B->lvl = 0;
414+}
415+
416+/* }====================================================== */
417+
418+
419+LUALIB_API int luaL_ref (lua_State *L, int t) {
420+ int ref;
421+ t = abs_index(L, t);
422+ if (lua_isnil(L, -1)) {
423+ lua_pop(L, 1); /* remove from stack */
424+ return LUA_REFNIL; /* `nil' has a unique fixed reference */
425+ }
426+ lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
427+ ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */
428+ lua_pop(L, 1); /* remove it from stack */
429+ if (ref != 0) { /* any free element? */
430+ lua_rawgeti(L, t, ref); /* remove it from list */
431+ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
432+ }
433+ else { /* no free elements */
434+ ref = luaL_getn(L, t);
435+ if (ref < RESERVED_REFS)
436+ ref = RESERVED_REFS; /* skip reserved references */
437+ ref++; /* create new reference */
438+ luaL_setn(L, t, ref);
439+ }
440+ lua_rawseti(L, t, ref);
441+ return ref;
442+}
443+
444+
445+LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
446+ if (ref >= 0) {
447+ t = abs_index(L, t);
448+ lua_rawgeti(L, t, FREELIST_REF);
449+ lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
450+ lua_pushnumber(L, (lua_Number)ref);
451+ lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
452+ }
453+}
454+
455+
456+
457+/*
458+** {======================================================
459+** Load functions
460+** =======================================================
461+*/
462+
463+typedef struct LoadF {
464+ FILE *f;
465+ char buff[LUAL_BUFFERSIZE];
466+} LoadF;
467+
468+
469+static const char *getF (lua_State *L, void *ud, size_t *size) {
470+ LoadF *lf = (LoadF *)ud;
471+ (void)L;
472+ if (feof(lf->f)) return NULL;
473+ *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f);
474+ return (*size > 0) ? lf->buff : NULL;
475+}
476+
477+
478+static int errfile (lua_State *L, int fnameindex) {
479+ const char *filename = lua_tostring(L, fnameindex) + 1;
480+ lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno));
481+ lua_remove(L, fnameindex);
482+ return LUA_ERRFILE;
483+}
484+
485+
486+LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
487+ LoadF lf;
488+ int status, readstatus;
489+ int c;
490+ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
491+ if (filename == NULL) {
492+ lua_pushliteral(L, "=stdin");
493+ lf.f = stdin;
494+ }
495+ else {
496+ lua_pushfstring(L, "@%s", filename);
497+ lf.f = fopen(filename, "r");
498+ }
499+ if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */
500+ c = ungetc(getc(lf.f), lf.f);
501+ if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */
502+ fclose(lf.f);
503+ lf.f = fopen(filename, "rb"); /* reopen in binary mode */
504+ if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */
505+ }
506+ status = lua_load(L, getF, &lf, lua_tostring(L, -1));
507+ readstatus = ferror(lf.f);
508+ if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
509+ if (readstatus) {
510+ lua_settop(L, fnameindex); /* ignore results from `lua_load' */
511+ return errfile(L, fnameindex);
512+ }
513+ lua_remove(L, fnameindex);
514+ return status;
515+}
516+
517+
518+typedef struct LoadS {
519+ const char *s;
520+ size_t size;
521+} LoadS;
522+
523+
524+static const char *getS (lua_State *L, void *ud, size_t *size) {
525+ LoadS *ls = (LoadS *)ud;
526+ (void)L;
527+ if (ls->size == 0) return NULL;
528+ *size = ls->size;
529+ ls->size = 0;
530+ return ls->s;
531+}
532+
533+
534+LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
535+ const char *name) {
536+ LoadS ls;
537+ ls.s = buff;
538+ ls.size = size;
539+ return lua_load(L, getS, &ls, name);
540+}
541+
542+/* }====================================================== */
543+
544+
545+/*
546+** {======================================================
547+** compatibility code
548+** =======================================================
549+*/
550+
551+
552+static void callalert (lua_State *L, int status) {
553+ if (status != 0) {
554+ lua_getglobal(L, "_ALERT");
555+ if (lua_isfunction(L, -1)) {
556+ lua_insert(L, -2);
557+ lua_call(L, 1, 0);
558+ }
559+ else { /* no _ALERT function; print it on stderr */
560+ fprintf(stderr, "%s\n", lua_tostring(L, -2));
561+ lua_pop(L, 2); /* remove error message and _ALERT */
562+ }
563+ }
564+}
565+
566+
567+static int aux_do (lua_State *L, int status) {
568+ if (status == 0) { /* parse OK? */
569+ status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */
570+ }
571+ callalert(L, status);
572+ return status;
573+}
574+
575+
576+LUALIB_API int lua_dofile (lua_State *L, const char *filename) {
577+ return aux_do(L, luaL_loadfile(L, filename));
578+}
579+
580+
581+LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
582+ const char *name) {
583+ return aux_do(L, luaL_loadbuffer(L, buff, size, name));
584+}
585+
586+
587+LUALIB_API int lua_dostring (lua_State *L, const char *str) {
588+ return lua_dobuffer(L, str, strlen(str), str);
214589 }
215590
216591 /* }====================================================== */
src/lib/lbaselib.c+445−422
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lbaselib.c,v 1.17a 2000/11/06 13:45:18 roberto Exp $
2+** $Id: lbaselib.c,v 1.130 2003/04/03 13:35:34 roberto Exp $
33 ** Basic library
44 ** See Copyright Notice in lua.h
55 */
@@ -11,51 +11,15 @@ · 5 unmodified lines
1111 #include <stdlib.h>
1212 #include <string.h>
1313
14+#define lbaselib_c
15+
1416 #include "lua.h"
1517
1618 #include "lauxlib.h"
17−#include "luadebug.h"
1819 #include "lualib.h"
1920
2021
2122
22−/*
23−** If your system does not support `stderr', redefine this function, or
24−** redefine _ERRORMESSAGE so that it won't need _ALERT.
25−*/
26−static int luaB__ALERT (lua_State *L) {
27− fputs(luaL_check_string(L, 1), stderr);
28− return 0;
29−}
30−
31−
32−/*
33−** Basic implementation of _ERRORMESSAGE.
34−** The library `liolib' redefines _ERRORMESSAGE for better error information.
35−*/
36−static int luaB__ERRORMESSAGE (lua_State *L) {
37− luaL_checktype(L, 1, LUA_TSTRING);
38− lua_getglobal(L, LUA_ALERT);
39− if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */
40− lua_Debug ar;
41− lua_pushstring(L, "error: ");
42− lua_pushvalue(L, 1);
43− if (lua_getstack(L, 1, &ar)) {
44− lua_getinfo(L, "Sl", &ar);
45− if (ar.source && ar.currentline > 0) {
46− char buff[100];
47− sprintf(buff, "\n <%.70s: line %d>", ar.short_src, ar.currentline);
48− lua_pushstring(L, buff);
49− lua_concat(L, 2);
50− }
51− }
52− lua_pushstring(L, "\n");
53− lua_concat(L, 3);
54− lua_rawcall(L, 1, 0);
55− }
56− return 0;
57−}
58−
5923
6024 /*
6125 ** If your system does not support `stdout', you can just remove this function.
@@ -71,10 +35,10 @@ static int luaB_print (lua_State *L) { · 9 unmodified lines
7135 const char *s;
7236 lua_pushvalue(L, -1); /* function to be called */
7337 lua_pushvalue(L, i); /* value to print */
74− lua_rawcall(L, 1, 1);
38+ lua_call(L, 1, 1);
7539 s = lua_tostring(L, -1); /* get result */
7640 if (s == NULL)
77− lua_error(L, "`tostring' must return a string to `print'");
41+ return luaL_error(L, "`tostring' must return a string to `print'");
7842 if (i>1) fputs("\t", stdout);
7943 fputs(s, stdout);
8044 lua_pop(L, 1); /* pop result */
@@ -85,7 +49,7 @@ static int luaB_print (lua_State *L) { · 4 unmodified lines
8549
8650
8751 static int luaB_tonumber (lua_State *L) {
88− int base = luaL_opt_int(L, 2, 10);
52+ int base = luaL_optint(L, 2, 10);
8953 if (base == 10) { /* standard conversion */
9054 luaL_checkany(L, 1);
9155 if (lua_isnumber(L, 1)) {
@@ -94,15 +58,15 @@ static int luaB_tonumber (lua_State *L) { · 2 unmodified lines
9458 }
9559 }
9660 else {
97− const char *s1 = luaL_check_string(L, 1);
61+ const char *s1 = luaL_checkstring(L, 1);
9862 char *s2;
9963 unsigned long n;
100− luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range");
64+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
10165 n = strtoul(s1, &s2, base);
10266 if (s1 != s2) { /* at least one valid digit? */
103− while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */
67+ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
10468 if (*s2 == '\0') { /* no invalid trailing characters? */
105− lua_pushnumber(L, n);
69+ lua_pushnumber(L, (lua_Number)n);
10670 return 1;
10771 }
10872 }
@@ -113,55 +77,99 @@ static int luaB_tonumber (lua_State *L) { · 4 unmodified lines
11377
11478
11579 static int luaB_error (lua_State *L) {
116− lua_error(L, luaL_opt_string(L, 1, NULL));
117− return 0; /* to avoid warnings */
80+ int level = luaL_optint(L, 2, 1);
81+ luaL_checkany(L, 1);
82+ if (!lua_isstring(L, 1) || level == 0)
83+ lua_pushvalue(L, 1); /* propagate error message without changes */
84+ else { /* add extra information */
85+ luaL_where(L, level);
86+ lua_pushvalue(L, 1);
87+ lua_concat(L, 2);
88+ }
89+ return lua_error(L);
11890 }
11991
120−static int luaB_setglobal (lua_State *L) {
121− luaL_checkany(L, 2);
122− lua_setglobal(L, luaL_check_string(L, 1));
123− return 0;
92+
93+static int luaB_getmetatable (lua_State *L) {
94+ luaL_checkany(L, 1);
95+ if (!lua_getmetatable(L, 1)) {
96+ lua_pushnil(L);
97+ return 1; /* no metatable */
98+ }
99+ luaL_getmetafield(L, 1, "__metatable");
100+ return 1; /* returns either __metatable field (if present) or metatable */
124101 }
125102
126−static int luaB_getglobal (lua_State *L) {
127− lua_getglobal(L, luaL_check_string(L, 1));
103+
104+static int luaB_setmetatable (lua_State *L) {
105+ int t = lua_type(L, 2);
106+ luaL_checktype(L, 1, LUA_TTABLE);
107+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
108+ "nil or table expected");
109+ if (luaL_getmetafield(L, 1, "__metatable"))
110+ luaL_error(L, "cannot change a protected metatable");
111+ lua_settop(L, 2);
112+ lua_setmetatable(L, 1);
128113 return 1;
129114 }
130115
131−static int luaB_tag (lua_State *L) {
132− luaL_checkany(L, 1);
133− lua_pushnumber(L, lua_tag(L, 1));
134− return 1;
116+
117+static void getfunc (lua_State *L) {
118+ if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
119+ else {
120+ lua_Debug ar;
121+ int level = luaL_optint(L, 1, 1);
122+ luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
123+ if (lua_getstack(L, level, &ar) == 0)
124+ luaL_argerror(L, 1, "invalid level");
125+ lua_getinfo(L, "f", &ar);
126+ if (lua_isnil(L, -1))
127+ luaL_error(L, "no function environment for tail call at level %d",
128+ level);
129+ }
135130 }
136131
137−static int luaB_settag (lua_State *L) {
138− luaL_checktype(L, 1, LUA_TTABLE);
139− lua_pushvalue(L, 1); /* push table */
140− lua_settag(L, luaL_check_int(L, 2));
141− return 1; /* return table */
132+
133+static int aux_getfenv (lua_State *L) {
134+ lua_getfenv(L, -1);
135+ lua_pushliteral(L, "__fenv");
136+ lua_rawget(L, -2);
137+ return !lua_isnil(L, -1);
142138 }
143139
144−static int luaB_newtag (lua_State *L) {
145− lua_pushnumber(L, lua_newtag(L));
140+
141+static int luaB_getfenv (lua_State *L) {
142+ getfunc(L);
143+ if (!aux_getfenv(L)) /* __fenv not defined? */
144+ lua_pop(L, 1); /* remove it, to return real environment */
146145 return 1;
147146 }
148147
149−static int luaB_copytagmethods (lua_State *L) {
150− lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1),
151− luaL_check_int(L, 2)));
152− return 1;
148+
149+static int luaB_setfenv (lua_State *L) {
150+ luaL_checktype(L, 2, LUA_TTABLE);
151+ getfunc(L);
152+ if (aux_getfenv(L)) /* __fenv defined? */
153+ luaL_error(L, "`setfenv' cannot change a protected environment");
154+ else
155+ lua_pop(L, 2); /* remove __fenv and real environment table */
156+ lua_pushvalue(L, 2);
157+ if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)
158+ lua_replace(L, LUA_GLOBALSINDEX);
159+ else if (lua_setfenv(L, -2) == 0)
160+ luaL_error(L, "`setfenv' cannot change environment of given function");
161+ return 0;
153162 }
154163
155−static int luaB_globals (lua_State *L) {
156− lua_getglobals(L); /* value to be returned */
157− if (!lua_isnull(L, 1)) {
158− luaL_checktype(L, 1, LUA_TTABLE);
159− lua_pushvalue(L, 1); /* new table of globals */
160− lua_setglobals(L);
161− }
164+
165+static int luaB_rawequal (lua_State *L) {
166+ luaL_checkany(L, 1);
167+ luaL_checkany(L, 2);
168+ lua_pushboolean(L, lua_rawequal(L, 1, 2));
162169 return 1;
163170 }
164171
172+
165173 static int luaB_rawget (lua_State *L) {
166174 luaL_checktype(L, 1, LUA_TTABLE);
167175 luaL_checkany(L, 2);
@@ -177,39 +185,16 @@ static int luaB_rawset (lua_State *L) { · 9 unmodified lines
177185 return 1;
178186 }
179187
180−static int luaB_settagmethod (lua_State *L) {
181− int tag = luaL_check_int(L, 1);
182− const char *event = luaL_check_string(L, 2);
183− luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
184− "function or nil expected");
185− if (strcmp(event, "gc") == 0)
186− lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
187− lua_gettagmethod(L, tag, event);
188− lua_pushvalue(L, 3);
189− lua_settagmethod(L, tag, event);
190− return 1;
191−}
192−
193−
194−static int luaB_gettagmethod (lua_State *L) {
195− int tag = luaL_check_int(L, 1);
196− const char *event = luaL_check_string(L, 2);
197− if (strcmp(event, "gc") == 0)
198− lua_error(L, "deprecated use: cannot get the `gc' tag method from Lua");
199− lua_gettagmethod(L, tag, event);
200− return 1;
201−}
202−
203188
204189 static int luaB_gcinfo (lua_State *L) {
205− lua_pushnumber(L, lua_getgccount(L));
206− lua_pushnumber(L, lua_getgcthreshold(L));
190+ lua_pushnumber(L, (lua_Number)lua_getgccount(L));
191+ lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L));
207192 return 2;
208193 }
209194
210195
211196 static int luaB_collectgarbage (lua_State *L) {
212− lua_setgcthreshold(L, luaL_opt_int(L, 1, 0));
197+ lua_setgcthreshold(L, luaL_optint(L, 1, 0));
213198 return 0;
214199 }
215200
@@ -233,83 +218,116 @@ static int luaB_next (lua_State *L) { · 17 unmodified lines
233218 }
234219
235220
236−static int passresults (lua_State *L, int status, int oldtop) {
237− static const char *const errornames[] =
238− {"ok", "run-time error", "file error", "syntax error",
239− "memory error", "error in error handling"};
240− if (status == 0) {
241− int nresults = lua_gettop(L) - oldtop;
242− if (nresults > 0)
243− return nresults; /* results are already on the stack */
244− else {
245− lua_pushuserdata(L, NULL); /* at least one result to signal no errors */
246− return 1;
247− }
221+static int luaB_pairs (lua_State *L) {
222+ luaL_checktype(L, 1, LUA_TTABLE);
223+ lua_pushliteral(L, "next");
224+ lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */
225+ lua_pushvalue(L, 1); /* state, */
226+ lua_pushnil(L); /* and initial value */
227+ return 3;
228+}
229+
230+
231+static int luaB_ipairs (lua_State *L) {
232+ lua_Number i = lua_tonumber(L, 2);
233+ luaL_checktype(L, 1, LUA_TTABLE);
234+ if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */
235+ lua_pushliteral(L, "ipairs");
236+ lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */
237+ lua_pushvalue(L, 1); /* state, */
238+ lua_pushnumber(L, 0); /* and initial value */
239+ return 3;
240+ }
241+ else { /* `for' step */
242+ i++; /* next value */
243+ lua_pushnumber(L, i);
244+ lua_rawgeti(L, 1, (int)i);
245+ return (lua_isnil(L, -1)) ? 0 : 2;
248246 }
249− else { /* error */
247+}
248+
249+
250+static int load_aux (lua_State *L, int status) {
251+ if (status == 0) /* OK? */
252+ return 1;
253+ else {
250254 lua_pushnil(L);
251− lua_pushstring(L, errornames[status]); /* error code */
252− return 2;
255+ lua_insert(L, -2); /* put before error message */
256+ return 2; /* return nil plus error message */
253257 }
254258 }
255259
256−static int luaB_dostring (lua_State *L) {
257− int oldtop = lua_gettop(L);
260+
261+static int luaB_loadstring (lua_State *L) {
258262 size_t l;
259− const char *s = luaL_check_lstr(L, 1, &l);
260− if (*s == '\33') /* binary files start with ESC... */
261− lua_error(L, "`dostring' cannot run pre-compiled code");
262− return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop);
263+ const char *s = luaL_checklstring(L, 1, &l);
264+ const char *chunkname = luaL_optstring(L, 2, s);
265+ return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
266+}
267+
268+
269+static int luaB_loadfile (lua_State *L) {
270+ const char *fname = luaL_optstring(L, 1, NULL);
271+ return load_aux(L, luaL_loadfile(L, fname));
263272 }
264273
265274
266275 static int luaB_dofile (lua_State *L) {
267− int oldtop = lua_gettop(L);
268− const char *fname = luaL_opt_string(L, 1, NULL);
269− return passresults(L, lua_dofile(L, fname), oldtop);
276+ const char *fname = luaL_optstring(L, 1, NULL);
277+ int status = luaL_loadfile(L, fname);
278+ if (status != 0) lua_error(L);
279+ lua_call(L, 0, LUA_MULTRET);
280+ return lua_gettop(L) - 1;
270281 }
271282
272283
273−static int luaB_call (lua_State *L) {
274− int oldtop;
275− const char *options = luaL_opt_string(L, 3, "");
276− int err = 0; /* index of old error method */
277− int i, status;
278− int n;
279− luaL_checktype(L, 2, LUA_TTABLE);
280− n = lua_getn(L, 2);
281− if (!lua_isnull(L, 4)) { /* set new error method */
282− lua_getglobal(L, LUA_ERRORMESSAGE);
283− err = lua_gettop(L); /* get index */
284− lua_pushvalue(L, 4);
285− lua_setglobal(L, LUA_ERRORMESSAGE);
286− }
287− oldtop = lua_gettop(L); /* top before function-call preparation */
288− /* push function */
289− lua_pushvalue(L, 1);
290− luaL_checkstack(L, n, "too many arguments");
291− for (i=0; i<n; i++) /* push arg[1...n] */
292− lua_rawgeti(L, 2, i+1);
293− status = lua_call(L, n, LUA_MULTRET);
294− if (err != 0) { /* restore old error method */
295− lua_pushvalue(L, err);
296− lua_setglobal(L, LUA_ERRORMESSAGE);
297− }
298− if (status != 0) { /* error in call? */
299− if (strchr(options, 'x'))
300− lua_pushnil(L); /* return nil to signal the error */
301− else
302− lua_error(L, NULL); /* propagate error without additional messages */
303− return 1;
304− }
305− if (strchr(options, 'p')) /* pack results? */
306− lua_error(L, "deprecated option `p' in `call'");
307− return lua_gettop(L) - oldtop; /* results are already on the stack */
284+static int luaB_assert (lua_State *L) {
285+ luaL_checkany(L, 1);
286+ if (!lua_toboolean(L, 1))
287+ return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
288+ lua_settop(L, 1);
289+ return 1;
290+}
291+
292+
293+static int luaB_unpack (lua_State *L) {
294+ int n, i;
295+ luaL_checktype(L, 1, LUA_TTABLE);
296+ n = luaL_getn(L, 1);
297+ luaL_checkstack(L, n, "table too big to unpack");
298+ for (i=1; i<=n; i++) /* push arg[1...n] */
299+ lua_rawgeti(L, 1, i);
300+ return n;
301+}
302+
303+
304+static int luaB_pcall (lua_State *L) {
305+ int status;
306+ luaL_checkany(L, 1);
307+ status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
308+ lua_pushboolean(L, (status == 0));
309+ lua_insert(L, 1);
310+ return lua_gettop(L); /* return status + all results */
311+}
312+
313+
314+static int luaB_xpcall (lua_State *L) {
315+ int status;
316+ luaL_checkany(L, 2);
317+ lua_settop(L, 2);
318+ lua_insert(L, 1); /* put error function under function to be called */
319+ status = lua_pcall(L, 0, LUA_MULTRET, 1);
320+ lua_pushboolean(L, (status == 0));
321+ lua_replace(L, 1);
322+ return lua_gettop(L); /* return status + all results */
308323 }
309324
310325
311326 static int luaB_tostring (lua_State *L) {
312327 char buff[64];
328+ luaL_checkany(L, 1);
329+ if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
330+ return 1; /* use its value */
313331 switch (lua_type(L, 1)) {
314332 case LUA_TNUMBER:
315333 lua_pushstring(L, lua_tostring(L, 1));
@@ -317,6 +335,9 @@ static int luaB_tostring (lua_State *L) { · 1 unmodified line
317335 case LUA_TSTRING:
318336 lua_pushvalue(L, 1);
319337 return 1;
338+ case LUA_TBOOLEAN:
339+ lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
340+ return 1;
320341 case LUA_TTABLE:
321342 sprintf(buff, "table: %p", lua_topointer(L, 1));
322343 break;
@@ -324,328 +345,330 @@ static int luaB_tostring (lua_State *L) { · 1 unmodified line
324345 sprintf(buff, "function: %p", lua_topointer(L, 1));
325346 break;
326347 case LUA_TUSERDATA:
327− sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1));
348+ case LUA_TLIGHTUSERDATA:
349+ sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
350+ break;
351+ case LUA_TTHREAD:
352+ sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1));
328353 break;
329354 case LUA_TNIL:
330− lua_pushstring(L, "nil");
355+ lua_pushliteral(L, "nil");
331356 return 1;
332− default:
333− luaL_argerror(L, 1, "value expected");
334357 }
335358 lua_pushstring(L, buff);
336359 return 1;
337360 }
338361
339362
340−static int luaB_foreachi (lua_State *L) {
341− int n, i;
342− luaL_checktype(L, 1, LUA_TTABLE);
343− luaL_checktype(L, 2, LUA_TFUNCTION);
344− n = lua_getn(L, 1);
345− for (i=1; i<=n; i++) {
346− lua_pushvalue(L, 2); /* function */
347− lua_pushnumber(L, i); /* 1st argument */
348− lua_rawgeti(L, 1, i); /* 2nd argument */
349− lua_rawcall(L, 2, 1);
350− if (!lua_isnil(L, -1))
351− return 1;
352− lua_pop(L, 1); /* remove nil result */
363+static int luaB_newproxy (lua_State *L) {
364+ lua_settop(L, 1);
365+ lua_newuserdata(L, 0); /* create proxy */
366+ if (lua_toboolean(L, 1) == 0)
367+ return 1; /* no metatable */
368+ else if (lua_isboolean(L, 1)) {
369+ lua_newtable(L); /* create a new metatable `m' ... */
370+ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
371+ lua_pushboolean(L, 1);
372+ lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
353373 }
354− return 0;
355−}
356−
357−
358−static int luaB_foreach (lua_State *L) {
359− luaL_checktype(L, 1, LUA_TTABLE);
360− luaL_checktype(L, 2, LUA_TFUNCTION);
361− lua_pushnil(L); /* first index */
362− for (;;) {
363− if (lua_next(L, 1) == 0)
364− return 0;
365− lua_pushvalue(L, 2); /* function */
366− lua_pushvalue(L, -3); /* key */
367− lua_pushvalue(L, -3); /* value */
368− lua_rawcall(L, 2, 1);
369− if (!lua_isnil(L, -1))
370− return 1;
371− lua_pop(L, 2); /* remove value and result */
374+ else {
375+ int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
376+ if (lua_getmetatable(L, 1)) {
377+ lua_rawget(L, lua_upvalueindex(1));
378+ validproxy = lua_toboolean(L, -1);
379+ lua_pop(L, 1); /* remove value */
380+ }
381+ luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
382+ lua_getmetatable(L, 1); /* metatable is valid; get it */
372383 }
373−}
374−
375−
376−static int luaB_assert (lua_State *L) {
377− luaL_checkany(L, 1);
378− if (lua_isnil(L, 1))
379− luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, ""));
380− return 0;
381−}
382−
383−
384−static int luaB_getn (lua_State *L) {
385− luaL_checktype(L, 1, LUA_TTABLE);
386− lua_pushnumber(L, lua_getn(L, 1));
384+ lua_setmetatable(L, 2);
387385 return 1;
388386 }
389387
390388
391−static int luaB_tinsert (lua_State *L) {
392− int v = lua_gettop(L); /* last argument: to be inserted */
393− int n, pos;
394− luaL_checktype(L, 1, LUA_TTABLE);
395− n = lua_getn(L, 1);
396− if (v == 2) /* called with only 2 arguments */
397− pos = n+1;
398− else
399− pos = luaL_check_int(L, 2); /* 2nd argument is the position */
400− lua_pushstring(L, "n");
401− lua_pushnumber(L, n+1);
402− lua_rawset(L, 1); /* t.n = n+1 */
403− for (; n>=pos; n--) {
404− lua_rawgeti(L, 1, n);
405− lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
406− }
407− lua_pushvalue(L, v);
408− lua_rawseti(L, 1, pos); /* t[pos] = v */
409− return 0;
410−}
411−
389+/*
390+** {======================================================
391+** `require' function
392+** =======================================================
393+*/
412394
413−static int luaB_tremove (lua_State *L) {
414− int pos, n;
415− luaL_checktype(L, 1, LUA_TTABLE);
416− n = lua_getn(L, 1);
417− pos = luaL_opt_int(L, 2, n);
418− if (n <= 0) return 0; /* table is "empty" */
419− lua_rawgeti(L, 1, pos); /* result = t[pos] */
420− for ( ;pos<n; pos++) {
421− lua_rawgeti(L, 1, pos+1);
422− lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */
423− }
424− lua_pushstring(L, "n");
425− lua_pushnumber(L, n-1);
426− lua_rawset(L, 1); /* t.n = n-1 */
427− lua_pushnil(L);
428− lua_rawseti(L, 1, n); /* t[n] = nil */
429− return 1;
430−}
431395
396+/* name of global that holds table with loaded packages */
397+#define REQTAB "_LOADED"
432398
399+/* name of global that holds the search path for packages */
400+#define LUA_PATH "LUA_PATH"
433401
402+#ifndef LUA_PATH_SEP
403+#define LUA_PATH_SEP ';'
404+#endif
434405
435−/*
436−** {======================================================
437−** Quicksort
438−** (based on `Algorithms in MODULA-3', Robert Sedgewick;
439−** Addison-Wesley, 1993.)
440−*/
406+#ifndef LUA_PATH_MARK
407+#define LUA_PATH_MARK '?'
408+#endif
441409
410+#ifndef LUA_PATH_DEFAULT
411+#define LUA_PATH_DEFAULT "?;?.lua"
412+#endif
442413
443−static void set2 (lua_State *L, int i, int j) {
444− lua_rawseti(L, 1, i);
445− lua_rawseti(L, 1, j);
446−}
447414
448−static int sort_comp (lua_State *L, int a, int b) {
449− /* WARNING: the caller (auxsort) must ensure stack space */
450− if (!lua_isnil(L, 2)) { /* function? */
451− int res;
452− lua_pushvalue(L, 2);
453− lua_pushvalue(L, a-1); /* -1 to compensate function */
454− lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
455− lua_rawcall(L, 2, 1);
456− res = !lua_isnil(L, -1);
457− lua_pop(L, 1);
458− return res;
415+static const char *getpath (lua_State *L) {
416+ const char *path;
417+ lua_getglobal(L, LUA_PATH); /* try global variable */
418+ path = lua_tostring(L, -1);
419+ lua_pop(L, 1);
420+ if (path) return path;
421+ path = getenv(LUA_PATH); /* else try environment variable */
422+ if (path) return path;
423+ return LUA_PATH_DEFAULT; /* else use default */
424+}
425+
426+
427+static const char *pushnextpath (lua_State *L, const char *path) {
428+ const char *l;
429+ if (*path == '\0') return NULL; /* no more paths */
430+ if (*path == LUA_PATH_SEP) path++; /* skip separator */
431+ l = strchr(path, LUA_PATH_SEP); /* find next separator */
432+ if (l == NULL) l = path+strlen(path);
433+ lua_pushlstring(L, path, l - path); /* directory name */
434+ return l;
435+}
436+
437+
438+static void pushcomposename (lua_State *L) {
439+ const char *path = lua_tostring(L, -1);
440+ const char *wild;
441+ int n = 1;
442+ while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) {
443+ /* is there stack space for prefix, name, and eventual last sufix? */
444+ luaL_checkstack(L, 3, "too many marks in a path component");
445+ lua_pushlstring(L, path, wild - path); /* push prefix */
446+ lua_pushvalue(L, 1); /* push package name (in place of MARK) */
447+ path = wild + 1; /* continue after MARK */
448+ n += 2;
459449 }
460− else /* a < b? */
461− return lua_lessthan(L, a, b);
462−}
463−
464−static void auxsort (lua_State *L, int l, int u) {
465− while (l < u) { /* for tail recursion */
466− int i, j;
467− /* sort elements a[l], a[(l+u)/2] and a[u] */
468− lua_rawgeti(L, 1, l);
469− lua_rawgeti(L, 1, u);
470− if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
471− set2(L, l, u); /* swap a[l] - a[u] */
472− else
473− lua_pop(L, 2);
474− if (u-l == 1) break; /* only 2 elements */
475− i = (l+u)/2;
476− lua_rawgeti(L, 1, i);
477− lua_rawgeti(L, 1, l);
478− if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
479− set2(L, i, l);
480− else {
481− lua_pop(L, 1); /* remove a[l] */
482− lua_rawgeti(L, 1, u);
483− if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
484− set2(L, i, u);
485− else
486− lua_pop(L, 2);
450+ lua_pushstring(L, path); /* push last sufix (`n' already includes this) */
451+ lua_concat(L, n);
452+}
453+
454+
455+static int luaB_require (lua_State *L) {
456+ const char *path;
457+ int status = LUA_ERRFILE; /* not found (yet) */
458+ luaL_checkstring(L, 1);
459+ lua_settop(L, 1);
460+ lua_getglobal(L, REQTAB);
461+ if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table");
462+ path = getpath(L);
463+ lua_pushvalue(L, 1); /* check package's name in book-keeping table */
464+ lua_rawget(L, 2);
465+ if (lua_toboolean(L, -1)) /* is it there? */
466+ return 1; /* package is already loaded; return its result */
467+ else { /* must load it */
468+ while (status == LUA_ERRFILE) {
469+ lua_settop(L, 3); /* reset stack position */
470+ if ((path = pushnextpath(L, path)) == NULL) break;
471+ pushcomposename(L);
472+ status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */
487473 }
488− if (u-l == 2) break; /* only 3 elements */
489− lua_rawgeti(L, 1, i); /* Pivot */
490− lua_pushvalue(L, -1);
491− lua_rawgeti(L, 1, u-1);
492− set2(L, i, u-1);
493− /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
494− i = l; j = u-1;
495− for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
496− /* repeat ++i until a[i] >= P */
497− while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
498− if (i>u) lua_error(L, "invalid order function for sorting");
499− lua_pop(L, 1); /* remove a[i] */
500− }
501− /* repeat --j until a[j] <= P */
502− while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
503− if (j<l) lua_error(L, "invalid order function for sorting");
504− lua_pop(L, 1); /* remove a[j] */
505− }
506− if (j<i) {
507− lua_pop(L, 3); /* pop pivot, a[i], a[j] */
508− break;
474+ }
475+ switch (status) {
476+ case 0: {
477+ lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */
478+ lua_insert(L, -2); /* put it below function */
479+ lua_pushvalue(L, 1);
480+ lua_setglobal(L, "_REQUIREDNAME"); /* set new name */
481+ lua_call(L, 0, 1); /* run loaded module */
482+ lua_insert(L, -2); /* put result below previous name */
483+ lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */
484+ if (lua_isnil(L, -1)) { /* no/nil return? */
485+ lua_pushboolean(L, 1);
486+ lua_replace(L, -2); /* replace to true */
509487 }
510− set2(L, i, j);
488+ lua_pushvalue(L, 1);
489+ lua_pushvalue(L, -2);
490+ lua_rawset(L, 2); /* mark it as loaded */
491+ return 1; /* return value */
511492 }
512− lua_rawgeti(L, 1, u-1);
513− lua_rawgeti(L, 1, i);
514− set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
515− /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
516− /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
517− if (i-l < u-i) {
518− j=l; i=i-1; l=i+2;
493+ case LUA_ERRFILE: { /* file not found */
494+ return luaL_error(L, "could not load package `%s' from path `%s'",
495+ lua_tostring(L, 1), getpath(L));
519496 }
520− else {
521− j=i+1; i=u; u=j-2;
497+ default: {
498+ return luaL_error(L, "error loading package `%s' (%s)",
499+ lua_tostring(L, 1), lua_tostring(L, -1));
522500 }
523− auxsort(L, j, i); /* call recursively the smaller one */
524− } /* repeat the routine for the larger one */
525−}
526−
527−static int luaB_sort (lua_State *L) {
528− int n;
529− luaL_checktype(L, 1, LUA_TTABLE);
530− n = lua_getn(L, 1);
531− if (!lua_isnull(L, 2)) /* is there a 2nd argument? */
532− luaL_checktype(L, 2, LUA_TFUNCTION);
533− lua_settop(L, 2); /* make sure there is two arguments */
534− auxsort(L, 1, n);
535− return 0;
501+ }
536502 }
537503
538504 /* }====================================================== */
539505
540506
507+static const luaL_reg base_funcs[] = {
508+ {"error", luaB_error},
509+ {"getmetatable", luaB_getmetatable},
510+ {"setmetatable", luaB_setmetatable},
511+ {"getfenv", luaB_getfenv},
512+ {"setfenv", luaB_setfenv},
513+ {"next", luaB_next},
514+ {"ipairs", luaB_ipairs},
515+ {"pairs", luaB_pairs},
516+ {"print", luaB_print},
517+ {"tonumber", luaB_tonumber},
518+ {"tostring", luaB_tostring},
519+ {"type", luaB_type},
520+ {"assert", luaB_assert},
521+ {"unpack", luaB_unpack},
522+ {"rawequal", luaB_rawequal},
523+ {"rawget", luaB_rawget},
524+ {"rawset", luaB_rawset},
525+ {"pcall", luaB_pcall},
526+ {"xpcall", luaB_xpcall},
527+ {"collectgarbage", luaB_collectgarbage},
528+ {"gcinfo", luaB_gcinfo},
529+ {"loadfile", luaB_loadfile},
530+ {"dofile", luaB_dofile},
531+ {"loadstring", luaB_loadstring},
532+ {"require", luaB_require},
533+ {NULL, NULL}
534+};
535+
541536
542537 /*
543538 ** {======================================================
544−** Deprecated functions to manipulate global environment.
539+** Coroutine library
545540 ** =======================================================
546541 */
547542
543+static int auxresume (lua_State *L, lua_State *co, int narg) {
544+ int status;
545+ if (!lua_checkstack(co, narg))
546+ luaL_error(L, "too many arguments to resume");
547+ lua_xmove(L, co, narg);
548+ status = lua_resume(co, narg);
549+ if (status == 0) {
550+ int nres = lua_gettop(co);
551+ if (!lua_checkstack(L, nres))
552+ luaL_error(L, "too many results to resume");
553+ lua_xmove(co, L, nres); /* move yielded values */
554+ return nres;
555+ }
556+ else {
557+ lua_xmove(co, L, 1); /* move error message */
558+ return -1; /* error flag */
559+ }
560+}
548561
549−#define num_deprecated 4
550−
551−static const struct luaL_reg deprecated_names [num_deprecated] = {
552− {"foreachvar", luaB_foreach},
553− {"nextvar", luaB_next},
554− {"rawgetglobal", luaB_rawget},
555− {"rawsetglobal", luaB_rawset}
556−};
557562
563+static int luaB_coresume (lua_State *L) {
564+ lua_State *co = lua_tothread(L, 1);
565+ int r;
566+ luaL_argcheck(L, co, 1, "coroutine expected");
567+ r = auxresume(L, co, lua_gettop(L) - 1);
568+ if (r < 0) {
569+ lua_pushboolean(L, 0);
570+ lua_insert(L, -2);
571+ return 2; /* return false + error message */
572+ }
573+ else {
574+ lua_pushboolean(L, 1);
575+ lua_insert(L, -(r + 1));
576+ return r + 1; /* return true + `resume' returns */
577+ }
578+}
558579
559−#ifdef LUA_DEPRECATEDFUNCS
560580
561−/*
562−** call corresponding function inserting `globals' as first argument
563−*/
564−static int deprecated_func (lua_State *L) {
565− lua_insert(L, 1); /* upvalue is the function to be called */
566− lua_getglobals(L);
567− lua_insert(L, 2); /* table of globals is 1o argument */
568− lua_rawcall(L, lua_gettop(L)-1, LUA_MULTRET);
569− return lua_gettop(L); /* return all results */
581+static int luaB_auxwrap (lua_State *L) {
582+ lua_State *co = lua_tothread(L, lua_upvalueindex(1));
583+ int r = auxresume(L, co, lua_gettop(L));
584+ if (r < 0) {
585+ if (lua_isstring(L, -1)) { /* error object is a string? */
586+ luaL_where(L, 1); /* add extra info */
587+ lua_insert(L, -2);
588+ lua_concat(L, 2);
589+ }
590+ lua_error(L); /* propagate error */
591+ }
592+ return r;
570593 }
571594
572595
573−static void deprecated_funcs (lua_State *L) {
574− int i;
575− for (i=0; i<num_deprecated; i++) {
576− lua_pushcfunction(L, deprecated_names[i].func);
577− lua_pushcclosure(L, deprecated_func, 1);
578− lua_setglobal(L, deprecated_names[i].name);
579− }
596+static int luaB_cocreate (lua_State *L) {
597+ lua_State *NL = lua_newthread(L);
598+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
599+ "Lua function expected");
600+ lua_pushvalue(L, 1); /* move function to top */
601+ lua_xmove(L, NL, 1); /* move function from L to NL */
602+ return 1;
580603 }
581604
582605
583−#else
606+static int luaB_cowrap (lua_State *L) {
607+ luaB_cocreate(L);
608+ lua_pushcclosure(L, luaB_auxwrap, 1);
609+ return 1;
610+}
584611
585−/*
586−** gives an explicit error in any attempt to call a deprecated function
587−*/
588−static int deprecated_func (lua_State *L) {
589− luaL_verror(L, "function `%.20s' is deprecated", lua_tostring(L, -1));
590− return 0; /* to avoid warnings */
612+
613+static int luaB_yield (lua_State *L) {
614+ return lua_yield(L, lua_gettop(L));
591615 }
592616
593617
594−static void deprecated_funcs (lua_State *L) {
595− int i;
596− for (i=0; i<num_deprecated; i++) {
597− lua_pushstring(L, deprecated_names[i].name);
598− lua_pushcclosure(L, deprecated_func, 1);
599− lua_setglobal(L, deprecated_names[i].name);
618+static int luaB_costatus (lua_State *L) {
619+ lua_State *co = lua_tothread(L, 1);
620+ luaL_argcheck(L, co, 1, "coroutine expected");
621+ if (L == co) lua_pushliteral(L, "running");
622+ else {
623+ lua_Debug ar;
624+ if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0)
625+ lua_pushliteral(L, "dead");
626+ else
627+ lua_pushliteral(L, "suspended");
600628 }
629+ return 1;
601630 }
602631
603−#endif
604−
605−/* }====================================================== */
606632
607−static const struct luaL_reg base_funcs[] = {
608− {LUA_ALERT, luaB__ALERT},
609− {LUA_ERRORMESSAGE, luaB__ERRORMESSAGE},
610− {"call", luaB_call},
611− {"collectgarbage", luaB_collectgarbage},
612− {"copytagmethods", luaB_copytagmethods},
613− {"dofile", luaB_dofile},
614− {"dostring", luaB_dostring},
615− {"error", luaB_error},
616− {"foreach", luaB_foreach},
617− {"foreachi", luaB_foreachi},
618− {"gcinfo", luaB_gcinfo},
619− {"getglobal", luaB_getglobal},
620− {"gettagmethod", luaB_gettagmethod},
621− {"globals", luaB_globals},
622− {"newtag", luaB_newtag},
623− {"next", luaB_next},
624− {"print", luaB_print},
625− {"rawget", luaB_rawget},
626− {"rawset", luaB_rawset},
627− {"rawgettable", luaB_rawget}, /* for compatibility */
628− {"rawsettable", luaB_rawset}, /* for compatibility */
629− {"setglobal", luaB_setglobal},
630− {"settag", luaB_settag},
631− {"settagmethod", luaB_settagmethod},
632− {"tag", luaB_tag},
633− {"tonumber", luaB_tonumber},
634− {"tostring", luaB_tostring},
635− {"type", luaB_type},
636− {"assert", luaB_assert},
637− {"getn", luaB_getn},
638− {"sort", luaB_sort},
639− {"tinsert", luaB_tinsert},
640− {"tremove", luaB_tremove}
633+static const luaL_reg co_funcs[] = {
634+ {"create", luaB_cocreate},
635+ {"wrap", luaB_cowrap},
636+ {"resume", luaB_coresume},
637+ {"yield", luaB_yield},
638+ {"status", luaB_costatus},
639+ {NULL, NULL}
641640 };
642641
642+/* }====================================================== */
643+
643644
644645
645−LUALIB_API void lua_baselibopen (lua_State *L) {
646− luaL_openl(L, base_funcs);
647− lua_pushstring(L, LUA_VERSION);
648− lua_setglobal(L, "_VERSION");
649− deprecated_funcs(L);
646+static void base_open (lua_State *L) {
647+ lua_pushliteral(L, "_G");
648+ lua_pushvalue(L, LUA_GLOBALSINDEX);
649+ luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */
650+ lua_pushliteral(L, "_VERSION");
651+ lua_pushliteral(L, LUA_VERSION);
652+ lua_rawset(L, -3); /* set global _VERSION */
653+ /* `newproxy' needs a weaktable as upvalue */
654+ lua_pushliteral(L, "newproxy");
655+ lua_newtable(L); /* new table `w' */
656+ lua_pushvalue(L, -1); /* `w' will be its own metatable */
657+ lua_setmetatable(L, -2);
658+ lua_pushliteral(L, "__mode");
659+ lua_pushliteral(L, "k");
660+ lua_rawset(L, -3); /* metatable(w).__mode = "k" */
661+ lua_pushcclosure(L, luaB_newproxy, 1);
662+ lua_rawset(L, -3); /* set global `newproxy' */
663+ lua_rawset(L, -1); /* set global _G */
664+}
665+
666+
667+LUALIB_API int luaopen_base (lua_State *L) {
668+ base_open(L);
669+ luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
670+ lua_newtable(L);
671+ lua_setglobal(L, REQTAB);
672+ return 0;
650673 }
651674
src/lib/ldblib.c+176−65
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ldblib.c,v 1.29 2000/11/06 17:58:38 roberto Exp $
2+** $Id: ldblib.c,v 1.80 2003/04/03 13:35:34 roberto Exp $
33 ** Interface from Lua to its debug API
44 ** See Copyright Notice in lua.h
55 */
@@ -9,10 +9,11 @@ · 3 unmodified lines
99 #include <stdlib.h>
1010 #include <string.h>
1111
12+#define ldblib_c
13+
1214 #include "lua.h"
1315
1416 #include "lauxlib.h"
15−#include "luadebug.h"
1617 #include "lualib.h"
1718
1819
@@ -20,43 +21,41 @@ · 1 unmodified line
2021 static void settabss (lua_State *L, const char *i, const char *v) {
2122 lua_pushstring(L, i);
2223 lua_pushstring(L, v);
23− lua_settable(L, -3);
24+ lua_rawset(L, -3);
2425 }
2526
2627
2728 static void settabsi (lua_State *L, const char *i, int v) {
2829 lua_pushstring(L, i);
29− lua_pushnumber(L, v);
30− lua_settable(L, -3);
30+ lua_pushnumber(L, (lua_Number)v);
31+ lua_rawset(L, -3);
3132 }
3233
3334
3435 static int getinfo (lua_State *L) {
3536 lua_Debug ar;
36− const char *options = luaL_opt_string(L, 2, "flnSu");
37− char buff[20];
37+ const char *options = luaL_optstring(L, 2, "flnSu");
3838 if (lua_isnumber(L, 1)) {
39− if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
39+ if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) {
4040 lua_pushnil(L); /* level out of range */
4141 return 1;
4242 }
4343 }
4444 else if (lua_isfunction(L, 1)) {
45+ lua_pushfstring(L, ">%s", options);
46+ options = lua_tostring(L, -1);
4547 lua_pushvalue(L, 1);
46− sprintf(buff, ">%.10s", options);
47− options = buff;
4848 }
4949 else
50− luaL_argerror(L, 1, "function or level expected");
50+ return luaL_argerror(L, 1, "function or level expected");
5151 if (!lua_getinfo(L, options, &ar))
52− luaL_argerror(L, 2, "invalid option");
52+ return luaL_argerror(L, 2, "invalid option");
5353 lua_newtable(L);
5454 for (; *options; options++) {
5555 switch (*options) {
5656 case 'S':
5757 settabss(L, "source", ar.source);
58− if (ar.source)
59− settabss(L, "short_src", ar.short_src);
58+ settabss(L, "short_src", ar.short_src);
6059 settabsi(L, "linedefined", ar.linedefined);
6160 settabss(L, "what", ar.what);
6261 break;
@@ -71,9 +70,9 @@ static int getinfo (lua_State *L) { · 8 unmodified lines
7170 settabss(L, "namewhat", ar.namewhat);
7271 break;
7372 case 'f':
74− lua_pushstring(L, "func");
73+ lua_pushliteral(L, "func");
7574 lua_pushvalue(L, -3);
76− lua_settable(L, -3);
75+ lua_rawset(L, -3);
7776 break;
7877 }
7978 }
@@ -84,9 +83,9 @@ static int getinfo (lua_State *L) { · 4 unmodified lines
8483 static int getlocal (lua_State *L) {
8584 lua_Debug ar;
8685 const char *name;
87− if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
88− luaL_argerror(L, 1, "level out of range");
89− name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
86+ if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */
87+ return luaL_argerror(L, 1, "level out of range");
88+ name = lua_getlocal(L, &ar, luaL_checkint(L, 2));
9089 if (name) {
9190 lua_pushstring(L, name);
9291 lua_pushvalue(L, -2);
@@ -101,88 +100,200 @@ static int getlocal (lua_State *L) { · 8 unmodified lines
101100
102101 static int setlocal (lua_State *L) {
103102 lua_Debug ar;
104− if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
105− luaL_argerror(L, 1, "level out of range");
103+ if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */
104+ return luaL_argerror(L, 1, "level out of range");
106105 luaL_checkany(L, 3);
107− lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
106+ lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2)));
108107 return 1;
109108 }
110109
111110
111+static int auxupvalue (lua_State *L, int get) {
112+ const char *name;
113+ int n = luaL_checkint(L, 2);
114+ luaL_checktype(L, 1, LUA_TFUNCTION);
115+ if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
116+ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
117+ if (name == NULL) return 0;
118+ lua_pushstring(L, name);
119+ lua_insert(L, -(get+1));
120+ return get + 1;
121+}
122+
123+
124+static int getupvalue (lua_State *L) {
125+ return auxupvalue(L, 1);
126+}
127+
128+
129+static int setupvalue (lua_State *L) {
130+ luaL_checkany(L, 3);
131+ return auxupvalue(L, 0);
132+}
133+
134+
112135
113−/* dummy variables (to define unique addresses) */
114−static char key1, key2;
115−#define KEY_CALLHOOK (&key1)
116−#define KEY_LINEHOOK (&key2)
136+static const char KEY_HOOK = 'h';
117137
118138
119−static void hookf (lua_State *L, void *key) {
120− lua_getregistry(L);
121− lua_pushuserdata(L, key);
122− lua_gettable(L, -2);
139+static void hookf (lua_State *L, lua_Debug *ar) {
140+ static const char *const hooknames[] =
141+ {"call", "return", "line", "count", "tail return"};
142+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
143+ lua_rawget(L, LUA_REGISTRYINDEX);
123144 if (lua_isfunction(L, -1)) {
124− lua_pushvalue(L, 1);
125− lua_rawcall(L, 1, 0);
145+ lua_pushstring(L, hooknames[(int)ar->event]);
146+ if (ar->currentline >= 0)
147+ lua_pushnumber(L, (lua_Number)ar->currentline);
148+ else lua_pushnil(L);
149+ lua_assert(lua_getinfo(L, "lS", ar));
150+ lua_call(L, 2, 0);
126151 }
127152 else
128153 lua_pop(L, 1); /* pop result from gettable */
129− lua_pop(L, 1); /* pop table */
130154 }
131155
132156
133−static void callf (lua_State *L, lua_Debug *ar) {
134− lua_pushstring(L, ar->event);
135− hookf(L, KEY_CALLHOOK);
157+static int makemask (const char *smask, int count) {
158+ int mask = 0;
159+ if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
160+ if (strchr(smask, 'r')) mask |= LUA_MASKRET;
161+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
162+ if (count > 0) mask |= LUA_MASKCOUNT;
163+ return mask;
136164 }
137165
138166
139−static void linef (lua_State *L, lua_Debug *ar) {
140− lua_pushnumber(L, ar->currentline);
141− hookf(L, KEY_LINEHOOK);
167+static char *unmakemask (int mask, char *smask) {
168+ int i = 0;
169+ if (mask & LUA_MASKCALL) smask[i++] = 'c';
170+ if (mask & LUA_MASKRET) smask[i++] = 'r';
171+ if (mask & LUA_MASKLINE) smask[i++] = 'l';
172+ smask[i] = '\0';
173+ return smask;
142174 }
143175
144176
145−static void sethook (lua_State *L, void *key, lua_Hook hook,
146− lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) {
147− lua_settop(L, 1);
148− if (lua_isnil(L, 1))
149− (*sethookf)(L, NULL);
150− else if (lua_isfunction(L, 1))
151− (*sethookf)(L, hook);
152− else
153− luaL_argerror(L, 1, "function expected");
154− lua_getregistry(L);
155− lua_pushuserdata(L, key);
156− lua_pushvalue(L, -1); /* dup key */
157− lua_gettable(L, -3); /* get old value */
158− lua_pushvalue(L, -2); /* key (again) */
177+static int sethook (lua_State *L) {
178+ if (lua_isnoneornil(L, 1)) {
179+ lua_settop(L, 1);
180+ lua_sethook(L, NULL, 0, 0); /* turn off hooks */
181+ }
182+ else {
183+ const char *smask = luaL_checkstring(L, 2);
184+ int count = luaL_optint(L, 3, 0);
185+ luaL_checktype(L, 1, LUA_TFUNCTION);
186+ lua_sethook(L, hookf, makemask(smask, count), count);
187+ }
188+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
159189 lua_pushvalue(L, 1);
160− lua_settable(L, -5); /* set new value */
190+ lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */
191+ return 0;
161192 }
162193
163194
164−static int setcallhook (lua_State *L) {
165− sethook(L, KEY_CALLHOOK, callf, lua_setcallhook);
166− return 1;
195+static int gethook (lua_State *L) {
196+ char buff[5];
197+ int mask = lua_gethookmask(L);
198+ lua_Hook hook = lua_gethook(L);
199+ if (hook != NULL && hook != hookf) /* external hook? */
200+ lua_pushliteral(L, "external hook");
201+ else {
202+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
203+ lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
204+ }
205+ lua_pushstring(L, unmakemask(mask, buff));
206+ lua_pushnumber(L, (lua_Number)lua_gethookcount(L));
207+ return 3;
208+}
209+
210+
211+static int debug (lua_State *L) {
212+ for (;;) {
213+ char buffer[250];
214+ fputs("lua_debug> ", stderr);
215+ if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
216+ strcmp(buffer, "cont\n") == 0)
217+ return 0;
218+ lua_dostring(L, buffer);
219+ lua_settop(L, 0); /* remove eventual returns */
220+ }
167221 }
168222
169223
170−static int setlinehook (lua_State *L) {
171− sethook(L, KEY_LINEHOOK, linef, lua_setlinehook);
224+#define LEVELS1 12 /* size of the first part of the stack */
225+#define LEVELS2 10 /* size of the second part of the stack */
226+
227+static int errorfb (lua_State *L) {
228+ int level = 1; /* skip level 0 (it's this function) */
229+ int firstpart = 1; /* still before eventual `...' */
230+ lua_Debug ar;
231+ if (lua_gettop(L) == 0)
232+ lua_pushliteral(L, "");
233+ else if (!lua_isstring(L, 1)) return 1; /* no string message */
234+ else lua_pushliteral(L, "\n");
235+ lua_pushliteral(L, "stack traceback:");
236+ while (lua_getstack(L, level++, &ar)) {
237+ if (level > LEVELS1 && firstpart) {
238+ /* no more than `LEVELS2' more levels? */
239+ if (!lua_getstack(L, level+LEVELS2, &ar))
240+ level--; /* keep going */
241+ else {
242+ lua_pushliteral(L, "\n\t..."); /* too many levels */
243+ while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */
244+ level++;
245+ }
246+ firstpart = 0;
247+ continue;
248+ }
249+ lua_pushliteral(L, "\n\t");
250+ lua_getinfo(L, "Snl", &ar);
251+ lua_pushfstring(L, "%s:", ar.short_src);
252+ if (ar.currentline > 0)
253+ lua_pushfstring(L, "%d:", ar.currentline);
254+ switch (*ar.namewhat) {
255+ case 'g': /* global */
256+ case 'l': /* local */
257+ case 'f': /* field */
258+ case 'm': /* method */
259+ lua_pushfstring(L, " in function `%s'", ar.name);
260+ break;
261+ default: {
262+ if (*ar.what == 'm') /* main? */
263+ lua_pushfstring(L, " in main chunk");
264+ else if (*ar.what == 'C' || *ar.what == 't')
265+ lua_pushliteral(L, " ?"); /* C function or tail call */
266+ else
267+ lua_pushfstring(L, " in function <%s:%d>",
268+ ar.short_src, ar.linedefined);
269+ }
270+ }
271+ lua_concat(L, lua_gettop(L));
272+ }
273+ lua_concat(L, lua_gettop(L));
172274 return 1;
173275 }
174276
175277
176−static const struct luaL_reg dblib[] = {
278+static const luaL_reg dblib[] = {
177279 {"getlocal", getlocal},
178280 {"getinfo", getinfo},
179− {"setcallhook", setcallhook},
180− {"setlinehook", setlinehook},
181− {"setlocal", setlocal}
281+ {"gethook", gethook},
282+ {"getupvalue", getupvalue},
283+ {"sethook", sethook},
284+ {"setlocal", setlocal},
285+ {"setupvalue", setupvalue},
286+ {"debug", debug},
287+ {"traceback", errorfb},
288+ {NULL, NULL}
182289 };
183290
184291
185−LUALIB_API void lua_dblibopen (lua_State *L) {
186− luaL_openl(L, dblib);
292+LUALIB_API int luaopen_debug (lua_State *L) {
293+ luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
294+ lua_pushliteral(L, "_TRACEBACK");
295+ lua_pushcfunction(L, errorfb);
296+ lua_settable(L, LUA_GLOBALSINDEX);
297+ return 1;
187298 }
188299
src/lib/liolib.c+509−477
@@ -1,302 +1,309 @@
11 /*
2−** $Id: liolib.c,v 1.91 2000/10/31 13:10:24 roberto Exp $
2+** $Id: liolib.c,v 2.39 2003/03/19 21:16:12 roberto Exp $
33 ** Standard I/O (and system) library
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <ctype.h>
8+#include <errno.h>
9+#include <locale.h>
910 #include <stdio.h>
1011 #include <stdlib.h>
1112 #include <string.h>
1213 #include <time.h>
1314
15+#define liolib_c
16+
1417 #include "lua.h"
1518
1619 #include "lauxlib.h"
17−#include "luadebug.h"
1820 #include "lualib.h"
1921
2022
21−#ifndef OLD_ANSI
22−#include <errno.h>
23−#include <locale.h>
24−#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
25−#define free(b) if (b) (free)(b)
23+
24+/*
25+** by default, gcc does not get `tmpname'
26+*/
27+#ifndef USE_TMPNAME
28+#ifdef __GNUC__
29+#define USE_TMPNAME 0
2630 #else
27−/* no support for locale and for strerror: fake them */
28−#define setlocale(a,b) ((void)a, strcmp((b),"C")==0?"C":NULL)
29−#define LC_ALL 0
30−#define LC_COLLATE 0
31−#define LC_CTYPE 0
32−#define LC_MONETARY 0
33−#define LC_NUMERIC 0
34−#define LC_TIME 0
35−#define strerror(e) "generic I/O error"
36−#define errno (-1)
31+#define USE_TMPNAME 1
32+#endif
3733 #endif
3834
3935
36+/*
37+** by default, posix systems get `popen'
38+*/
39+#ifndef USE_POPEN
40+#ifdef _POSIX_C_SOURCE
41+#if _POSIX_C_SOURCE >= 2
42+#define USE_POPEN 1
43+#endif
44+#endif
45+#endif
4046
41−#ifdef POPEN
42−/* FILE *popen();
43−int pclose(); */
44−#define CLOSEFILE(L, f) ((pclose(f) == -1) ? fclose(f) : 0)
45−#else
46−/* no support for popen */
47−#define popen(x,y) NULL /* that is, popen always fails */
48−#define CLOSEFILE(L, f) (fclose(f))
47+#ifndef USE_POPEN
48+#define USE_POPEN 0
4949 #endif
5050
5151
52−#define INFILE 0
53−#define OUTFILE 1
5452
55−typedef struct IOCtrl {
56− int ref[2]; /* ref for strings _INPUT/_OUTPUT */
57− int iotag; /* tag for file handles */
58− int closedtag; /* tag for closed handles */
59−} IOCtrl;
53+
54+/*
55+** {======================================================
56+** FILE Operations
57+** =======================================================
58+*/
59+
60+
61+#if !USE_POPEN
62+#define pclose(f) (-1)
63+#endif
6064
6165
66+#define FILEHANDLE "FILE*"
6267
63−static const char *const filenames[] = {"_INPUT", "_OUTPUT"};
68+#define IO_INPUT "_input"
69+#define IO_OUTPUT "_output"
6470
6571
66−static int pushresult (lua_State *L, int i) {
72+static int pushresult (lua_State *L, int i, const char *filename) {
6773 if (i) {
68− lua_pushuserdata(L, NULL);
74+ lua_pushboolean(L, 1);
6975 return 1;
7076 }
7177 else {
7278 lua_pushnil(L);
73− lua_pushstring(L, strerror(errno));
79+ if (filename)
80+ lua_pushfstring(L, "%s: %s", filename, strerror(errno));
81+ else
82+ lua_pushfstring(L, "%s", strerror(errno));
7483 lua_pushnumber(L, errno);
75− return 3;;
76− }
77−}
78−
79−
80−/*
81−** {======================================================
82−** FILE Operations
83−** =======================================================
84−*/
85−
86−
87−static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) {
88− void *p = lua_touserdata(L, f);
89− if (p != NULL) { /* is `f' a userdata ? */
90− int ftag = lua_tag(L, f);
91− if (ftag == ctrl->iotag) /* does it have the correct tag? */
92− return (FILE *)p;
93− else if (ftag == ctrl->closedtag)
94− lua_error(L, "cannot access a closed file");
95− /* else go through */
84+ return 3;
9685 }
97− return NULL;
9886 }
9987
10088
101−static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
102− FILE *f = gethandle(L, ctrl, arg);
103− luaL_arg_check(L, f, arg, "invalid file handle");
89+static FILE **topfile (lua_State *L, int findex) {
90+ FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);
91+ if (f == NULL) luaL_argerror(L, findex, "bad file");
10492 return f;
10593 }
10694
10795
108−static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) {
109− FILE *f;
110− lua_getglobals(L);
111− lua_getref(L, ctrl->ref[inout]);
112− lua_rawget(L, -2);
113− f = gethandle(L, ctrl, -1);
114− if (f == NULL)
115− luaL_verror(L, "global variable `%.10s' is not a file handle",
116− filenames[inout]);
117− return f;
96+static int io_type (lua_State *L) {
97+ FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);
98+ if (f == NULL) lua_pushnil(L);
99+ else if (*f == NULL)
100+ lua_pushliteral(L, "closed file");
101+ else
102+ lua_pushliteral(L, "file");
103+ return 1;
118104 }
119105
120106
121−static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f,
122− const char *name) {
123− lua_pushusertag(L, f, ctrl->iotag);
124− lua_setglobal(L, name);
107+static FILE *tofile (lua_State *L, int findex) {
108+ FILE **f = topfile(L, findex);
109+ if (*f == NULL)
110+ luaL_error(L, "attempt to use a closed file");
111+ return *f;
125112 }
126113
127114
128−#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout]))
129115
116+/*
117+** When creating file handles, always creates a `closed' file handle
118+** before opening the actual file; so, if there is a memory error, the
119+** file is not left opened.
120+*/
121+static FILE **newfile (lua_State *L) {
122+ FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
123+ *pf = NULL; /* file handle is currently `closed' */
124+ luaL_getmetatable(L, FILEHANDLE);
125+ lua_setmetatable(L, -2);
126+ return pf;
127+}
130128
131−static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
132− if (f == NULL)
133− return pushresult(L, 0);
134− else {
135− setfile(L, ctrl, f, inout);
136− lua_pushusertag(L, f, ctrl->iotag);
137− return 1;
129+
130+/*
131+** assumes that top of the stack is the `io' library, and next is
132+** the `io' metatable
133+*/
134+static void registerfile (lua_State *L, FILE *f, const char *name,
135+ const char *impname) {
136+ lua_pushstring(L, name);
137+ *newfile(L) = f;
138+ if (impname) {
139+ lua_pushstring(L, impname);
140+ lua_pushvalue(L, -2);
141+ lua_settable(L, -6); /* metatable[impname] = file */
138142 }
143+ lua_settable(L, -3); /* io[name] = file */
139144 }
140145
141146
142−static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
147+static int aux_close (lua_State *L) {
148+ FILE *f = tofile(L, 1);
143149 if (f == stdin || f == stdout || f == stderr)
144− return 1;
150+ return 0; /* file cannot be closed */
145151 else {
146− lua_pushusertag(L, f, ctrl->iotag);
147− lua_settag(L, ctrl->closedtag);
148− return (CLOSEFILE(L, f) == 0);
152+ int ok = (pclose(f) != -1) || (fclose(f) == 0);
153+ if (ok)
154+ *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
155+ return ok;
149156 }
150157 }
151158
152159
153160 static int io_close (lua_State *L) {
154− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
155− lua_pop(L, 1); /* remove upvalue */
156− return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1)));
161+ if (lua_isnone(L, 1)) {
162+ lua_pushstring(L, IO_OUTPUT);
163+ lua_rawget(L, lua_upvalueindex(1));
164+ }
165+ return pushresult(L, aux_close(L), NULL);
157166 }
158167
159168
160−static int file_collect (lua_State *L) {
161− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
162− FILE *f = getnonullfile(L, ctrl, 1);
163− if (f != stdin && f != stdout && f != stderr)
164− CLOSEFILE(L, f);
169+static int io_gc (lua_State *L) {
170+ FILE **f = topfile(L, 1);
171+ if (*f != NULL) /* ignore closed files */
172+ aux_close(L);
165173 return 0;
166174 }
167175
168176
169−static int io_open (lua_State *L) {
170− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
171− FILE *f;
172− lua_pop(L, 1); /* remove upvalue */
173− f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2));
174− if (f) {
175− lua_pushusertag(L, f, ctrl->iotag);
176− return 1;
177− }
177+static int io_tostring (lua_State *L) {
178+ char buff[32];
179+ FILE **f = topfile(L, 1);
180+ if (*f == NULL)
181+ strcpy(buff, "closed");
178182 else
179− return pushresult(L, 0);
183+ sprintf(buff, "%p", lua_touserdata(L, 1));
184+ lua_pushfstring(L, "file (%s)", buff);
185+ return 1;
180186 }
181187
182188
189+static int io_open (lua_State *L) {
190+ const char *filename = luaL_checkstring(L, 1);
191+ const char *mode = luaL_optstring(L, 2, "r");
192+ FILE **pf = newfile(L);
193+ *pf = fopen(filename, mode);
194+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
195+}
183196
184−static int io_fromto (lua_State *L, int inout, const char *mode) {
185− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
186− FILE *current;
187− lua_pop(L, 1); /* remove upvalue */
188− if (lua_isnull(L, 1)) {
189− closefile(L, ctrl, getfilebyref(L, ctrl, inout));
190− current = (inout == 0) ? stdin : stdout;
191− }
192− else if (lua_tag(L, 1) == ctrl->iotag) /* deprecated option */
193− current = (FILE *)lua_touserdata(L, 1);
194− else {
195− const char *s = luaL_check_string(L, 1);
196− current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
197− }
198− return setreturn(L, ctrl, current, inout);
197+
198+static int io_popen (lua_State *L) {
199+#if !USE_POPEN
200+ luaL_error(L, "`popen' not supported");
201+ return 0;
202+#else
203+ const char *filename = luaL_checkstring(L, 1);
204+ const char *mode = luaL_optstring(L, 2, "r");
205+ FILE **pf = newfile(L);
206+ *pf = popen(filename, mode);
207+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
208+#endif
199209 }
200210
201211
202−static int io_readfrom (lua_State *L) {
203− return io_fromto(L, INFILE, "r");
212+static int io_tmpfile (lua_State *L) {
213+ FILE **pf = newfile(L);
214+ *pf = tmpfile();
215+ return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
204216 }
205217
206218
207−static int io_writeto (lua_State *L) {
208− return io_fromto(L, OUTFILE, "w");
219+static FILE *getiofile (lua_State *L, const char *name) {
220+ lua_pushstring(L, name);
221+ lua_rawget(L, lua_upvalueindex(1));
222+ return tofile(L, -1);
209223 }
210224
211225
212−static int io_appendto (lua_State *L) {
213− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
214− FILE *current;
215− lua_pop(L, 1); /* remove upvalue */
216− current = fopen(luaL_check_string(L, 1), "a");
217− return setreturn(L, ctrl, current, OUTFILE);
226+static int g_iofile (lua_State *L, const char *name, const char *mode) {
227+ if (!lua_isnoneornil(L, 1)) {
228+ const char *filename = lua_tostring(L, 1);
229+ lua_pushstring(L, name);
230+ if (filename) {
231+ FILE **pf = newfile(L);
232+ *pf = fopen(filename, mode);
233+ if (*pf == NULL) {
234+ lua_pushfstring(L, "%s: %s", filename, strerror(errno));
235+ luaL_argerror(L, 1, lua_tostring(L, -1));
236+ }
237+ }
238+ else {
239+ tofile(L, 1); /* check that it's a valid file handle */
240+ lua_pushvalue(L, 1);
241+ }
242+ lua_rawset(L, lua_upvalueindex(1));
243+ }
244+ /* return current value */
245+ lua_pushstring(L, name);
246+ lua_rawget(L, lua_upvalueindex(1));
247+ return 1;
218248 }
219249
220250
251+static int io_input (lua_State *L) {
252+ return g_iofile(L, IO_INPUT, "r");
253+}
221254
222−/*
223−** {======================================================
224−** READ
225−** =======================================================
226−*/
227255
256+static int io_output (lua_State *L) {
257+ return g_iofile(L, IO_OUTPUT, "w");
258+}
228259
229260
230−#ifdef LUA_COMPAT_READPATTERN
261+static int io_readline (lua_State *L);
231262
232−/*
233−** We cannot lookahead without need, because this can lock stdin.
234−** This flag signals when we need to read a next char.
235−*/
236−#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
237263
264+static void aux_lines (lua_State *L, int idx, int close) {
265+ lua_pushliteral(L, FILEHANDLE);
266+ lua_rawget(L, LUA_REGISTRYINDEX);
267+ lua_pushvalue(L, idx);
268+ lua_pushboolean(L, close); /* close/not close file when finished */
269+ lua_pushcclosure(L, io_readline, 3);
270+}
238271
239−static int read_pattern (lua_State *L, FILE *f, const char *p) {
240− int inskip = 0; /* {skip} level */
241− int c = NEED_OTHER;
242− luaL_Buffer b;
243− luaL_buffinit(L, &b);
244− while (*p != '\0') {
245− switch (*p) {
246− case '{':
247− inskip++;
248− p++;
249− continue;
250− case '}':
251− if (!inskip) lua_error(L, "unbalanced braces in read pattern");
252− inskip--;
253− p++;
254− continue;
255− default: {
256− const char *ep = luaI_classend(L, p); /* get what is next */
257− int m; /* match result */
258− if (c == NEED_OTHER) c = getc(f);
259− m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
260− if (m) {
261− if (!inskip) luaL_putchar(&b, c);
262− c = NEED_OTHER;
263− }
264− switch (*ep) {
265− case '+': /* repetition (1 or more) */
266− if (!m) goto break_while; /* pattern fails? */
267− /* else go through */
268− case '*': /* repetition (0 or more) */
269− while (m) { /* reads the same item until it fails */
270− c = getc(f);
271− m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
272− if (m && !inskip) luaL_putchar(&b, c);
273− }
274− /* go through to continue reading the pattern */
275− case '?': /* optional */
276− p = ep+1; /* continues reading the pattern */
277− continue;
278− default:
279− if (!m) goto break_while; /* pattern fails? */
280− p = ep; /* else continues reading the pattern */
281− }
282− }
283− }
284− } break_while:
285− if (c != NEED_OTHER) ungetc(c, f);
286− luaL_pushresult(&b); /* close buffer */
287− return (*p == '\0');
272+
273+static int f_lines (lua_State *L) {
274+ tofile(L, 1); /* check that it's a valid file handle */
275+ aux_lines(L, 1, 0);
276+ return 1;
288277 }
289278
290−#else
291279
292−#define read_pattern(L, f, p) (lua_error(L, "read patterns are deprecated"), 0)
280+static int io_lines (lua_State *L) {
281+ if (lua_isnoneornil(L, 1)) { /* no arguments? */
282+ lua_pushstring(L, IO_INPUT);
283+ lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */
284+ return f_lines(L);
285+ }
286+ else {
287+ const char *filename = luaL_checkstring(L, 1);
288+ FILE **pf = newfile(L);
289+ *pf = fopen(filename, "r");
290+ luaL_argcheck(L, *pf, 1, strerror(errno));
291+ aux_lines(L, lua_gettop(L), 1);
292+ return 1;
293+ }
294+}
295+
293296
294−#endif
297+/*
298+** {======================================================
299+** READ
300+** =======================================================
301+*/
295302
296303
297304 static int read_number (lua_State *L, FILE *f) {
298− double d;
299− if (fscanf(f, "%lf", &d) == 1) {
305+ lua_Number d;
306+ if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
300307 lua_pushnumber(L, d);
301308 return 1;
302309 }
@@ -304,175 +311,167 @@ static int read_number (lua_State *L, FILE *f) { · 1 unmodified line
304311 }
305312
306313
307−static int read_word (lua_State *L, FILE *f) {
308− int c;
309− luaL_Buffer b;
310− luaL_buffinit(L, &b);
311− do { c = fgetc(f); } while (isspace(c)); /* skip spaces */
312− while (c != EOF && !isspace(c)) {
313− luaL_putchar(&b, c);
314− c = fgetc(f);
315− }
314+static int test_eof (lua_State *L, FILE *f) {
315+ int c = getc(f);
316316 ungetc(c, f);
317− luaL_pushresult(&b); /* close buffer */
318− return (lua_strlen(L, -1) > 0);
317+ lua_pushlstring(L, NULL, 0);
318+ return (c != EOF);
319319 }
320320
321321
322322 static int read_line (lua_State *L, FILE *f) {
323− int n = 0;
324323 luaL_Buffer b;
325324 luaL_buffinit(L, &b);
326325 for (;;) {
326+ size_t l;
327327 char *p = luaL_prepbuffer(&b);
328− if (!fgets(p, LUAL_BUFFERSIZE, f)) /* read fails? */
329− break;
330− n = strlen(p);
331− if (p[n-1] != '\n')
332− luaL_addsize(&b, n);
333− else {
334− luaL_addsize(&b, n-1); /* do not add the `\n' */
335− break;
328+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
329+ luaL_pushresult(&b); /* close buffer */
330+ return (lua_strlen(L, -1) > 0); /* check whether read something */
336331 }
337− }
338− luaL_pushresult(&b); /* close buffer */
339− return (n > 0); /* read something? */
340−}
341−
342−
343−static void read_file (lua_State *L, FILE *f) {
344− size_t len = 0;
345− size_t size = BUFSIZ;
346− char *buffer = NULL;
347− for (;;) {
348− char *newbuffer = (char *)realloc(buffer, size);
349− if (newbuffer == NULL) {
350− free(buffer);
351− lua_error(L, "not enough memory to read a file");
332+ l = strlen(p);
333+ if (p[l-1] != '\n')
334+ luaL_addsize(&b, l);
335+ else {
336+ luaL_addsize(&b, l - 1); /* do not include `eol' */
337+ luaL_pushresult(&b); /* close buffer */
338+ return 1; /* read at least an `eol' */
352339 }
353− buffer = newbuffer;
354− len += fread(buffer+len, sizeof(char), size-len, f);
355− if (len < size) break; /* did not read all it could */
356− size *= 2;
357340 }
358− lua_pushlstring(L, buffer, len);
359− free(buffer);
360341 }
361342
362343
363344 static int read_chars (lua_State *L, FILE *f, size_t n) {
364− char *buffer;
365− size_t n1;
366− char statbuff[BUFSIZ];
367− if (n <= BUFSIZ)
368− buffer = statbuff;
369− else {
370− buffer = (char *)malloc(n);
371− if (buffer == NULL)
372− lua_error(L, "not enough memory to read a file");
373− }
374− n1 = fread(buffer, sizeof(char), n, f);
375− lua_pushlstring(L, buffer, n1);
376− if (buffer != statbuff) free(buffer);
377− return (n1 > 0 || n == 0);
345+ size_t rlen; /* how much to read */
346+ size_t nr; /* number of chars actually read */
347+ luaL_Buffer b;
348+ luaL_buffinit(L, &b);
349+ rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
350+ do {
351+ char *p = luaL_prepbuffer(&b);
352+ if (rlen > n) rlen = n; /* cannot read more than asked */
353+ nr = fread(p, sizeof(char), rlen, f);
354+ luaL_addsize(&b, nr);
355+ n -= nr; /* still have to read `n' chars */
356+ } while (n > 0 && nr == rlen); /* until end of count or eof */
357+ luaL_pushresult(&b); /* close buffer */
358+ return (n == 0 || lua_strlen(L, -1) > 0);
378359 }
379360
380361
381−static int io_read (lua_State *L) {
382− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
383− int lastarg = lua_gettop(L) - 1;
384− int firstarg = 1;
385− FILE *f = gethandle(L, ctrl, firstarg);
362+static int g_read (lua_State *L, FILE *f, int first) {
363+ int nargs = lua_gettop(L) - 1;
364+ int success;
386365 int n;
387− if (f) firstarg++;
388− else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */
389− lua_pop(L, 1);
390− if (firstarg > lastarg) { /* no arguments? */
391− lua_settop(L, 0); /* erase upvalue and other eventual garbage */
392− firstarg = lastarg = 1; /* correct indices */
393− lua_pushstring(L, "*l"); /* push default argument */
366+ if (nargs == 0) { /* no arguments? */
367+ success = read_line(L, f);
368+ n = first+1; /* to return 1 result */
394369 }
395− else /* ensure stack space for all results and for auxlib's buffer */
396− luaL_checkstack(L, lastarg-firstarg+1+LUA_MINSTACK, "too many arguments");
397− for (n = firstarg; n<=lastarg; n++) {
398− int success;
399− if (lua_isnumber(L, n))
400− success = read_chars(L, f, (size_t)lua_tonumber(L, n));
401− else {
402− const char *p = luaL_check_string(L, n);
403− if (p[0] != '*')
404− success = read_pattern(L, f, p); /* deprecated! */
370+ else { /* ensure stack space for all results and for auxlib's buffer */
371+ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
372+ success = 1;
373+ for (n = first; nargs-- && success; n++) {
374+ if (lua_type(L, n) == LUA_TNUMBER) {
375+ size_t l = (size_t)lua_tonumber(L, n);
376+ success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
377+ }
405378 else {
379+ const char *p = lua_tostring(L, n);
380+ luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
406381 switch (p[1]) {
407382 case 'n': /* number */
408− if (!read_number(L, f)) goto endloop; /* read fails */
409− continue; /* number is already pushed; avoid the "pushstring" */
383+ success = read_number(L, f);
384+ break;
410385 case 'l': /* line */
411386 success = read_line(L, f);
412387 break;
413388 case 'a': /* file */
414− read_file(L, f);
389+ read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
415390 success = 1; /* always success */
416391 break;
417392 case 'w': /* word */
418− success = read_word(L, f);
419− break;
393+ return luaL_error(L, "obsolete option `*w' to `read'");
420394 default:
421− luaL_argerror(L, n, "invalid format");
422− success = 0; /* to avoid warnings */
395+ return luaL_argerror(L, n, "invalid format");
423396 }
424397 }
425398 }
426− if (!success) {
427− lua_pop(L, 1); /* remove last result */
428− break; /* read fails */
399+ }
400+ if (!success) {
401+ lua_pop(L, 1); /* remove last result */
402+ lua_pushnil(L); /* push nil instead */
403+ }
404+ return n - first;
405+}
406+
407+
408+static int io_read (lua_State *L) {
409+ return g_read(L, getiofile(L, IO_INPUT), 1);
410+}
411+
412+
413+static int f_read (lua_State *L) {
414+ return g_read(L, tofile(L, 1), 2);
415+}
416+
417+
418+static int io_readline (lua_State *L) {
419+ FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2));
420+ if (f == NULL) /* file is already closed? */
421+ luaL_error(L, "file is already closed");
422+ if (read_line(L, f)) return 1;
423+ else { /* EOF */
424+ if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
425+ lua_settop(L, 0);
426+ lua_pushvalue(L, lua_upvalueindex(2));
427+ aux_close(L); /* close it */
429428 }
430− } endloop:
431− return n - firstarg;
429+ return 0;
430+ }
432431 }
433432
434433 /* }====================================================== */
435434
436435
437−static int io_write (lua_State *L) {
438− int lastarg = lua_gettop(L) - 1;
439− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
440− int arg = 1;
436+static int g_write (lua_State *L, FILE *f, int arg) {
437+ int nargs = lua_gettop(L) - 1;
441438 int status = 1;
442− FILE *f = gethandle(L, ctrl, arg);
443− if (f) arg++;
444− else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */
445− for (; arg <= lastarg; arg++) {
446− if (lua_type(L, arg) == LUA_TNUMBER) { /* LUA_NUMBER */
439+ for (; nargs--; arg++) {
440+ if (lua_type(L, arg) == LUA_TNUMBER) {
447441 /* optimization: could be done exactly as for strings */
448− status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0;
442+ status = status &&
443+ fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
449444 }
450445 else {
451446 size_t l;
452− const char *s = luaL_check_lstr(L, arg, &l);
447+ const char *s = luaL_checklstring(L, arg, &l);
453448 status = status && (fwrite(s, sizeof(char), l, f) == l);
454449 }
455450 }
456− pushresult(L, status);
457− return 1;
451+ return pushresult(L, status, NULL);
452+}
453+
454+
455+static int io_write (lua_State *L) {
456+ return g_write(L, getiofile(L, IO_OUTPUT), 1);
458457 }
459458
460459
461−static int io_seek (lua_State *L) {
460+static int f_write (lua_State *L) {
461+ return g_write(L, tofile(L, 1), 2);
462+}
463+
464+
465+static int f_seek (lua_State *L) {
462466 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
463467 static const char *const modenames[] = {"set", "cur", "end", NULL};
464− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
465− FILE *f;
466− int op;
467− long offset;
468− lua_pop(L, 1); /* remove upvalue */
469− f = getnonullfile(L, ctrl, 1);
470− op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames);
471− offset = luaL_opt_long(L, 3, 0);
472− luaL_arg_check(L, op != -1, 2, "invalid mode");
468+ FILE *f = tofile(L, 1);
469+ int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames);
470+ long offset = luaL_optlong(L, 3, 0);
471+ luaL_argcheck(L, op != -1, 2, "invalid mode");
473472 op = fseek(f, offset, mode[op]);
474473 if (op)
475− return pushresult(L, 0); /* error */
474+ return pushresult(L, 0, NULL); /* error */
476475 else {
477476 lua_pushnumber(L, ftell(f));
478477 return 1;
@@ -481,12 +480,51 @@ static int io_seek (lua_State *L) { · 2 unmodified lines
481480
482481
483482 static int io_flush (lua_State *L) {
484− IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
485− FILE *f;
486− lua_pop(L, 1); /* remove upvalue */
487− f = gethandle(L, ctrl, 1);
488− luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle");
489− return pushresult(L, fflush(f) == 0);
483+ return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
484+}
485+
486+
487+static int f_flush (lua_State *L) {
488+ return pushresult(L, fflush(tofile(L, 1)) == 0, NULL);
489+}
490+
491+
492+static const luaL_reg iolib[] = {
493+ {"input", io_input},
494+ {"output", io_output},
495+ {"lines", io_lines},
496+ {"close", io_close},
497+ {"flush", io_flush},
498+ {"open", io_open},
499+ {"popen", io_popen},
500+ {"read", io_read},
501+ {"tmpfile", io_tmpfile},
502+ {"type", io_type},
503+ {"write", io_write},
504+ {NULL, NULL}
505+};
506+
507+
508+static const luaL_reg flib[] = {
509+ {"flush", f_flush},
510+ {"read", f_read},
511+ {"lines", f_lines},
512+ {"seek", f_seek},
513+ {"write", f_write},
514+ {"close", io_close},
515+ {"__gc", io_gc},
516+ {"__tostring", io_tostring},
517+ {NULL, NULL}
518+};
519+
520+
521+static void createmeta (lua_State *L) {
522+ luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */
523+ /* file methods */
524+ lua_pushliteral(L, "__index");
525+ lua_pushvalue(L, -2); /* push metatable */
526+ lua_rawset(L, -3); /* metatable.__index = metatable */
527+ luaL_openlib(L, NULL, flib, 0);
490528 }
491529
492530 /* }====================================================== */
@@ -499,220 +537,214 @@ static int io_flush (lua_State *L) { · 6 unmodified lines
499537 */
500538
501539 static int io_execute (lua_State *L) {
502− lua_pushnumber(L, system(luaL_check_string(L, 1)));
540+ lua_pushnumber(L, system(luaL_checkstring(L, 1)));
503541 return 1;
504542 }
505543
506544
507545 static int io_remove (lua_State *L) {
508− return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
546+ const char *filename = luaL_checkstring(L, 1);
547+ return pushresult(L, remove(filename) == 0, filename);
509548 }
510549
511550
512551 static int io_rename (lua_State *L) {
513− return pushresult(L, rename(luaL_check_string(L, 1),
514− luaL_check_string(L, 2)) == 0);
552+ const char *fromname = luaL_checkstring(L, 1);
553+ const char *toname = luaL_checkstring(L, 2);
554+ return pushresult(L, rename(fromname, toname) == 0, fromname);
515555 }
516556
517557
518558 static int io_tmpname (lua_State *L) {
519− lua_pushstring(L, tmpnam(NULL));
559+#if !USE_TMPNAME
560+ luaL_error(L, "`tmpname' not supported");
561+ return 0;
562+#else
563+ char buff[L_tmpnam];
564+ if (tmpnam(buff) != buff)
565+ return luaL_error(L, "unable to generate a unique filename in `tmpname'");
566+ lua_pushstring(L, buff);
520567 return 1;
568+#endif
521569 }
522570
523571
524−
525572 static int io_getenv (lua_State *L) {
526− lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */
573+ lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
527574 return 1;
528575 }
529576
530577
531578 static int io_clock (lua_State *L) {
532− lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC);
579+ lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
533580 return 1;
534581 }
535582
536583
584+/*
585+** {======================================================
586+** Time/Date operations
587+** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
588+** wday=%w+1, yday=%j, isdst=? }
589+** =======================================================
590+*/
591+
592+static void setfield (lua_State *L, const char *key, int value) {
593+ lua_pushstring(L, key);
594+ lua_pushnumber(L, value);
595+ lua_rawset(L, -3);
596+}
597+
598+static void setboolfield (lua_State *L, const char *key, int value) {
599+ lua_pushstring(L, key);
600+ lua_pushboolean(L, value);
601+ lua_rawset(L, -3);
602+}
603+
604+static int getboolfield (lua_State *L, const char *key) {
605+ int res;
606+ lua_pushstring(L, key);
607+ lua_gettable(L, -2);
608+ res = lua_toboolean(L, -1);
609+ lua_pop(L, 1);
610+ return res;
611+}
612+
613+
614+static int getfield (lua_State *L, const char *key, int d) {
615+ int res;
616+ lua_pushstring(L, key);
617+ lua_gettable(L, -2);
618+ if (lua_isnumber(L, -1))
619+ res = (int)(lua_tonumber(L, -1));
620+ else {
621+ if (d == -2)
622+ return luaL_error(L, "field `%s' missing in date table", key);
623+ res = d;
624+ }
625+ lua_pop(L, 1);
626+ return res;
627+}
628+
629+
537630 static int io_date (lua_State *L) {
538− char b[256];
539− const char *s = luaL_opt_string(L, 1, "%c");
631+ const char *s = luaL_optstring(L, 1, "%c");
632+ time_t t = (time_t)(luaL_optnumber(L, 2, -1));
540633 struct tm *stm;
541− time_t t;
542− time(&t); stm = localtime(&t);
543− if (strftime(b, sizeof(b), s, stm))
544− lua_pushstring(L, b);
634+ if (t == (time_t)(-1)) /* no time given? */
635+ t = time(NULL); /* use current time */
636+ if (*s == '!') { /* UTC? */
637+ stm = gmtime(&t);
638+ s++; /* skip `!' */
639+ }
545640 else
546− lua_error(L, "invalid `date' format");
641+ stm = localtime(&t);
642+ if (stm == NULL) /* invalid date? */
643+ lua_pushnil(L);
644+ else if (strcmp(s, "*t") == 0) {
645+ lua_newtable(L);
646+ setfield(L, "sec", stm->tm_sec);
647+ setfield(L, "min", stm->tm_min);
648+ setfield(L, "hour", stm->tm_hour);
649+ setfield(L, "day", stm->tm_mday);
650+ setfield(L, "month", stm->tm_mon+1);
651+ setfield(L, "year", stm->tm_year+1900);
652+ setfield(L, "wday", stm->tm_wday+1);
653+ setfield(L, "yday", stm->tm_yday+1);
654+ setboolfield(L, "isdst", stm->tm_isdst);
655+ }
656+ else {
657+ char b[256];
658+ if (strftime(b, sizeof(b), s, stm))
659+ lua_pushstring(L, b);
660+ else
661+ return luaL_error(L, "`date' format too long");
662+ }
547663 return 1;
548664 }
549665
550666
551−static int setloc (lua_State *L) {
552− static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
553− LC_NUMERIC, LC_TIME};
554− static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
555− "numeric", "time", NULL};
556− int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames);
557− luaL_arg_check(L, op != -1, 2, "invalid option");
558− lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1)));
667+static int io_time (lua_State *L) {
668+ if (lua_isnoneornil(L, 1)) /* called without args? */
669+ lua_pushnumber(L, time(NULL)); /* return current time */
670+ else {
671+ time_t t;
672+ struct tm ts;
673+ luaL_checktype(L, 1, LUA_TTABLE);
674+ lua_settop(L, 1); /* make sure table is at the top */
675+ ts.tm_sec = getfield(L, "sec", 0);
676+ ts.tm_min = getfield(L, "min", 0);
677+ ts.tm_hour = getfield(L, "hour", 12);
678+ ts.tm_mday = getfield(L, "day", -2);
679+ ts.tm_mon = getfield(L, "month", -2) - 1;
680+ ts.tm_year = getfield(L, "year", -2) - 1900;
681+ ts.tm_isdst = getboolfield(L, "isdst");
682+ t = mktime(&ts);
683+ if (t == (time_t)(-1))
684+ lua_pushnil(L);
685+ else
686+ lua_pushnumber(L, t);
687+ }
559688 return 1;
560689 }
561690
562691
563−static int io_exit (lua_State *L) {
564− exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
565− return 0; /* to avoid warnings */
692+static int io_difftime (lua_State *L) {
693+ lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
694+ (time_t)(luaL_optnumber(L, 2, 0))));
695+ return 1;
566696 }
567697
568698 /* }====================================================== */
569699
570700
571−
572−static int io_debug (lua_State *L) {
573− for (;;) {
574− char buffer[250];
575− fprintf(stderr, "lua_debug> ");
576− if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
577− strcmp(buffer, "cont\n") == 0)
578− return 0;
579− lua_dostring(L, buffer);
580− lua_settop(L, 0); /* remove eventual returns */
581− }
701+static int io_setloc (lua_State *L) {
702+ static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
703+ LC_NUMERIC, LC_TIME};
704+ static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
705+ "numeric", "time", NULL};
706+ const char *l = lua_tostring(L, 1);
707+ int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames);
708+ luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
709+ luaL_argcheck(L, op != -1, 2, "invalid option");
710+ lua_pushstring(L, setlocale(cat[op], l));
711+ return 1;
582712 }
583713
584714
585−#define LEVELS1 12 /* size of the first part of the stack */
586−#define LEVELS2 10 /* size of the second part of the stack */
587−
588−static int errorfb (lua_State *L) {
589− int level = 1; /* skip level 0 (it's this function) */
590− int firstpart = 1; /* still before eventual `...' */
591− lua_Debug ar;
592− luaL_Buffer b;
593− luaL_buffinit(L, &b);
594− luaL_addstring(&b, "error: ");
595− luaL_addstring(&b, luaL_check_string(L, 1));
596− luaL_addstring(&b, "\n");
597− while (lua_getstack(L, level++, &ar)) {
598− char buff[120]; /* enough to fit following `sprintf's */
599− if (level == 2)
600− luaL_addstring(&b, "stack traceback:\n");
601− else if (level > LEVELS1 && firstpart) {
602− /* no more than `LEVELS2' more levels? */
603− if (!lua_getstack(L, level+LEVELS2, &ar))
604− level--; /* keep going */
605− else {
606− luaL_addstring(&b, " ...\n"); /* too many levels */
607− while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */
608− level++;
609− }
610− firstpart = 0;
611− continue;
612− }
613− sprintf(buff, "%4d: ", level-1);
614− luaL_addstring(&b, buff);
615− lua_getinfo(L, "Snl", &ar);
616− switch (*ar.namewhat) {
617− case 'g': case 'l': /* global, local */
618− sprintf(buff, "function `%.50s'", ar.name);
619− break;
620− case 'f': /* field */
621− sprintf(buff, "method `%.50s'", ar.name);
622− break;
623− case 't': /* tag method */
624− sprintf(buff, "`%.50s' tag method", ar.name);
625− break;
626− default: {
627− if (*ar.what == 'm') /* main? */
628− sprintf(buff, "main of %.70s", ar.short_src);
629− else if (*ar.what == 'C') /* C function? */
630− sprintf(buff, "%.70s", ar.short_src);
631− else
632− sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src);
633− ar.source = NULL; /* do not print source again */
634− }
635− }
636− luaL_addstring(&b, buff);
637− if (ar.currentline > 0) {
638− sprintf(buff, " at line %d", ar.currentline);
639− luaL_addstring(&b, buff);
640− }
641− if (ar.source) {
642− sprintf(buff, " [%.70s]", ar.short_src);
643− luaL_addstring(&b, buff);
644− }
645− luaL_addstring(&b, "\n");
646− }
647− luaL_pushresult(&b);
648− lua_getglobal(L, LUA_ALERT);
649− if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */
650− lua_pushvalue(L, -2); /* error message */
651− lua_rawcall(L, 1, 0);
652− }
653− return 0;
715+static int io_exit (lua_State *L) {
716+ exit(luaL_optint(L, 1, EXIT_SUCCESS));
717+ return 0; /* to avoid warnings */
654718 }
655719
656−
657−
658−static const struct luaL_reg iolib[] = {
659− {LUA_ERRORMESSAGE, errorfb},
720+static const luaL_reg syslib[] = {
660721 {"clock", io_clock},
661− {"date", io_date},
662− {"debug", io_debug},
663− {"execute", io_execute},
664− {"exit", io_exit},
665− {"getenv", io_getenv},
666− {"remove", io_remove},
667− {"rename", io_rename},
668− {"setlocale", setloc},
669− {"tmpname", io_tmpname}
722+ {"date", io_date},
723+ {"difftime", io_difftime},
724+ {"execute", io_execute},
725+ {"exit", io_exit},
726+ {"getenv", io_getenv},
727+ {"remove", io_remove},
728+ {"rename", io_rename},
729+ {"setlocale", io_setloc},
730+ {"time", io_time},
731+ {"tmpname", io_tmpname},
732+ {NULL, NULL}
670733 };
671734
735+/* }====================================================== */
672736
673−static const struct luaL_reg iolibtag[] = {
674− {"appendto", io_appendto},
675− {"closefile", io_close},
676− {"flush", io_flush},
677− {"openfile", io_open},
678− {"read", io_read},
679− {"readfrom", io_readfrom},
680− {"seek", io_seek},
681− {"write", io_write},
682− {"writeto", io_writeto}
683−};
684737
685738
686−static void openwithcontrol (lua_State *L) {
687− IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl));
688− unsigned int i;
689− ctrl->iotag = lua_newtag(L);
690− ctrl->closedtag = lua_newtag(L);
691− for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
692− /* put `ctrl' as upvalue for these functions */
693− lua_pushvalue(L, -1);
694− lua_pushcclosure(L, iolibtag[i].func, 1);
695− lua_setglobal(L, iolibtag[i].name);
696− }
697− /* create references to variable names */
698− lua_pushstring(L, filenames[INFILE]);
699− ctrl->ref[INFILE] = lua_ref(L, 1);
700− lua_pushstring(L, filenames[OUTFILE]);
701− ctrl->ref[OUTFILE] = lua_ref(L, 1);
702− /* predefined file handles */
703− setfile(L, ctrl, stdin, INFILE);
704− setfile(L, ctrl, stdout, OUTFILE);
705− setfilebyname(L, ctrl, stdin, "_STDIN");
706− setfilebyname(L, ctrl, stdout, "_STDOUT");
707− setfilebyname(L, ctrl, stderr, "_STDERR");
708− /* close files when collected */
709− lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */
710− lua_settagmethod(L, ctrl->iotag, "gc");
711−}
712−
713−
714−LUALIB_API void lua_iolibopen (lua_State *L) {
715− luaL_openl(L, iolib);
716− openwithcontrol(L);
739+LUALIB_API int luaopen_io (lua_State *L) {
740+ luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
741+ createmeta(L);
742+ lua_pushvalue(L, -1);
743+ luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
744+ /* put predefined file handles into `io' table */
745+ registerfile(L, stdin, "stdin", IO_INPUT);
746+ registerfile(L, stdout, "stdout", IO_OUTPUT);
747+ registerfile(L, stderr, "stderr", NULL);
748+ return 1;
717749 }
718750
src/lib/lmathlib.c+80−72
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lmathlib.c,v 1.32 2000/10/31 13:10:24 roberto Exp $
2+** $Id: lmathlib.c,v 1.56 2003/03/11 12:30:37 roberto Exp $
33 ** Standard mathematical library
44 ** See Copyright Notice in lua.h
55 */
@@ -8,6 +8,8 @@ · 2 unmodified lines
88 #include <stdlib.h>
99 #include <math.h>
1010
11+#define lmathlib_c
12+
1113 #include "lua.h"
1214
1315 #include "lauxlib.h"
@@ -21,117 +23,117 @@ · 7 unmodified lines
2123
2224
2325 /*
24−** If you want Lua to operate in radians (instead of degrees),
25−** define RADIANS
26+** If you want Lua to operate in degrees (instead of radians),
27+** define USE_DEGREES
2628 */
27−#ifdef RADIANS
28−#define FROMRAD(a) (a)
29−#define TORAD(a) (a)
30−#else
29+#ifdef USE_DEGREES
3130 #define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
3231 #define TORAD(a) ((a)*RADIANS_PER_DEGREE)
32+#else
33+#define FROMRAD(a) (a)
34+#define TORAD(a) (a)
3335 #endif
3436
3537
3638 static int math_abs (lua_State *L) {
37− lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
39+ lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
3840 return 1;
3941 }
4042
4143 static int math_sin (lua_State *L) {
42− lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
44+ lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1))));
4345 return 1;
4446 }
4547
4648 static int math_cos (lua_State *L) {
47− lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
49+ lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1))));
4850 return 1;
4951 }
5052
5153 static int math_tan (lua_State *L) {
52− lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
54+ lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1))));
5355 return 1;
5456 }
5557
5658 static int math_asin (lua_State *L) {
57− lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
59+ lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1))));
5860 return 1;
5961 }
6062
6163 static int math_acos (lua_State *L) {
62− lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
64+ lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1))));
6365 return 1;
6466 }
6567
6668 static int math_atan (lua_State *L) {
67− lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
69+ lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1))));
6870 return 1;
6971 }
7072
7173 static int math_atan2 (lua_State *L) {
72− lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
74+ lua_pushnumber(L, FROMRAD(atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))));
7375 return 1;
7476 }
7577
7678 static int math_ceil (lua_State *L) {
77− lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
79+ lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
7880 return 1;
7981 }
8082
8183 static int math_floor (lua_State *L) {
82− lua_pushnumber(L, floor(luaL_check_number(L, 1)));
84+ lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
8385 return 1;
8486 }
8587
8688 static int math_mod (lua_State *L) {
87− lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
89+ lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
8890 return 1;
8991 }
9092
9193 static int math_sqrt (lua_State *L) {
92− lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
94+ lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
9395 return 1;
9496 }
9597
9698 static int math_pow (lua_State *L) {
97− lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
99+ lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
98100 return 1;
99101 }
100102
101103 static int math_log (lua_State *L) {
102− lua_pushnumber(L, log(luaL_check_number(L, 1)));
104+ lua_pushnumber(L, log(luaL_checknumber(L, 1)));
103105 return 1;
104106 }
105107
106108 static int math_log10 (lua_State *L) {
107− lua_pushnumber(L, log10(luaL_check_number(L, 1)));
109+ lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
108110 return 1;
109111 }
110112
111113 static int math_exp (lua_State *L) {
112− lua_pushnumber(L, exp(luaL_check_number(L, 1)));
114+ lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
113115 return 1;
114116 }
115117
116118 static int math_deg (lua_State *L) {
117− lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
119+ lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
118120 return 1;
119121 }
120122
121123 static int math_rad (lua_State *L) {
122− lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
124+ lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
123125 return 1;
124126 }
125127
126128 static int math_frexp (lua_State *L) {
127129 int e;
128− lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
130+ lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
129131 lua_pushnumber(L, e);
130132 return 2;
131133 }
132134
133135 static int math_ldexp (lua_State *L) {
134− lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
136+ lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
135137 return 1;
136138 }
137139
@@ -139,10 +141,10 @@ static int math_ldexp (lua_State *L) { · 1 unmodified line
139141
140142 static int math_min (lua_State *L) {
141143 int n = lua_gettop(L); /* number of arguments */
142− double dmin = luaL_check_number(L, 1);
144+ lua_Number dmin = luaL_checknumber(L, 1);
143145 int i;
144146 for (i=2; i<=n; i++) {
145− double d = luaL_check_number(L, i);
147+ lua_Number d = luaL_checknumber(L, i);
146148 if (d < dmin)
147149 dmin = d;
148150 }
@@ -153,10 +155,10 @@ static int math_min (lua_State *L) { · 4 unmodified lines
153155
154156 static int math_max (lua_State *L) {
155157 int n = lua_gettop(L); /* number of arguments */
156− double dmax = luaL_check_number(L, 1);
158+ lua_Number dmax = luaL_checknumber(L, 1);
157159 int i;
158160 for (i=2; i<=n; i++) {
159− double d = luaL_check_number(L, i);
161+ lua_Number d = luaL_checknumber(L, i);
160162 if (d > dmax)
161163 dmax = d;
162164 }
@@ -166,73 +168,79 @@ static int math_max (lua_State *L) { · 3 unmodified lines
166168
167169
168170 static int math_random (lua_State *L) {
169− /* the '%' avoids the (rare) case of r==1, and is needed also because on
170− some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
171− double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
171+ /* the `%' avoids the (rare) case of r==1, and is needed also because on
172+ some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
173+ lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
172174 switch (lua_gettop(L)) { /* check number of arguments */
173175 case 0: { /* no arguments */
174176 lua_pushnumber(L, r); /* Number between 0 and 1 */
175177 break;
176178 }
177179 case 1: { /* only upper limit */
178− int u = luaL_check_int(L, 1);
179− luaL_arg_check(L, 1<=u, 1, "interval is empty");
180− lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */
180+ int u = luaL_checkint(L, 1);
181+ luaL_argcheck(L, 1<=u, 1, "interval is empty");
182+ lua_pushnumber(L, (int)floor(r*u)+1); /* int between 1 and `u' */
181183 break;
182184 }
183185 case 2: { /* lower and upper limits */
184− int l = luaL_check_int(L, 1);
185− int u = luaL_check_int(L, 2);
186− luaL_arg_check(L, l<=u, 2, "interval is empty");
187− lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */
186+ int l = luaL_checkint(L, 1);
187+ int u = luaL_checkint(L, 2);
188+ luaL_argcheck(L, l<=u, 2, "interval is empty");
189+ lua_pushnumber(L, (int)floor(r*(u-l+1))+l); /* int between `l' and `u' */
188190 break;
189191 }
190− default: lua_error(L, "wrong number of arguments");
192+ default: return luaL_error(L, "wrong number of arguments");
191193 }
192194 return 1;
193195 }
194196
195197
196198 static int math_randomseed (lua_State *L) {
197− srand(luaL_check_int(L, 1));
199+ srand(luaL_checkint(L, 1));
198200 return 0;
199201 }
200202
201203
202−static const struct luaL_reg mathlib[] = {
203−{"abs", math_abs},
204−{"sin", math_sin},
205−{"cos", math_cos},
206−{"tan", math_tan},
207−{"asin", math_asin},
208−{"acos", math_acos},
209−{"atan", math_atan},
210−{"atan2", math_atan2},
211−{"ceil", math_ceil},
212−{"floor", math_floor},
213−{"mod", math_mod},
214−{"frexp", math_frexp},
215−{"ldexp", math_ldexp},
216−{"sqrt", math_sqrt},
217−{"min", math_min},
218−{"max", math_max},
219−{"log", math_log},
220−{"log10", math_log10},
221−{"exp", math_exp},
222−{"deg", math_deg},
223−{"rad", math_rad},
224−{"random", math_random},
225−{"randomseed", math_randomseed}
204+static const luaL_reg mathlib[] = {
205+ {"abs", math_abs},
206+ {"sin", math_sin},
207+ {"cos", math_cos},
208+ {"tan", math_tan},
209+ {"asin", math_asin},
210+ {"acos", math_acos},
211+ {"atan", math_atan},
212+ {"atan2", math_atan2},
213+ {"ceil", math_ceil},
214+ {"floor", math_floor},
215+ {"mod", math_mod},
216+ {"frexp", math_frexp},
217+ {"ldexp", math_ldexp},
218+ {"sqrt", math_sqrt},
219+ {"min", math_min},
220+ {"max", math_max},
221+ {"log", math_log},
222+ {"log10", math_log10},
223+ {"exp", math_exp},
224+ {"deg", math_deg},
225+ {"pow", math_pow},
226+ {"rad", math_rad},
227+ {"random", math_random},
228+ {"randomseed", math_randomseed},
229+ {NULL, NULL}
226230 };
227231
232+
228233 /*
229234 ** Open math library
230235 */
231−LUALIB_API void lua_mathlibopen (lua_State *L) {
232− luaL_openl(L, mathlib);
233− lua_pushcfunction(L, math_pow);
234− lua_settagmethod(L, LUA_TNUMBER, "pow");
236+LUALIB_API int luaopen_math (lua_State *L) {
237+ luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
238+ lua_pushliteral(L, "pi");
235239 lua_pushnumber(L, PI);
236− lua_setglobal(L, "PI");
240+ lua_settable(L, -3);
241+ lua_pushliteral(L, "__pow");
242+ lua_pushcfunction(L, math_pow);
243+ lua_settable(L, LUA_GLOBALSINDEX);
244+ return 1;
237245 }
238246
src/lib/loadlib.c+205−0
@@ -0,0 +1,205 @@
1+/*
2+** $Id: loadlib.c,v 1.4 2003/04/07 20:11:53 roberto Exp $
3+** Dynamic library loader for Lua
4+** See Copyright Notice in lua.h
5+*
6+* This Lua library exports a single function, called loadlib, which is
7+* called from Lua as loadlib(lib,init), where lib is the full name of the
8+* library to be loaded (including the complete path) and init is the name
9+* of a function to be called after the library is loaded. Typically, this
10+* function will register other functions, thus making the complete library
11+* available to Lua. The init function is *not* automatically called by
12+* loadlib. Instead, loadlib returns the init function as a Lua function
13+* that the client can call when it thinks is appropriate. In the case of
14+* errors, loadlib returns nil and two strings describing the error.
15+* The first string is supplied by the operating system; it should be
16+* informative and useful for error messages. The second string is "open",
17+* "init", or "absent" to identify the error and is meant to be used for
18+* making decisions without having to look into the first string (whose
19+* format is system-dependent).
20+*
21+* This module contains an implementation of loadlib for Unix systems that
22+* have dlfcn, an implementation for Windows, and a stub for other systems.
23+* See the list at the end of this file for some links to available
24+* implementations of dlfcn and interfaces to other native dynamic loaders
25+* on top of which loadlib could be implemented.
26+*
27+*/
28+
29+#include "lua.h"
30+#include "lauxlib.h"
31+#include "lualib.h"
32+
33+
34+#undef LOADLIB
35+
36+
37+#ifdef USE_DLOPEN
38+#define LOADLIB
39+/*
40+* This is an implementation of loadlib based on the dlfcn interface.
41+* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
42+* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
43+* as an emulation layer on top of native functions.
44+*/
45+
46+#include <dlfcn.h>
47+
48+static int loadlib(lua_State *L)
49+{
50+ const char *path=luaL_checkstring(L,1);
51+ const char *init=luaL_checkstring(L,2);
52+ void *lib=dlopen(path,RTLD_NOW);
53+ if (lib!=NULL)
54+ {
55+ lua_CFunction f=(lua_CFunction) dlsym(lib,init);
56+ if (f!=NULL)
57+ {
58+ lua_pushlightuserdata(L,lib);
59+ lua_pushcclosure(L,f,1);
60+ return 1;
61+ }
62+ }
63+ /* else return appropriate error messages */
64+ lua_pushnil(L);
65+ lua_pushstring(L,dlerror());
66+ lua_pushstring(L,(lib!=NULL) ? "init" : "open");
67+ if (lib!=NULL) dlclose(lib);
68+ return 3;
69+}
70+
71+#endif
72+
73+
74+
75+/*
76+** In Windows, default is to use dll; otherwise, default is not to use dll
77+*/
78+#ifndef USE_DLL
79+#ifdef _WIN32
80+#define USE_DLL 1
81+#else
82+#define USE_DLL 0
83+#endif
84+#endif
85+
86+
87+#if USE_DLL
88+#define LOADLIB
89+/*
90+* This is an implementation of loadlib for Windows using native functions.
91+*/
92+
93+#include <windows.h>
94+
95+static void pusherror(lua_State *L)
96+{
97+ int error=GetLastError();
98+ char buffer[128];
99+ if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
100+ 0, error, 0, buffer, sizeof(buffer), 0))
101+ lua_pushstring(L,buffer);
102+ else
103+ lua_pushfstring(L,"system error %d\n",error);
104+}
105+
106+static int loadlib(lua_State *L)
107+{
108+ const char *path=luaL_checkstring(L,1);
109+ const char *init=luaL_checkstring(L,2);
110+ HINSTANCE lib=LoadLibrary(path);
111+ if (lib!=NULL)
112+ {
113+ lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
114+ if (f!=NULL)
115+ {
116+ lua_pushlightuserdata(L,lib);
117+ lua_pushcclosure(L,f,1);
118+ return 1;
119+ }
120+ }
121+ lua_pushnil(L);
122+ pusherror(L);
123+ lua_pushstring(L,(lib!=NULL) ? "init" : "open");
124+ if (lib!=NULL) FreeLibrary(lib);
125+ return 3;
126+}
127+
128+#endif
129+
130+
131+
132+#ifndef LOADLIB
133+/* Fallback for other systems */
134+
135+/*
136+** Those systems support dlopen, so they should have defined USE_DLOPEN.
137+** The default (no)implementation gives them a special error message.
138+*/
139+#ifdef linux
140+#define LOADLIB
141+#endif
142+
143+#ifdef sun
144+#define LOADLIB
145+#endif
146+
147+#ifdef sgi
148+#define LOADLIB
149+#endif
150+
151+#ifdef BSD
152+#define LOADLIB
153+#endif
154+
155+#ifdef _WIN32
156+#define LOADLIB
157+#endif
158+
159+#ifdef LOADLIB
160+#undef LOADLIB
161+#define LOADLIB "`loadlib' not installed (check your Lua configuration)"
162+#else
163+#define LOADLIB "`loadlib' not supported"
164+#endif
165+
166+static int loadlib(lua_State *L)
167+{
168+ lua_pushnil(L);
169+ lua_pushliteral(L,LOADLIB);
170+ lua_pushliteral(L,"absent");
171+ return 3;
172+}
173+#endif
174+
175+LUALIB_API int luaopen_loadlib (lua_State *L)
176+{
177+ lua_register(L,"loadlib",loadlib);
178+ return 0;
179+}
180+
181+/*
182+* Here are some links to available implementations of dlfcn and
183+* interfaces to other native dynamic loaders on top of which loadlib
184+* could be implemented. Please send contributions and corrections to us.
185+*
186+* AIX
187+* Starting with AIX 4.2, dlfcn is included in the base OS.
188+* There is also an emulation package available.
189+* http://www.faqs.org/faqs/aix-faq/part4/section-21.html
190+*
191+* HPUX
192+* HPUX 11 has dlfcn. For HPUX 10 use shl_*.
193+* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
194+* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
195+*
196+* Macintosh, Windows
197+* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
198+*
199+* Mac OS X/Darwin
200+* http://www.opendarwin.org/projects/dlcompat/
201+*
202+* GLIB has wrapper code for BeOS, OS2, Unix and Windows
203+* http://cvs.gnome.org/lxr/source/glib/gmodule/
204+*
205+*/
src/lib/lstrlib.c+374−225
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstrlib.c,v 1.56 2000/10/27 16:15:53 roberto Exp $
2+** $Id: lstrlib.c,v 1.98 2003/04/03 13:35:34 roberto Exp $
33 ** Standard library for string operations and pattern-matching
44 ** See Copyright Notice in lua.h
55 */
@@ -11,37 +11,47 @@ · 5 unmodified lines
1111 #include <stdlib.h>
1212 #include <string.h>
1313
14+#define lstrlib_c
15+
1416 #include "lua.h"
1517
1618 #include "lauxlib.h"
1719 #include "lualib.h"
1820
1921
22+/* macro to `unsign' a character */
23+#ifndef uchar
24+#define uchar(c) ((unsigned char)(c))
25+#endif
26+
27+
28+typedef long sint32; /* a signed version for size_t */
29+
2030
2131 static int str_len (lua_State *L) {
2232 size_t l;
23− luaL_check_lstr(L, 1, &l);
24− lua_pushnumber(L, l);
33+ luaL_checklstring(L, 1, &l);
34+ lua_pushnumber(L, (lua_Number)l);
2535 return 1;
2636 }
2737
2838
29−static long posrelat (long pos, size_t len) {
39+static sint32 posrelat (sint32 pos, size_t len) {
3040 /* relative string position: negative means back from end */
31− return (pos>=0) ? pos : (long)len+pos+1;
41+ return (pos>=0) ? pos : (sint32)len+pos+1;
3242 }
3343
3444
3545 static int str_sub (lua_State *L) {
3646 size_t l;
37− const char *s = luaL_check_lstr(L, 1, &l);
38− long start = posrelat(luaL_check_long(L, 2), l);
39− long end = posrelat(luaL_opt_long(L, 3, -1), l);
47+ const char *s = luaL_checklstring(L, 1, &l);
48+ sint32 start = posrelat(luaL_checklong(L, 2), l);
49+ sint32 end = posrelat(luaL_optlong(L, 3, -1), l);
4050 if (start < 1) start = 1;
41− if (end > (long)l) end = l;
51+ if (end > (sint32)l) end = (sint32)l;
4252 if (start <= end)
4353 lua_pushlstring(L, s+start-1, end-start+1);
44− else lua_pushstring(L, "");
54+ else lua_pushliteral(L, "");
4555 return 1;
4656 }
4757
@@ -50,10 +60,10 @@ static int str_lower (lua_State *L) { · 2 unmodified lines
5060 size_t l;
5161 size_t i;
5262 luaL_Buffer b;
53− const char *s = luaL_check_lstr(L, 1, &l);
63+ const char *s = luaL_checklstring(L, 1, &l);
5464 luaL_buffinit(L, &b);
5565 for (i=0; i<l; i++)
56− luaL_putchar(&b, tolower((unsigned char)(s[i])));
66+ luaL_putchar(&b, tolower(uchar(s[i])));
5767 luaL_pushresult(&b);
5868 return 1;
5969 }
@@ -63,10 +73,10 @@ static int str_upper (lua_State *L) { · 3 unmodified lines
6373 size_t l;
6474 size_t i;
6575 luaL_Buffer b;
66− const char *s = luaL_check_lstr(L, 1, &l);
76+ const char *s = luaL_checklstring(L, 1, &l);
6777 luaL_buffinit(L, &b);
6878 for (i=0; i<l; i++)
69− luaL_putchar(&b, toupper((unsigned char)(s[i])));
79+ luaL_putchar(&b, toupper(uchar(s[i])));
7080 luaL_pushresult(&b);
7181 return 1;
7282 }
@@ -74,8 +84,8 @@ static int str_upper (lua_State *L) { · 1 unmodified line
7484 static int str_rep (lua_State *L) {
7585 size_t l;
7686 luaL_Buffer b;
77− const char *s = luaL_check_lstr(L, 1, &l);
78− int n = luaL_check_int(L, 2);
87+ const char *s = luaL_checklstring(L, 1, &l);
88+ int n = luaL_checkint(L, 2);
7989 luaL_buffinit(L, &b);
8090 while (n-- > 0)
8191 luaL_addlstring(&b, s, l);
@@ -86,10 +96,11 @@ static int str_rep (lua_State *L) { · 4 unmodified lines
8696
8797 static int str_byte (lua_State *L) {
8898 size_t l;
89− const char *s = luaL_check_lstr(L, 1, &l);
90− long pos = posrelat(luaL_opt_long(L, 2, 1), l);
91− luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range");
92− lua_pushnumber(L, (unsigned char)s[pos-1]);
99+ const char *s = luaL_checklstring(L, 1, &l);
100+ sint32 pos = posrelat(luaL_optlong(L, 2, 1), l);
101+ if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */
102+ return 0; /* no answer */
103+ lua_pushnumber(L, uchar(s[pos-1]));
93104 return 1;
94105 }
95106
@@ -100,15 +111,33 @@ static int str_char (lua_State *L) { · 4 unmodified lines
100111 luaL_Buffer b;
101112 luaL_buffinit(L, &b);
102113 for (i=1; i<=n; i++) {
103− int c = luaL_check_int(L, i);
104− luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
105− luaL_putchar(&b, (unsigned char)c);
114+ int c = luaL_checkint(L, i);
115+ luaL_argcheck(L, uchar(c) == c, i, "invalid value");
116+ luaL_putchar(&b, uchar(c));
106117 }
107118 luaL_pushresult(&b);
108119 return 1;
109120 }
110121
111122
123+static int writer (lua_State *L, const void* b, size_t size, void* B) {
124+ (void)L;
125+ luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
126+ return 1;
127+}
128+
129+
130+static int str_dump (lua_State *L) {
131+ luaL_Buffer b;
132+ luaL_checktype(L, 1, LUA_TFUNCTION);
133+ luaL_buffinit(L,&b);
134+ if (!lua_dump(L, writer, &b))
135+ luaL_error(L, "unable to dump given function");
136+ luaL_pushresult(&b);
137+ return 1;
138+}
139+
140+
112141
113142 /*
114143 ** {======================================================
@@ -121,51 +150,61 @@ static int str_char (lua_State *L) { · 6 unmodified lines
121150 #endif
122151
123152
124−struct Capture {
125− const char *src_end; /* end ('\0') of source string */
153+#define CAP_UNFINISHED (-1)
154+#define CAP_POSITION (-2)
155+
156+typedef struct MatchState {
157+ const char *src_init; /* init of source string */
158+ const char *src_end; /* end (`\0') of source string */
159+ lua_State *L;
126160 int level; /* total number of captures (finished or unfinished) */
127161 struct {
128162 const char *init;
129− long len; /* -1 signals unfinished capture */
163+ sint32 len;
130164 } capture[MAX_CAPTURES];
131−};
165+} MatchState;
132166
133167
134168 #define ESC '%'
135169 #define SPECIALS "^$*+?.([%-"
136170
137171
138−static int check_capture (lua_State *L, int l, struct Capture *cap) {
172+static int check_capture (MatchState *ms, int l) {
139173 l -= '1';
140− if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
141− lua_error(L, "invalid capture index");
174+ if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
175+ return luaL_error(ms->L, "invalid capture index");
142176 return l;
143177 }
144178
145179
146−static int capture_to_close (lua_State *L, struct Capture *cap) {
147− int level = cap->level;
180+static int capture_to_close (MatchState *ms) {
181+ int level = ms->level;
148182 for (level--; level>=0; level--)
149− if (cap->capture[level].len == -1) return level;
150− lua_error(L, "invalid pattern capture");
151− return 0; /* to avoid warnings */
183+ if (ms->capture[level].len == CAP_UNFINISHED) return level;
184+ return luaL_error(ms->L, "invalid pattern capture");
152185 }
153186
154187
155−const char *luaI_classend (lua_State *L, const char *p) {
188+static const char *luaI_classend (MatchState *ms, const char *p) {
156189 switch (*p++) {
157− case ESC:
158− if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')");
190+ case ESC: {
191+ if (*p == '\0')
192+ luaL_error(ms->L, "malformed pattern (ends with `%')");
159193 return p+1;
160− case '[':
194+ }
195+ case '[': {
161196 if (*p == '^') p++;
162− do { /* look for a ']' */
163− if (*p == '\0') lua_error(L, "malformed pattern (missing `]')");
164− if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */
197+ do { /* look for a `]' */
198+ if (*p == '\0')
199+ luaL_error(ms->L, "malformed pattern (missing `]')");
200+ if (*(p++) == ESC && *p != '\0')
201+ p++; /* skip escapes (e.g. `%]') */
165202 } while (*p != ']');
166203 return p+1;
167− default:
204+ }
205+ default: {
168206 return p;
207+ }
169208 }
170209 }
171210
@@ -182,66 +221,59 @@ static int match_class (int c, int cl) { · 10 unmodified lines
182221 case 'u' : res = isupper(c); break;
183222 case 'w' : res = isalnum(c); break;
184223 case 'x' : res = isxdigit(c); break;
185− case 'z' : res = (c == '\0'); break;
224+ case 'z' : res = (c == 0); break;
186225 default: return (cl == c);
187226 }
188227 return (islower(cl) ? res : !res);
189228 }
190229
191230
192−
193−static int matchbracketclass (int c, const char *p, const char *endclass) {
231+static int matchbracketclass (int c, const char *p, const char *ec) {
194232 int sig = 1;
195233 if (*(p+1) == '^') {
196234 sig = 0;
197− p++; /* skip the '^' */
235+ p++; /* skip the `^' */
198236 }
199− while (++p < endclass) {
237+ while (++p < ec) {
200238 if (*p == ESC) {
201239 p++;
202− if (match_class(c, (unsigned char)*p))
240+ if (match_class(c, *p))
203241 return sig;
204242 }
205− else if ((*(p+1) == '-') && (p+2 < endclass)) {
243+ else if ((*(p+1) == '-') && (p+2 < ec)) {
206244 p+=2;
207− if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
245+ if (uchar(*(p-2)) <= c && c <= uchar(*p))
208246 return sig;
209247 }
210− else if ((int)(unsigned char)*p == c) return sig;
248+ else if (uchar(*p) == c) return sig;
211249 }
212250 return !sig;
213251 }
214252
215253
216−
217−int luaI_singlematch (int c, const char *p, const char *ep) {
254+static int luaI_singlematch (int c, const char *p, const char *ep) {
218255 switch (*p) {
219− case '.': /* matches any char */
220− return 1;
221− case ESC:
222− return match_class(c, (unsigned char)*(p+1));
223− case '[':
224− return matchbracketclass(c, p, ep-1);
225− default:
226− return ((unsigned char)*p == c);
256+ case '.': return 1; /* matches any char */
257+ case ESC: return match_class(c, *(p+1));
258+ case '[': return matchbracketclass(c, p, ep-1);
259+ default: return (uchar(*p) == c);
227260 }
228261 }
229262
230263
231−static const char *match (lua_State *L, const char *s, const char *p,
232− struct Capture *cap);
264+static const char *match (MatchState *ms, const char *s, const char *p);
233265
234266
235−static const char *matchbalance (lua_State *L, const char *s, const char *p,
236− struct Capture *cap) {
267+static const char *matchbalance (MatchState *ms, const char *s,
268+ const char *p) {
237269 if (*p == 0 || *(p+1) == 0)
238− lua_error(L, "unbalanced pattern");
270+ luaL_error(ms->L, "unbalanced pattern");
239271 if (*s != *p) return NULL;
240272 else {
241273 int b = *p;
242274 int e = *(p+1);
243275 int cont = 1;
244− while (++s < cap->src_end) {
276+ while (++s < ms->src_end) {
245277 if (*s == e) {
246278 if (--cont == 0) return s+1;
247279 }
@@ -252,14 +284,14 @@ static const char *matchbalance (lua_State *L, const char *s, const char *p, · 4 unmodified lines
252284 }
253285
254286
255−static const char *max_expand (lua_State *L, const char *s, const char *p,
256− const char *ep, struct Capture *cap) {
257− long i = 0; /* counts maximum expand for item */
258− while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
287+static const char *max_expand (MatchState *ms, const char *s,
288+ const char *p, const char *ep) {
289+ sint32 i = 0; /* counts maximum expand for item */
290+ while ((s+i)<ms->src_end && luaI_singlematch(uchar(*(s+i)), p, ep))
259291 i++;
260292 /* keeps trying to match with the maximum repetitions */
261293 while (i>=0) {
262− const char *res = match(L, (s+i), ep+1, cap);
294+ const char *res = match(ms, (s+i), ep+1);
263295 if (res) return res;
264296 i--; /* else didn't match; reduce 1 repetition to try again */
265297 }
@@ -267,100 +299,126 @@ static const char *max_expand (lua_State *L, const char *s, const char *p, · 1 unmodified line
267299 }
268300
269301
270−static const char *min_expand (lua_State *L, const char *s, const char *p,
271− const char *ep, struct Capture *cap) {
302+static const char *min_expand (MatchState *ms, const char *s,
303+ const char *p, const char *ep) {
272304 for (;;) {
273− const char *res = match(L, s, ep+1, cap);
305+ const char *res = match(ms, s, ep+1);
274306 if (res != NULL)
275307 return res;
276− else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
308+ else if (s<ms->src_end && luaI_singlematch(uchar(*s), p, ep))
277309 s++; /* try with one more repetition */
278310 else return NULL;
279311 }
280312 }
281313
282314
283−static const char *start_capture (lua_State *L, const char *s, const char *p,
284− struct Capture *cap) {
315+static const char *start_capture (MatchState *ms, const char *s,
316+ const char *p, int what) {
285317 const char *res;
286− int level = cap->level;
287− if (level >= MAX_CAPTURES) lua_error(L, "too many captures");
288− cap->capture[level].init = s;
289− cap->capture[level].len = -1;
290− cap->level = level+1;
291− if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */
292− cap->level--; /* undo capture */
318+ int level = ms->level;
319+ if (level >= MAX_CAPTURES) luaL_error(ms->L, "too many captures");
320+ ms->capture[level].init = s;
321+ ms->capture[level].len = what;
322+ ms->level = level+1;
323+ if ((res=match(ms, s, p)) == NULL) /* match failed? */
324+ ms->level--; /* undo capture */
293325 return res;
294326 }
295327
296328
297−static const char *end_capture (lua_State *L, const char *s, const char *p,
298− struct Capture *cap) {
299− int l = capture_to_close(L, cap);
329+static const char *end_capture (MatchState *ms, const char *s,
330+ const char *p) {
331+ int l = capture_to_close(ms);
300332 const char *res;
301− cap->capture[l].len = s - cap->capture[l].init; /* close capture */
302− if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */
303− cap->capture[l].len = -1; /* undo capture */
333+ ms->capture[l].len = s - ms->capture[l].init; /* close capture */
334+ if ((res = match(ms, s, p)) == NULL) /* match failed? */
335+ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
304336 return res;
305337 }
306338
307339
308−static const char *match_capture (lua_State *L, const char *s, int level,
309− struct Capture *cap) {
310− int l = check_capture(L, level, cap);
311− size_t len = cap->capture[l].len;
312− if ((size_t)(cap->src_end-s) >= len &&
313− memcmp(cap->capture[l].init, s, len) == 0)
340+static const char *match_capture (MatchState *ms, const char *s, int l) {
341+ size_t len;
342+ l = check_capture(ms, l);
343+ len = ms->capture[l].len;
344+ if ((size_t)(ms->src_end-s) >= len &&
345+ memcmp(ms->capture[l].init, s, len) == 0)
314346 return s+len;
315347 else return NULL;
316348 }
317349
318350
319−static const char *match (lua_State *L, const char *s, const char *p,
320− struct Capture *cap) {
351+static const char *match (MatchState *ms, const char *s, const char *p) {
321352 init: /* using goto's to optimize tail recursion */
322353 switch (*p) {
323− case '(': /* start capture */
324− return start_capture(L, s, p, cap);
325− case ')': /* end capture */
326− return end_capture(L, s, p, cap);
327− case ESC: /* may be %[0-9] or %b */
328− if (isdigit((unsigned char)(*(p+1)))) { /* capture? */
329− s = match_capture(L, s, *(p+1), cap);
330− if (s == NULL) return NULL;
331− p+=2; goto init; /* else return match(L, s, p+2, cap) */
332− }
333− else if (*(p+1) == 'b') { /* balanced string? */
334− s = matchbalance(L, s, p+2, cap);
335− if (s == NULL) return NULL;
336− p+=4; goto init; /* else return match(L, s, p+4, cap); */
354+ case '(': { /* start capture */
355+ if (*(p+1) == ')') /* position capture? */
356+ return start_capture(ms, s, p+2, CAP_POSITION);
357+ else
358+ return start_capture(ms, s, p+1, CAP_UNFINISHED);
359+ }
360+ case ')': { /* end capture */
361+ return end_capture(ms, s, p+1);
362+ }
363+ case ESC: {
364+ switch (*(p+1)) {
365+ case 'b': { /* balanced string? */
366+ s = matchbalance(ms, s, p+2);
367+ if (s == NULL) return NULL;
368+ p+=4; goto init; /* else return match(ms, s, p+4); */
369+ }
370+ case 'f': { /* frontier? */
371+ const char *ep; char previous;
372+ p += 2;
373+ if (*p != '[')
374+ luaL_error(ms->L, "missing `[' after `%%f' in pattern");
375+ ep = luaI_classend(ms, p); /* points to what is next */
376+ previous = (s == ms->src_init) ? '\0' : *(s-1);
377+ if (matchbracketclass(uchar(previous), p, ep-1) ||
378+ !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
379+ p=ep; goto init; /* else return match(ms, s, ep); */
380+ }
381+ default: {
382+ if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
383+ s = match_capture(ms, s, *(p+1));
384+ if (s == NULL) return NULL;
385+ p+=2; goto init; /* else return match(ms, s, p+2) */
386+ }
387+ goto dflt; /* case default */
388+ }
337389 }
338− else goto dflt; /* case default */
339− case '\0': /* end of pattern */
390+ }
391+ case '\0': { /* end of pattern */
340392 return s; /* match succeeded */
341− case '$':
342− if (*(p+1) == '\0') /* is the '$' the last char in pattern? */
343− return (s == cap->src_end) ? s : NULL; /* check end of string */
393+ }
394+ case '$': {
395+ if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
396+ return (s == ms->src_end) ? s : NULL; /* check end of string */
344397 else goto dflt;
398+ }
345399 default: dflt: { /* it is a pattern item */
346− const char *ep = luaI_classend(L, p); /* points to what is next */
347− int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
400+ const char *ep = luaI_classend(ms, p); /* points to what is next */
401+ int m = s<ms->src_end && luaI_singlematch(uchar(*s), p, ep);
348402 switch (*ep) {
349403 case '?': { /* optional */
350404 const char *res;
351− if (m && ((res=match(L, s+1, ep+1, cap)) != NULL))
405+ if (m && ((res=match(ms, s+1, ep+1)) != NULL))
352406 return res;
353− p=ep+1; goto init; /* else return match(L, s, ep+1, cap); */
407+ p=ep+1; goto init; /* else return match(ms, s, ep+1); */
408+ }
409+ case '*': { /* 0 or more repetitions */
410+ return max_expand(ms, s, p, ep);
411+ }
412+ case '+': { /* 1 or more repetitions */
413+ return (m ? max_expand(ms, s+1, p, ep) : NULL);
414+ }
415+ case '-': { /* 0 or more repetitions (minimum) */
416+ return min_expand(ms, s, p, ep);
354417 }
355− case '*': /* 0 or more repetitions */
356− return max_expand(L, s, p, ep, cap);
357− case '+': /* 1 or more repetitions */
358− return (m ? max_expand(L, s+1, p, ep, cap) : NULL);
359− case '-': /* 0 or more repetitions (minimum) */
360− return min_expand(L, s, p, ep, cap);
361− default:
418+ default: {
362419 if (!m) return NULL;
363− s++; p=ep; goto init; /* else return match(L, s+1, ep, cap); */
420+ s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
421+ }
364422 }
365423 }
366424 }
@@ -369,7 +427,7 @@ static const char *match (lua_State *L, const char *s, const char *p, · 2 unmodified lines
369427
370428
371429 static const char *lmemfind (const char *s1, size_t l1,
372− const char *s2, size_t l2) {
430+ const char *s2, size_t l2) {
373431 if (l2 == 0) return s1; /* empty strings are everywhere */
374432 else if (l2 > l1) return NULL; /* avoids a negative `l1' */
375433 else {
@@ -390,54 +448,109 @@ static const char *lmemfind (const char *s1, size_t l1, · 14 unmodified lines
390448 }
391449
392450
393−static int push_captures (lua_State *L, struct Capture *cap) {
451+static void push_onecapture (MatchState *ms, int i) {
452+ int l = ms->capture[i].len;
453+ if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
454+ if (l == CAP_POSITION)
455+ lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1));
456+ else
457+ lua_pushlstring(ms->L, ms->capture[i].init, l);
458+}
459+
460+
461+static int push_captures (MatchState *ms, const char *s, const char *e) {
394462 int i;
395− luaL_checkstack(L, cap->level, "too many captures");
396− for (i=0; i<cap->level; i++) {
397− int l = cap->capture[i].len;
398− if (l == -1) lua_error(L, "unfinished capture");
399− lua_pushlstring(L, cap->capture[i].init, l);
463+ luaL_checkstack(ms->L, ms->level, "too many captures");
464+ if (ms->level == 0 && s) { /* no explicit captures? */
465+ lua_pushlstring(ms->L, s, e-s); /* return whole match */
466+ return 1;
467+ }
468+ else { /* return all captures */
469+ for (i=0; i<ms->level; i++)
470+ push_onecapture(ms, i);
471+ return ms->level; /* number of strings pushed */
400472 }
401− return cap->level; /* number of strings pushed */
402473 }
403474
404475
405476 static int str_find (lua_State *L) {
406477 size_t l1, l2;
407− const char *s = luaL_check_lstr(L, 1, &l1);
408− const char *p = luaL_check_lstr(L, 2, &l2);
409− long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
410− struct Capture cap;
411− luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
412− if (lua_gettop(L) > 3 || /* extra argument? */
478+ const char *s = luaL_checklstring(L, 1, &l1);
479+ const char *p = luaL_checklstring(L, 2, &l2);
480+ sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1;
481+ if (init < 0) init = 0;
482+ else if ((size_t)(init) > l1) init = (sint32)l1;
483+ if (lua_toboolean(L, 4) || /* explicit request? */
413484 strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
485+ /* do a plain search */
414486 const char *s2 = lmemfind(s+init, l1-init, p, l2);
415487 if (s2) {
416− lua_pushnumber(L, s2-s+1);
417− lua_pushnumber(L, s2-s+l2);
488+ lua_pushnumber(L, (lua_Number)(s2-s+1));
489+ lua_pushnumber(L, (lua_Number)(s2-s+l2));
418490 return 2;
419491 }
420492 }
421493 else {
494+ MatchState ms;
422495 int anchor = (*p == '^') ? (p++, 1) : 0;
423496 const char *s1=s+init;
424− cap.src_end = s+l1;
497+ ms.L = L;
498+ ms.src_init = s;
499+ ms.src_end = s+l1;
425500 do {
426501 const char *res;
427− cap.level = 0;
428− if ((res=match(L, s1, p, &cap)) != NULL) {
429− lua_pushnumber(L, s1-s+1); /* start */
430− lua_pushnumber(L, res-s); /* end */
431− return push_captures(L, &cap) + 2;
502+ ms.level = 0;
503+ if ((res=match(&ms, s1, p)) != NULL) {
504+ lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */
505+ lua_pushnumber(L, (lua_Number)(res-s)); /* end */
506+ return push_captures(&ms, NULL, 0) + 2;
432507 }
433− } while (s1++<cap.src_end && !anchor);
508+ } while (s1++<ms.src_end && !anchor);
434509 }
435510 lua_pushnil(L); /* not found */
436511 return 1;
437512 }
438513
439514
440−static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) {
515+static int gfind_aux (lua_State *L) {
516+ MatchState ms;
517+ const char *s = lua_tostring(L, lua_upvalueindex(1));
518+ size_t ls = lua_strlen(L, lua_upvalueindex(1));
519+ const char *p = lua_tostring(L, lua_upvalueindex(2));
520+ const char *src;
521+ ms.L = L;
522+ ms.src_init = s;
523+ ms.src_end = s+ls;
524+ for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3));
525+ src <= ms.src_end;
526+ src++) {
527+ const char *e;
528+ ms.level = 0;
529+ if ((e = match(&ms, src, p)) != NULL) {
530+ int newstart = e-s;
531+ if (e == src) newstart++; /* empty match? go at least one position */
532+ lua_pushnumber(L, (lua_Number)newstart);
533+ lua_replace(L, lua_upvalueindex(3));
534+ return push_captures(&ms, src, e);
535+ }
536+ }
537+ return 0; /* not found */
538+}
539+
540+
541+static int gfind (lua_State *L) {
542+ luaL_checkstring(L, 1);
543+ luaL_checkstring(L, 2);
544+ lua_settop(L, 2);
545+ lua_pushnumber(L, 0);
546+ lua_pushcclosure(L, gfind_aux, 3);
547+ return 1;
548+}
549+
550+
551+static void add_s (MatchState *ms, luaL_Buffer *b,
552+ const char *s, const char *e) {
553+ lua_State *L = ms->L;
441554 if (lua_isstring(L, 3)) {
442555 const char *news = lua_tostring(L, 3);
443556 size_t l = lua_strlen(L, 3);
@@ -447,11 +560,12 @@ static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) { · 3 unmodified lines
447560 luaL_putchar(b, news[i]);
448561 else {
449562 i++; /* skip ESC */
450− if (!isdigit((unsigned char)news[i]))
563+ if (!isdigit(uchar(news[i])))
451564 luaL_putchar(b, news[i]);
452565 else {
453− int level = check_capture(L, news[i], cap);
454− luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len);
566+ int level = check_capture(ms, news[i]);
567+ push_onecapture(ms, level);
568+ luaL_addvalue(b); /* add capture to accumulated result */
455569 }
456570 }
457571 }
@@ -459,8 +573,8 @@ static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) { · 1 unmodified line
459573 else { /* is a function */
460574 int n;
461575 lua_pushvalue(L, 3);
462− n = push_captures(L, cap);
463− lua_rawcall(L, n, 1);
576+ n = push_captures(ms, s, e);
577+ lua_call(L, n, 1);
464578 if (lua_isstring(L, -1))
465579 luaL_addvalue(b); /* add return to accumulated result */
466580 else
@@ -471,124 +585,155 @@ static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) { · 4 unmodified lines
471585
472586 static int str_gsub (lua_State *L) {
473587 size_t srcl;
474− const char *src = luaL_check_lstr(L, 1, &srcl);
475− const char *p = luaL_check_string(L, 2);
476− int max_s = luaL_opt_int(L, 4, srcl+1);
588+ const char *src = luaL_checklstring(L, 1, &srcl);
589+ const char *p = luaL_checkstring(L, 2);
590+ int max_s = luaL_optint(L, 4, srcl+1);
477591 int anchor = (*p == '^') ? (p++, 1) : 0;
478592 int n = 0;
479− struct Capture cap;
593+ MatchState ms;
480594 luaL_Buffer b;
481− luaL_arg_check(L,
595+ luaL_argcheck(L,
482596 lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
483597 3, "string or function expected");
484598 luaL_buffinit(L, &b);
485− cap.src_end = src+srcl;
599+ ms.L = L;
600+ ms.src_init = src;
601+ ms.src_end = src+srcl;
486602 while (n < max_s) {
487603 const char *e;
488− cap.level = 0;
489− e = match(L, src, p, &cap);
604+ ms.level = 0;
605+ e = match(&ms, src, p);
490606 if (e) {
491607 n++;
492− add_s(L, &b, &cap);
608+ add_s(&ms, &b, src, e);
493609 }
494610 if (e && e>src) /* non empty match? */
495611 src = e; /* skip it */
496− else if (src < cap.src_end)
612+ else if (src < ms.src_end)
497613 luaL_putchar(&b, *src++);
498614 else break;
499615 if (anchor) break;
500616 }
501− luaL_addlstring(&b, src, cap.src_end-src);
617+ luaL_addlstring(&b, src, ms.src_end-src);
502618 luaL_pushresult(&b);
503− lua_pushnumber(L, n); /* number of substitutions */
619+ lua_pushnumber(L, (lua_Number)n); /* number of substitutions */
504620 return 2;
505621 }
506622
507623 /* }====================================================== */
508624
509625
626+/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
627+#define MAX_ITEM 512
628+/* maximum size of each format specification (such as '%-099.99d') */
629+#define MAX_FORMAT 20
630+
631+
510632 static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
511633 size_t l;
512− const char *s = luaL_check_lstr(L, arg, &l);
634+ const char *s = luaL_checklstring(L, arg, &l);
513635 luaL_putchar(b, '"');
514636 while (l--) {
515637 switch (*s) {
516− case '"': case '\\': case '\n':
638+ case '"': case '\\': case '\n': {
517639 luaL_putchar(b, '\\');
518640 luaL_putchar(b, *s);
519641 break;
520− case '\0': luaL_addlstring(b, "\\000", 4); break;
521− default: luaL_putchar(b, *s);
642+ }
643+ case '\0': {
644+ luaL_addlstring(b, "\\000", 4);
645+ break;
646+ }
647+ default: {
648+ luaL_putchar(b, *s);
649+ break;
650+ }
522651 }
523652 s++;
524653 }
525654 luaL_putchar(b, '"');
526655 }
527656
528−/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
529−#define MAX_ITEM 512
530−/* maximum size of each format specification (such as '%-099.99d') */
531−#define MAX_FORMAT 20
657+
658+static const char *scanformat (lua_State *L, const char *strfrmt,
659+ char *form, int *hasprecision) {
660+ const char *p = strfrmt;
661+ while (strchr("-+ #0", *p)) p++; /* skip flags */
662+ if (isdigit(uchar(*p))) p++; /* skip width */
663+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
664+ if (*p == '.') {
665+ p++;
666+ *hasprecision = 1;
667+ if (isdigit(uchar(*p))) p++; /* skip precision */
668+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
669+ }
670+ if (isdigit(uchar(*p)))
671+ luaL_error(L, "invalid format (width or precision too long)");
672+ if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */
673+ luaL_error(L, "invalid format (too long)");
674+ form[0] = '%';
675+ strncpy(form+1, strfrmt, p-strfrmt+1);
676+ form[p-strfrmt+2] = 0;
677+ return p;
678+}
679+
532680
533681 static int str_format (lua_State *L) {
534682 int arg = 1;
535− const char *strfrmt = luaL_check_string(L, arg);
683+ size_t sfl;
684+ const char *strfrmt = luaL_checklstring(L, arg, &sfl);
685+ const char *strfrmt_end = strfrmt+sfl;
536686 luaL_Buffer b;
537687 luaL_buffinit(L, &b);
538− while (*strfrmt) {
688+ while (strfrmt < strfrmt_end) {
539689 if (*strfrmt != '%')
540690 luaL_putchar(&b, *strfrmt++);
541691 else if (*++strfrmt == '%')
542692 luaL_putchar(&b, *strfrmt++); /* %% */
543693 else { /* format item */
544− struct Capture cap;
545− char form[MAX_FORMAT]; /* to store the format ('%...') */
694+ char form[MAX_FORMAT]; /* to store the format (`%...') */
546695 char buff[MAX_ITEM]; /* to store the formatted item */
547− const char *initf = strfrmt;
548− form[0] = '%';
549− if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
550− arg = *initf - '0';
551− initf += 2; /* skip the 'n$' */
552− }
696+ int hasprecision = 0;
697+ if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$')
698+ return luaL_error(L, "obsolete option (d$) to `format'");
553699 arg++;
554− cap.src_end = strfrmt+strlen(strfrmt)+1;
555− cap.level = 0;
556− strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
557− if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
558− strfrmt-initf > MAX_FORMAT-2)
559− lua_error(L, "invalid format (width or precision too long)");
560− strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
561− form[strfrmt-initf+2] = 0;
700+ strfrmt = scanformat(L, strfrmt, form, &hasprecision);
562701 switch (*strfrmt++) {
563− case 'c': case 'd': case 'i':
564− sprintf(buff, form, luaL_check_int(L, arg));
702+ case 'c': case 'd': case 'i': {
703+ sprintf(buff, form, luaL_checkint(L, arg));
565704 break;
566− case 'o': case 'u': case 'x': case 'X':
567− sprintf(buff, form, (unsigned int)luaL_check_number(L, arg));
705+ }
706+ case 'o': case 'u': case 'x': case 'X': {
707+ sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg)));
568708 break;
569− case 'e': case 'E': case 'f': case 'g': case 'G':
570− sprintf(buff, form, luaL_check_number(L, arg));
709+ }
710+ case 'e': case 'E': case 'f':
711+ case 'g': case 'G': {
712+ sprintf(buff, form, luaL_checknumber(L, arg));
571713 break;
572− case 'q':
714+ }
715+ case 'q': {
573716 luaI_addquoted(L, &b, arg);
574− continue; /* skip the "addsize" at the end */
717+ continue; /* skip the `addsize' at the end */
718+ }
575719 case 's': {
576720 size_t l;
577− const char *s = luaL_check_lstr(L, arg, &l);
578− if (cap.capture[1].len == 0 && l >= 100) {
721+ const char *s = luaL_checklstring(L, arg, &l);
722+ if (!hasprecision && l >= 100) {
579723 /* no precision and string is too long to be formatted;
580724 keep original string */
581725 lua_pushvalue(L, arg);
582726 luaL_addvalue(&b);
583− continue; /* skip the "addsize" at the end */
727+ continue; /* skip the `addsize' at the end */
584728 }
585729 else {
586730 sprintf(buff, form, s);
587731 break;
588732 }
589733 }
590− default: /* also treat cases 'pnLlh' */
591− lua_error(L, "invalid option in `format'");
734+ default: { /* also treat cases `pnLlh' */
735+ return luaL_error(L, "invalid option to `format'");
736+ }
592737 }
593738 luaL_addlstring(&b, buff, strlen(buff));
594739 }
@@ -598,24 +743,28 @@ static int str_format (lua_State *L) { · 3 unmodified lines
598743 }
599744
600745
601−static const struct luaL_reg strlib[] = {
602−{"strlen", str_len},
603−{"strsub", str_sub},
604−{"strlower", str_lower},
605−{"strupper", str_upper},
606−{"strchar", str_char},
607−{"strrep", str_rep},
608−{"ascii", str_byte}, /* for compatibility with 3.0 and earlier */
609−{"strbyte", str_byte},
610−{"format", str_format},
611−{"strfind", str_find},
612−{"gsub", str_gsub}
746+static const luaL_reg strlib[] = {
747+ {"len", str_len},
748+ {"sub", str_sub},
749+ {"lower", str_lower},
750+ {"upper", str_upper},
751+ {"char", str_char},
752+ {"rep", str_rep},
753+ {"byte", str_byte},
754+ {"format", str_format},
755+ {"dump", str_dump},
756+ {"find", str_find},
757+ {"gfind", gfind},
758+ {"gsub", str_gsub},
759+ {NULL, NULL}
613760 };
614761
615762
616763 /*
617764 ** Open string library
618765 */
619−LUALIB_API void lua_strlibopen (lua_State *L) {
620− luaL_openl(L, strlib);
766+LUALIB_API int luaopen_string (lua_State *L) {
767+ luaL_openlib(L, LUA_STRLIBNAME, strlib, 0);
768+ return 1;
621769 }
770+
src/lib/ltablib.c+250−0
@@ -0,0 +1,250 @@
1+/*
2+** $Id: ltablib.c,v 1.21 2003/04/03 13:35:34 roberto Exp $
3+** Library for Table Manipulation
4+** See Copyright Notice in lua.h
5+*/
6+
7+
8+#include <stddef.h>
9+
10+#define ltablib_c
11+
12+#include "lua.h"
13+
14+#include "lauxlib.h"
15+#include "lualib.h"
16+
17+
18+#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
19+
20+
21+static int luaB_foreachi (lua_State *L) {
22+ int i;
23+ int n = aux_getn(L, 1);
24+ luaL_checktype(L, 2, LUA_TFUNCTION);
25+ for (i=1; i<=n; i++) {
26+ lua_pushvalue(L, 2); /* function */
27+ lua_pushnumber(L, (lua_Number)i); /* 1st argument */
28+ lua_rawgeti(L, 1, i); /* 2nd argument */
29+ lua_call(L, 2, 1);
30+ if (!lua_isnil(L, -1))
31+ return 1;
32+ lua_pop(L, 1); /* remove nil result */
33+ }
34+ return 0;
35+}
36+
37+
38+static int luaB_foreach (lua_State *L) {
39+ luaL_checktype(L, 1, LUA_TTABLE);
40+ luaL_checktype(L, 2, LUA_TFUNCTION);
41+ lua_pushnil(L); /* first key */
42+ for (;;) {
43+ if (lua_next(L, 1) == 0)
44+ return 0;
45+ lua_pushvalue(L, 2); /* function */
46+ lua_pushvalue(L, -3); /* key */
47+ lua_pushvalue(L, -3); /* value */
48+ lua_call(L, 2, 1);
49+ if (!lua_isnil(L, -1))
50+ return 1;
51+ lua_pop(L, 2); /* remove value and result */
52+ }
53+}
54+
55+
56+static int luaB_getn (lua_State *L) {
57+ lua_pushnumber(L, (lua_Number)aux_getn(L, 1));
58+ return 1;
59+}
60+
61+
62+static int luaB_setn (lua_State *L) {
63+ luaL_checktype(L, 1, LUA_TTABLE);
64+ luaL_setn(L, 1, luaL_checkint(L, 2));
65+ return 0;
66+}
67+
68+
69+static int luaB_tinsert (lua_State *L) {
70+ int v = lua_gettop(L); /* number of arguments */
71+ int n = aux_getn(L, 1) + 1;
72+ int pos; /* where to insert new element */
73+ if (v == 2) /* called with only 2 arguments */
74+ pos = n; /* insert new element at the end */
75+ else {
76+ pos = luaL_checkint(L, 2); /* 2nd argument is the position */
77+ if (pos > n) n = pos; /* `grow' array if necessary */
78+ v = 3; /* function may be called with more than 3 args */
79+ }
80+ luaL_setn(L, 1, n); /* new size */
81+ while (--n >= pos) { /* move up elements */
82+ lua_rawgeti(L, 1, n);
83+ lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
84+ }
85+ lua_pushvalue(L, v);
86+ lua_rawseti(L, 1, pos); /* t[pos] = v */
87+ return 0;
88+}
89+
90+
91+static int luaB_tremove (lua_State *L) {
92+ int n = aux_getn(L, 1);
93+ int pos = luaL_optint(L, 2, n);
94+ if (n <= 0) return 0; /* table is `empty' */
95+ luaL_setn(L, 1, n-1); /* t.n = n-1 */
96+ lua_rawgeti(L, 1, pos); /* result = t[pos] */
97+ for ( ;pos<n; pos++) {
98+ lua_rawgeti(L, 1, pos+1);
99+ lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
100+ }
101+ lua_pushnil(L);
102+ lua_rawseti(L, 1, n); /* t[n] = nil */
103+ return 1;
104+}
105+
106+
107+static int str_concat (lua_State *L) {
108+ luaL_Buffer b;
109+ size_t lsep;
110+ const char *sep = luaL_optlstring(L, 2, "", &lsep);
111+ int i = luaL_optint(L, 3, 1);
112+ int n = luaL_optint(L, 4, 0);
113+ luaL_checktype(L, 1, LUA_TTABLE);
114+ if (n == 0) n = luaL_getn(L, 1);
115+ luaL_buffinit(L, &b);
116+ for (; i <= n; i++) {
117+ lua_rawgeti(L, 1, i);
118+ luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");
119+ luaL_addvalue(&b);
120+ if (i != n)
121+ luaL_addlstring(&b, sep, lsep);
122+ }
123+ luaL_pushresult(&b);
124+ return 1;
125+}
126+
127+
128+
129+/*
130+** {======================================================
131+** Quicksort
132+** (based on `Algorithms in MODULA-3', Robert Sedgewick;
133+** Addison-Wesley, 1993.)
134+*/
135+
136+
137+static void set2 (lua_State *L, int i, int j) {
138+ lua_rawseti(L, 1, i);
139+ lua_rawseti(L, 1, j);
140+}
141+
142+static int sort_comp (lua_State *L, int a, int b) {
143+ if (!lua_isnil(L, 2)) { /* function? */
144+ int res;
145+ lua_pushvalue(L, 2);
146+ lua_pushvalue(L, a-1); /* -1 to compensate function */
147+ lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
148+ lua_call(L, 2, 1);
149+ res = lua_toboolean(L, -1);
150+ lua_pop(L, 1);
151+ return res;
152+ }
153+ else /* a < b? */
154+ return lua_lessthan(L, a, b);
155+}
156+
157+static void auxsort (lua_State *L, int l, int u) {
158+ while (l < u) { /* for tail recursion */
159+ int i, j;
160+ /* sort elements a[l], a[(l+u)/2] and a[u] */
161+ lua_rawgeti(L, 1, l);
162+ lua_rawgeti(L, 1, u);
163+ if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
164+ set2(L, l, u); /* swap a[l] - a[u] */
165+ else
166+ lua_pop(L, 2);
167+ if (u-l == 1) break; /* only 2 elements */
168+ i = (l+u)/2;
169+ lua_rawgeti(L, 1, i);
170+ lua_rawgeti(L, 1, l);
171+ if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
172+ set2(L, i, l);
173+ else {
174+ lua_pop(L, 1); /* remove a[l] */
175+ lua_rawgeti(L, 1, u);
176+ if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
177+ set2(L, i, u);
178+ else
179+ lua_pop(L, 2);
180+ }
181+ if (u-l == 2) break; /* only 3 elements */
182+ lua_rawgeti(L, 1, i); /* Pivot */
183+ lua_pushvalue(L, -1);
184+ lua_rawgeti(L, 1, u-1);
185+ set2(L, i, u-1);
186+ /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
187+ i = l; j = u-1;
188+ for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
189+ /* repeat ++i until a[i] >= P */
190+ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
191+ if (i>u) luaL_error(L, "invalid order function for sorting");
192+ lua_pop(L, 1); /* remove a[i] */
193+ }
194+ /* repeat --j until a[j] <= P */
195+ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
196+ if (j<l) luaL_error(L, "invalid order function for sorting");
197+ lua_pop(L, 1); /* remove a[j] */
198+ }
199+ if (j<i) {
200+ lua_pop(L, 3); /* pop pivot, a[i], a[j] */
201+ break;
202+ }
203+ set2(L, i, j);
204+ }
205+ lua_rawgeti(L, 1, u-1);
206+ lua_rawgeti(L, 1, i);
207+ set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
208+ /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
209+ /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
210+ if (i-l < u-i) {
211+ j=l; i=i-1; l=i+2;
212+ }
213+ else {
214+ j=i+1; i=u; u=j-2;
215+ }
216+ auxsort(L, j, i); /* call recursively the smaller one */
217+ } /* repeat the routine for the larger one */
218+}
219+
220+static int luaB_sort (lua_State *L) {
221+ int n = aux_getn(L, 1);
222+ luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
223+ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
224+ luaL_checktype(L, 2, LUA_TFUNCTION);
225+ lua_settop(L, 2); /* make sure there is two arguments */
226+ auxsort(L, 1, n);
227+ return 0;
228+}
229+
230+/* }====================================================== */
231+
232+
233+static const luaL_reg tab_funcs[] = {
234+ {"concat", str_concat},
235+ {"foreach", luaB_foreach},
236+ {"foreachi", luaB_foreachi},
237+ {"getn", luaB_getn},
238+ {"setn", luaB_setn},
239+ {"sort", luaB_sort},
240+ {"insert", luaB_tinsert},
241+ {"remove", luaB_tremove},
242+ {NULL, NULL}
243+};
244+
245+
246+LUALIB_API int luaopen_table (lua_State *L) {
247+ luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
248+ return 1;
249+}
250+
src/llex.c+201−164
@@ -1,24 +1,23 @@
11 /*
2−** $Id: llex.c,v 1.72 2000/10/20 16:39:03 roberto Exp $
2+** $Id: llex.c,v 1.119 2003/03/24 12:39:34 roberto Exp $
33 ** Lexical Analyzer
44 ** See Copyright Notice in lua.h
55 */
66
77
88 #include <ctype.h>
9−#include <stdio.h>
109 #include <string.h>
1110
11+#define llex_c
12+
1213 #include "lua.h"
1314
15+#include "ldo.h"
1416 #include "llex.h"
15−#include "lmem.h"
1617 #include "lobject.h"
1718 #include "lparser.h"
1819 #include "lstate.h"
1920 #include "lstring.h"
20−#include "ltable.h"
21−#include "luadebug.h"
2221 #include "lzio.h"
2322
2423
@@ -29,16 +28,22 @@ · 4 unmodified lines
2928
3029 /* ORDER RESERVED */
3130 static const char *const token2string [] = {
32− "and", "break", "do", "else", "elseif", "end", "for",
33− "function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
34− "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", "<eof>"};
31+ "and", "break", "do", "else", "elseif",
32+ "end", "false", "for", "function", "if",
33+ "in", "local", "nil", "not", "or", "repeat",
34+ "return", "then", "true", "until", "while", "*name",
35+ "..", "...", "==", ">=", "<=", "~=",
36+ "*number", "*string", "<eof>"
37+};
3538
3639
3740 void luaX_init (lua_State *L) {
3841 int i;
3942 for (i=0; i<NUM_RESERVED; i++) {
4043 TString *ts = luaS_new(L, token2string[i]);
41− ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */
44+ luaS_fix(ts); /* reserved words are never collected */
45+ lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN);
46+ ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */
4247 }
4348 }
4449
@@ -48,50 +53,64 @@ void luaX_init (lua_State *L) { · 3 unmodified lines
4853
4954 void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
5055 if (val > limit) {
51− char buff[100];
52− sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
53− luaX_error(ls, buff, ls->t.token);
56+ msg = luaO_pushfstring(ls->L, "too many %s (limit=%d)", msg, limit);
57+ luaX_syntaxerror(ls, msg);
5458 }
5559 }
5660
5761
58−void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
62+void luaX_errorline (LexState *ls, const char *s, const char *token, int line) {
63+ lua_State *L = ls->L;
5964 char buff[MAXSRC];
60− luaO_chunkid(buff, ls->source->str, sizeof(buff));
61− luaO_verror(ls->L, "%.99s;\n last token read: `%.30s' at line %d in %.80s",
62− s, token, ls->linenumber, buff);
65+ luaO_chunkid(buff, getstr(ls->source), MAXSRC);
66+ luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token);
67+ luaD_throw(L, LUA_ERRSYNTAX);
6368 }
6469
6570
66−void luaX_error (LexState *ls, const char *s, int token) {
67− char buff[TOKEN_LEN];
68− luaX_token2str(token, buff);
69− if (buff[0] == '\0')
70− luaX_syntaxerror(ls, s, ls->L->Mbuffer);
71− else
72− luaX_syntaxerror(ls, s, buff);
71+static void luaX_error (LexState *ls, const char *s, const char *token) {
72+ luaX_errorline(ls, s, token, ls->linenumber);
73+}
74+
75+
76+void luaX_syntaxerror (LexState *ls, const char *msg) {
77+ const char *lasttoken;
78+ switch (ls->t.token) {
79+ case TK_NAME:
80+ lasttoken = getstr(ls->t.seminfo.ts);
81+ break;
82+ case TK_STRING:
83+ case TK_NUMBER:
84+ lasttoken = luaZ_buffer(ls->buff);
85+ break;
86+ default:
87+ lasttoken = luaX_token2str(ls, ls->t.token);
88+ break;
89+ }
90+ luaX_error(ls, msg, lasttoken);
7391 }
7492
7593
76−void luaX_token2str (int token, char *s) {
77− if (token < 256) {
78− s[0] = (char)token;
79− s[1] = '\0';
94+const char *luaX_token2str (LexState *ls, int token) {
95+ if (token < FIRST_RESERVED) {
96+ lua_assert(token == (unsigned char)token);
97+ return luaO_pushfstring(ls->L, "%c", token);
8098 }
8199 else
82− strcpy(s, token2string[token-FIRST_RESERVED]);
100+ return token2string[token-FIRST_RESERVED];
83101 }
84102
85103
86−static void luaX_invalidchar (LexState *ls, int c) {
87− char buff[8];
88− sprintf(buff, "0x%02X", c);
89− luaX_syntaxerror(ls, "invalid control char", buff);
104+static void luaX_lexerror (LexState *ls, const char *s, int token) {
105+ if (token == TK_EOS)
106+ luaX_error(ls, s, luaX_token2str(ls, token));
107+ else
108+ luaX_error(ls, s, luaZ_buffer(ls->buff));
90109 }
91110
92111
93112 static void inclinenumber (LexState *LS) {
94− next(LS); /* skip '\n' */
113+ next(LS); /* skip `\n' */
95114 ++LS->linenumber;
96115 luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
97116 }
@@ -122,159 +141,173 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { · 24 unmodified lines
122141 */
123142
124143
125−/* use Mbuffer to store names, literal strings and numbers */
144+/* use buffer to store names, literal strings and numbers */
145+
146+/* extra space to allocate when growing buffer */
147+#define EXTRABUFF 32
148+
149+/* maximum number of chars that can be read without checking buffer size */
150+#define MAXNOCHECK 5
126151
127−#define EXTRABUFF 128
128−#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \
129− luaO_openspace(L, (len)+(n)+EXTRABUFF)
152+#define checkbuffer(LS, len) \
153+ if (((len)+MAXNOCHECK)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \
154+ luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF)
130155
131−#define save(L, c, l) (L->Mbuffer[l++] = (char)c)
132−#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS))
156+#define save(LS, c, l) \
157+ (luaZ_buffer((LS)->buff)[l++] = cast(char, c))
158+#define save_and_next(LS, l) (save(LS, LS->current, l), next(LS))
133159
134160
135−static const char *readname (LexState *LS) {
136− lua_State *L = LS->L;
161+static size_t readname (LexState *LS) {
137162 size_t l = 0;
138− checkbuffer(L, 10, l);
163+ checkbuffer(LS, l);
139164 do {
140− checkbuffer(L, 10, l);
141− save_and_next(L, LS, l);
165+ checkbuffer(LS, l);
166+ save_and_next(LS, l);
142167 } while (isalnum(LS->current) || LS->current == '_');
143− save(L, '\0', l);
144− return L->Mbuffer;
168+ save(LS, '\0', l);
169+ return l-1;
145170 }
146171
147172
148173 /* LUA_NUMBER */
149−static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
150− lua_State *L = LS->L;
174+static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) {
151175 size_t l = 0;
152− checkbuffer(L, 10, l);
153− if (comma) save(L, '.', l);
176+ checkbuffer(LS, l);
177+ if (comma) save(LS, '.', l);
154178 while (isdigit(LS->current)) {
155− checkbuffer(L, 10, l);
156− save_and_next(L, LS, l);
179+ checkbuffer(LS, l);
180+ save_and_next(LS, l);
157181 }
158182 if (LS->current == '.') {
159− save_and_next(L, LS, l);
183+ save_and_next(LS, l);
160184 if (LS->current == '.') {
161− save_and_next(L, LS, l);
162− save(L, '\0', l);
163− luaX_error(LS, "ambiguous syntax"
164− " (decimal point x string concatenation)", TK_NUMBER);
185+ save_and_next(LS, l);
186+ save(LS, '\0', l);
187+ luaX_lexerror(LS,
188+ "ambiguous syntax (decimal point x string concatenation)",
189+ TK_NUMBER);
165190 }
166191 }
167192 while (isdigit(LS->current)) {
168− checkbuffer(L, 10, l);
169− save_and_next(L, LS, l);
193+ checkbuffer(LS, l);
194+ save_and_next(LS, l);
170195 }
171196 if (LS->current == 'e' || LS->current == 'E') {
172− save_and_next(L, LS, l); /* read 'E' */
197+ save_and_next(LS, l); /* read `E' */
173198 if (LS->current == '+' || LS->current == '-')
174− save_and_next(L, LS, l); /* optional exponent sign */
199+ save_and_next(LS, l); /* optional exponent sign */
175200 while (isdigit(LS->current)) {
176− checkbuffer(L, 10, l);
177− save_and_next(L, LS, l);
201+ checkbuffer(LS, l);
202+ save_and_next(LS, l);
178203 }
179204 }
180− save(L, '\0', l);
181− if (!luaO_str2d(L->Mbuffer, &seminfo->r))
182− luaX_error(LS, "malformed number", TK_NUMBER);
205+ save(LS, '\0', l);
206+ if (!luaO_str2d(luaZ_buffer(LS->buff), &seminfo->r))
207+ luaX_lexerror(LS, "malformed number", TK_NUMBER);
183208 }
184209
185210
186211 static void read_long_string (LexState *LS, SemInfo *seminfo) {
187− lua_State *L = LS->L;
188212 int cont = 0;
189213 size_t l = 0;
190− checkbuffer(L, 10, l);
191− save(L, '[', l); /* save first '[' */
192− save_and_next(L, LS, l); /* pass the second '[' */
214+ checkbuffer(LS, l);
215+ save(LS, '[', l); /* save first `[' */
216+ save_and_next(LS, l); /* pass the second `[' */
217+ if (LS->current == '\n') /* string starts with a newline? */
218+ inclinenumber(LS); /* skip it */
193219 for (;;) {
194− checkbuffer(L, 10, l);
220+ checkbuffer(LS, l);
195221 switch (LS->current) {
196222 case EOZ:
197− save(L, '\0', l);
198− luaX_error(LS, "unfinished long string", TK_STRING);
223+ save(LS, '\0', l);
224+ luaX_lexerror(LS, (seminfo) ? "unfinished long string" :
225+ "unfinished long comment", TK_EOS);
199226 break; /* to avoid warnings */
200227 case '[':
201− save_and_next(L, LS, l);
228+ save_and_next(LS, l);
202229 if (LS->current == '[') {
203230 cont++;
204− save_and_next(L, LS, l);
231+ save_and_next(LS, l);
205232 }
206233 continue;
207234 case ']':
208− save_and_next(L, LS, l);
235+ save_and_next(LS, l);
209236 if (LS->current == ']') {
210237 if (cont == 0) goto endloop;
211238 cont--;
212− save_and_next(L, LS, l);
239+ save_and_next(LS, l);
213240 }
214241 continue;
215242 case '\n':
216− save(L, '\n', l);
243+ save(LS, '\n', l);
217244 inclinenumber(LS);
245+ if (!seminfo) l = 0; /* reset buffer to avoid wasting space */
218246 continue;
219247 default:
220− save_and_next(L, LS, l);
248+ save_and_next(LS, l);
221249 }
222250 } endloop:
223− save_and_next(L, LS, l); /* skip the second ']' */
224− save(L, '\0', l);
225− seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
251+ save_and_next(LS, l); /* skip the second `]' */
252+ save(LS, '\0', l);
253+ if (seminfo)
254+ seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5);
226255 }
227256
228257
229258 static void read_string (LexState *LS, int del, SemInfo *seminfo) {
230− lua_State *L = LS->L;
231259 size_t l = 0;
232− checkbuffer(L, 10, l);
233− save_and_next(L, LS, l);
260+ checkbuffer(LS, l);
261+ save_and_next(LS, l);
234262 while (LS->current != del) {
235− checkbuffer(L, 10, l);
263+ checkbuffer(LS, l);
236264 switch (LS->current) {
237− case EOZ: case '\n':
238− save(L, '\0', l);
239− luaX_error(LS, "unfinished string", TK_STRING);
265+ case EOZ:
266+ save(LS, '\0', l);
267+ luaX_lexerror(LS, "unfinished string", TK_EOS);
268+ break; /* to avoid warnings */
269+ case '\n':
270+ save(LS, '\0', l);
271+ luaX_lexerror(LS, "unfinished string", TK_STRING);
240272 break; /* to avoid warnings */
241273 case '\\':
242− next(LS); /* do not save the '\' */
274+ next(LS); /* do not save the `\' */
243275 switch (LS->current) {
244− case 'a': save(L, '\a', l); next(LS); break;
245− case 'b': save(L, '\b', l); next(LS); break;
246− case 'f': save(L, '\f', l); next(LS); break;
247− case 'n': save(L, '\n', l); next(LS); break;
248− case 'r': save(L, '\r', l); next(LS); break;
249− case 't': save(L, '\t', l); next(LS); break;
250− case 'v': save(L, '\v', l); next(LS); break;
251− case '\n': save(L, '\n', l); inclinenumber(LS); break;
252− case '0': case '1': case '2': case '3': case '4':
253− case '5': case '6': case '7': case '8': case '9': {
254− int c = 0;
255− int i = 0;
256− do {
257− c = 10*c + (LS->current-'0');
258− next(LS);
259− } while (++i<3 && isdigit(LS->current));
260− if (c != (unsigned char)c) {
261− save(L, '\0', l);
262− luaX_error(LS, "escape sequence too large", TK_STRING);
276+ case 'a': save(LS, '\a', l); next(LS); break;
277+ case 'b': save(LS, '\b', l); next(LS); break;
278+ case 'f': save(LS, '\f', l); next(LS); break;
279+ case 'n': save(LS, '\n', l); next(LS); break;
280+ case 'r': save(LS, '\r', l); next(LS); break;
281+ case 't': save(LS, '\t', l); next(LS); break;
282+ case 'v': save(LS, '\v', l); next(LS); break;
283+ case '\n': save(LS, '\n', l); inclinenumber(LS); break;
284+ case EOZ: break; /* will raise an error next loop */
285+ default: {
286+ if (!isdigit(LS->current))
287+ save_and_next(LS, l); /* handles \\, \", \', and \? */
288+ else { /* \xxx */
289+ int c = 0;
290+ int i = 0;
291+ do {
292+ c = 10*c + (LS->current-'0');
293+ next(LS);
294+ } while (++i<3 && isdigit(LS->current));
295+ if (c > UCHAR_MAX) {
296+ save(LS, '\0', l);
297+ luaX_lexerror(LS, "escape sequence too large", TK_STRING);
298+ }
299+ save(LS, c, l);
263300 }
264− save(L, c, l);
265− break;
266301 }
267− default: /* handles \\, \", \', and \? */
268− save_and_next(L, LS, l);
269302 }
270303 break;
271304 default:
272− save_and_next(L, LS, l);
305+ save_and_next(LS, l);
273306 }
274307 }
275− save_and_next(L, LS, l); /* skip delimiter */
276− save(L, '\0', l);
277− seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
308+ save_and_next(LS, l); /* skip delimiter */
309+ save(LS, '\0', l);
310+ seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3);
278311 }
279312
280313
@@ -282,58 +315,56 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { · 1 unmodified line
282315 for (;;) {
283316 switch (LS->current) {
284317
285− case ' ': case '\t': case '\r': /* `\r' to avoid problems with DOS */
286− next(LS);
287− continue;
288−
289− case '\n':
318+ case '\n': {
290319 inclinenumber(LS);
291320 continue;
292−
293− case '$':
294− luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$');
295− break;
296−
297− case '-':
321+ }
322+ case '-': {
298323 next(LS);
299324 if (LS->current != '-') return '-';
300− do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
325+ /* else is a comment */
326+ next(LS);
327+ if (LS->current == '[' && (next(LS), LS->current == '['))
328+ read_long_string(LS, NULL); /* long comment */
329+ else /* short comment */
330+ while (LS->current != '\n' && LS->current != EOZ)
331+ next(LS);
301332 continue;
302−
303− case '[':
333+ }
334+ case '[': {
304335 next(LS);
305336 if (LS->current != '[') return '[';
306337 else {
307338 read_long_string(LS, seminfo);
308339 return TK_STRING;
309340 }
310−
311− case '=':
341+ }
342+ case '=': {
312343 next(LS);
313344 if (LS->current != '=') return '=';
314345 else { next(LS); return TK_EQ; }
315−
316− case '<':
346+ }
347+ case '<': {
317348 next(LS);
318349 if (LS->current != '=') return '<';
319350 else { next(LS); return TK_LE; }
320−
321− case '>':
351+ }
352+ case '>': {
322353 next(LS);
323354 if (LS->current != '=') return '>';
324355 else { next(LS); return TK_GE; }
325−
326− case '~':
356+ }
357+ case '~': {
327358 next(LS);
328359 if (LS->current != '=') return '~';
329360 else { next(LS); return TK_NE; }
330−
361+ }
331362 case '"':
332− case '\'':
363+ case '\'': {
333364 read_string(LS, LS->current, seminfo);
334365 return TK_STRING;
335−
336− case '.':
366+ }
367+ case '.': {
337368 next(LS);
338369 if (LS->current == '.') {
339370 next(LS);
@@ -345,36 +376,42 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { · 5 unmodified lines
345376 }
346377 else if (!isdigit(LS->current)) return '.';
347378 else {
348− read_number(LS, 1, seminfo);
379+ read_numeral(LS, 1, seminfo);
349380 return TK_NUMBER;
350381 }
351−
352− case '0': case '1': case '2': case '3': case '4':
353− case '5': case '6': case '7': case '8': case '9':
354− read_number(LS, 0, seminfo);
355− return TK_NUMBER;
356−
357− case EOZ:
382+ }
383+ case EOZ: {
358384 return TK_EOS;
359−
360− case '_': goto tname;
361−
362− default:
363− if (!isalpha(LS->current)) {
364− int c = LS->current;
365− if (iscntrl(c))
366− luaX_invalidchar(LS, c);
385+ }
386+ default: {
387+ if (isspace(LS->current)) {
367388 next(LS);
368− return c;
389+ continue;
390+ }
391+ else if (isdigit(LS->current)) {
392+ read_numeral(LS, 0, seminfo);
393+ return TK_NUMBER;
369394 }
370− tname: { /* identifier or reserved word */
371− TString *ts = luaS_new(LS->L, readname(LS));
372− if (ts->marked >= RESERVEDMARK) /* reserved word? */
373− return ts->marked-RESERVEDMARK+FIRST_RESERVED;
395+ else if (isalpha(LS->current) || LS->current == '_') {
396+ /* identifier or reserved word */
397+ size_t l = readname(LS);
398+ TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l);
399+ if (ts->tsv.reserved > 0) /* reserved word? */
400+ return ts->tsv.reserved - 1 + FIRST_RESERVED;
374401 seminfo->ts = ts;
375402 return TK_NAME;
376403 }
404+ else {
405+ int c = LS->current;
406+ if (iscntrl(c))
407+ luaX_error(LS, "invalid control char",
408+ luaO_pushfstring(LS->L, "char(%d)", c));
409+ next(LS);
410+ return c; /* single-char tokens (+ - / ...) */
411+ }
412+ }
377413 }
378414 }
379415 }
380416
417+#undef next
src/llex.h+17−14
@@ -1,5 +1,5 @@
11 /*
2−** $Id: llex.h,v 1.31 2000/09/27 17:41:58 roberto Exp $
2+** $Id: llex.h,v 1.47 2003/02/28 17:19:47 roberto Exp $
33 ** Lexical Analyzer
44 ** See Copyright Notice in lua.h
55 */
@@ -13,8 +13,8 @@ · 7 unmodified lines
1313
1414 #define FIRST_RESERVED 257
1515
16−/* maximum length of a reserved word (+1 for final 0) */
17−#define TOKEN_LEN 15
16+/* maximum length of a reserved word */
17+#define TOKEN_LEN (sizeof("function")/sizeof(char))
1818
1919
2020 /*
@@ -24,19 +24,20 @@ · 3 unmodified lines
2424 enum RESERVED {
2525 /* terminal symbols denoted by reserved words */
2626 TK_AND = FIRST_RESERVED, TK_BREAK,
27− TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_IF, TK_LOCAL,
28− TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_UNTIL, TK_WHILE,
27+ 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,
29+ TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
2930 /* other terminal symbols */
3031 TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
3132 TK_STRING, TK_EOS
3233 };
3334
3435 /* number of reserved words */
35−#define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1))
36+#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
3637
3738
3839 typedef union {
39− Number r;
40+ lua_Number r;
4041 TString *ts;
4142 } SemInfo; /* semantics information */
4243
@@ -48,15 +49,17 @@ typedef struct Token { · 5 unmodified lines
4849
4950
5051 typedef struct LexState {
51− int current; /* current character */
52+ int current; /* current character (charint) */
53+ int linenumber; /* input line counter */
54+ int lastline; /* line of last token `consumed' */
5255 Token t; /* current token */
5356 Token lookahead; /* look ahead token */
5457 struct FuncState *fs; /* `FuncState' is private to the parser */
5558 struct lua_State *L;
56− struct zio *z; /* input stream */
57− int linenumber; /* input line counter */
58− int lastline; /* line of last token `consumed' */
59+ ZIO *z; /* input stream */
60+ Mbuffer *buff; /* buffer for tokens */
5961 TString *source; /* current source name */
62+ int nestlevel; /* level of nested non-terminals */
6063 } LexState;
6164
6265
@@ -64,9 +67,9 @@ void luaX_init (lua_State *L); · 1 unmodified line
6467 void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
6568 int luaX_lex (LexState *LS, SemInfo *seminfo);
6669 void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
67−void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
68−void luaX_error (LexState *ls, const char *s, int token);
69−void luaX_token2str (int token, char *s);
70+void luaX_syntaxerror (LexState *ls, const char *s);
71+void luaX_errorline (LexState *ls, const char *s, const char *token, int line);
72+const char *luaX_token2str (LexState *ls, int token);
7073
7174
7275 #endif
src/llimits.h+83−102
@@ -1,6 +1,6 @@
11 /*
2−** $Id: llimits.h,v 1.19 2000/10/26 12:47:05 roberto Exp $
3−** Limits, basic types, and some other "installation-dependent" definitions
2+** $Id: llimits.h,v 1.52 2003/02/20 19:33:23 roberto Exp $
3+** Limits, basic types, and some other `installation-dependent' definitions
44 ** See Copyright Notice in lua.h
55 */
66
@@ -12,6 +12,8 @@ · 5 unmodified lines
1212 #include <stddef.h>
1313
1414
15+#include "lua.h"
16+
1517
1618 /*
1719 ** try to find number of bits in an integer
@@ -32,25 +34,29 @@ · 14 unmodified lines
3234
3335
3436 /*
35−** Define the type `number' of Lua
36−** GREP LUA_NUMBER to change that
37+** the following types define integer types for values that may not
38+** fit in a `small int' (16 bits), but may waste space in a
39+** `large long' (64 bits). The current definitions should work in
40+** any machine, but may not be optimal.
3741 */
38−#ifndef LUA_NUM_TYPE
39−#define LUA_NUM_TYPE double
40−#endif
4142
42−typedef LUA_NUM_TYPE Number;
43+/* an unsigned integer to hold hash values */
44+typedef unsigned int lu_hash;
45+/* its signed equivalent */
46+typedef int ls_hash;
4347
44−/* function to convert a Number to a string */
45−#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
46−#define lua_number2str(s,n) sprintf((s), NUMBER_FMT, (n))
48+/* an unsigned integer big enough to count the total memory used by Lua; */
49+/* it should be at least as large as size_t */
50+typedef unsigned long lu_mem;
4751
48−/* function to convert a string to a Number */
49−#define lua_str2number(s,p) strtod((s), (p))
52+#define MAX_LUMEM ULONG_MAX
5053
5154
55+/* an integer big enough to count the number of strings in use */
56+typedef long ls_nstr;
5257
53−typedef unsigned long lint32; /* unsigned int with at least 32 bits */
58+/* chars used as small naturals (so that `char' is reserved for characters) */
59+typedef unsigned char lu_byte;
5460
5561
5662 #define MAX_SIZET ((size_t)(~(size_t)0)-2)
@@ -59,117 +65,93 @@ typedef unsigned long lint32; /* unsigned int with at least 32 bits */ · 2 unmodified lines
5965 #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
6066
6167 /*
62−** conversion of pointer to int (for hashing only)
63−** (the shift removes bits that are usually 0 because of alignment)
68+** conversion of pointer to integer
69+** this is for hashing only; there is no problem if the integer
70+** cannot hold the whole pointer value
6471 */
65−#define IntPoint(p) (((unsigned long)(p)) >> 3)
72+#define IntPoint(p) ((lu_hash)(p))
73+
6674
6775
76+/* type to ensure maximum alignment */
77+#ifndef LUSER_ALIGNMENT_T
78+typedef union { double u; void *s; long l; } L_Umaxalign;
79+#else
80+typedef LUSER_ALIGNMENT_T L_Umaxalign;
81+#endif
6882
69−#define MINPOWER2 4 /* minimum size for "growing" vectors */
7083
84+/* result of `usual argument conversion' over lua_Number */
85+#ifndef LUA_UACNUMBER
86+typedef double l_uacNumber;
87+#else
88+typedef LUA_UACNUMBER l_uacNumber;
89+#endif
7190
7291
73−#ifndef DEFAULT_STACK_SIZE
74−#define DEFAULT_STACK_SIZE 1024
92+#ifndef lua_assert
93+#define lua_assert(c) /* empty */
7594 #endif
7695
7796
97+#ifndef check_exp
98+#define check_exp(c,e) (e)
99+#endif
78100
79−/* type to ensure maximum alignment */
80−union L_Umaxalign { double d; char *s; long l; };
101+
102+#ifndef UNUSED
103+#define UNUSED(x) ((void)(x)) /* to avoid warnings */
104+#endif
105+
106+
107+#ifndef cast
108+#define cast(t, exp) ((t)(exp))
109+#endif
81110
82111
83112
84113 /*
85114 ** type for virtual-machine instructions
86115 ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
87−** For a very small machine, you may change that to 2 bytes (and adjust
88−** the following limits accordingly)
89116 */
90117 typedef unsigned long Instruction;
91118
92119
93−/*
94−** size and position of opcode arguments.
95−** For an instruction with 2 bytes, size is 16, and size_b can be 5
96−** (accordingly, size_u will be 10, and size_a will be 5)
97−*/
98−#define SIZE_INSTRUCTION 32
99−#define SIZE_B 9
100−
101−#define SIZE_OP 6
102−#define SIZE_U (SIZE_INSTRUCTION-SIZE_OP)
103−#define POS_U SIZE_OP
104−#define POS_B SIZE_OP
105−#define SIZE_A (SIZE_INSTRUCTION-(SIZE_OP+SIZE_B))
106−#define POS_A (SIZE_OP+SIZE_B)
120+/* maximum depth for calls (unsigned short) */
121+#ifndef LUA_MAXCALLS
122+#define LUA_MAXCALLS 4096
123+#endif
107124
108125
109126 /*
110−** limits for opcode arguments.
111−** we use (signed) int to manipulate most arguments,
112−** so they must fit in BITS_INT-1 bits (-1 for sign)
127+** maximum depth for C calls (unsigned short): Not too big, or may
128+** overflow the C stack...
113129 */
114−#if SIZE_U < BITS_INT-1
115−#define MAXARG_U ((1<<SIZE_U)-1)
116−#define MAXARG_S (MAXARG_U>>1) /* `S' is signed */
117−#else
118−#define MAXARG_U MAX_INT
119−#define MAXARG_S MAX_INT
120−#endif
121130
122−#if SIZE_A < BITS_INT-1
123−#define MAXARG_A ((1<<SIZE_A)-1)
124−#else
125−#define MAXARG_A MAX_INT
131+#ifndef LUA_MAXCCALLS
132+#define LUA_MAXCCALLS 200
126133 #endif
127134
128−#if SIZE_B < BITS_INT-1
129−#define MAXARG_B ((1<<SIZE_B)-1)
130−#else
131−#define MAXARG_B MAX_INT
135+
136+/* maximum size for the C stack */
137+#ifndef LUA_MAXCSTACK
138+#define LUA_MAXCSTACK 2048
132139 #endif
133140
134141
135−/* maximum stack size in a function */
136−#ifndef MAXSTACK
142+/* maximum stack for a Lua function */
137143 #define MAXSTACK 250
138−#endif
139−
140−#if MAXSTACK > MAXARG_B
141−#undef MAXSTACK
142−#define MAXSTACK MAXARG_B
143−#endif
144144
145145
146−/* maximum number of local variables */
147−#ifndef MAXLOCALS
148−#define MAXLOCALS 200 /* arbitrary limit (<MAXSTACK) */
149−#endif
150−#if MAXLOCALS>=MAXSTACK
151−#undef MAXLOCALS
152−#define MAXLOCALS (MAXSTACK-1)
146+/* maximum number of variables declared in a function */
147+#ifndef MAXVARS
148+#define MAXVARS 200 /* arbitrary limit (<MAXSTACK) */
153149 #endif
154150
155151
156−/* maximum number of upvalues */
152+/* maximum number of upvalues per function */
157153 #ifndef MAXUPVALUES
158−#define MAXUPVALUES 32 /* arbitrary limit (<=MAXARG_B) */
159−#endif
160−#if MAXUPVALUES>MAXARG_B
161−#undef MAXUPVALUES
162−#define MAXUPVALUES MAXARG_B
163−#endif
164−
165−
166−/* maximum number of variables in the left side of an assignment */
167−#ifndef MAXVARSLH
168−#define MAXVARSLH 100 /* arbitrary limit (<MULT_RET) */
169−#endif
170−#if MAXVARSLH>=MULT_RET
171−#undef MAXVARSLH
172−#define MAXVARSLH (MULT_RET-1)
154+#define MAXUPVALUES 32
173155 #endif
174156
175157
@@ -177,27 +159,26 @@ typedef unsigned long Instruction; · 1 unmodified line
177159 #ifndef MAXPARAMS
178160 #define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
179161 #endif
180−#if MAXPARAMS>=MAXLOCALS
181−#undef MAXPARAMS
182−#define MAXPARAMS (MAXLOCALS-1)
183−#endif
184162
185163
186−/* number of list items to accumulate before a SETLIST instruction */
187−#define LFIELDS_PER_FLUSH 64
188−#if LFIELDS_PER_FLUSH>(MAXSTACK/4)
189−#undef LFIELDS_PER_FLUSH
190−#define LFIELDS_PER_FLUSH (MAXSTACK/4)
164+/* minimum size for the string table (must be power of 2) */
165+#ifndef MINSTRTABSIZE
166+#define MINSTRTABSIZE 32
191167 #endif
192168
193−/* number of record items to accumulate before a SETMAP instruction */
194−/* (each item counts 2 elements on the stack: an index and a value) */
195−#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2)
169+
170+/* minimum size for string buffer */
171+#ifndef LUA_MINBUFFER
172+#define LUA_MINBUFFER 32
173+#endif
196174
197175
198−/* maximum lookback to find a real constant (for code generation) */
199−#ifndef LOOKBACKNUMS
200−#define LOOKBACKNUMS 20 /* arbitrary constant */
176+/*
177+** maximum number of syntactical nested non-terminals: Not too big,
178+** or may overflow the C stack...
179+*/
180+#ifndef LUA_MAXPARSERLEVEL
181+#define LUA_MAXPARSERLEVEL 200
201182 #endif
202183
203184
src/lmem.c+52−111
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lmem.c,v 1.39 2000/10/30 16:29:59 roberto Exp $
2+** $Id: lmem.c,v 1.61 2002/12/04 17:38:31 roberto Exp $
33 ** Interface to Memory Manager
44 ** See Copyright Notice in lua.h
55 */
@@ -7,8 +7,11 @@ · 1 unmodified line
77
88 #include <stdlib.h>
99
10+#define lmem_c
11+
1012 #include "lua.h"
1113
14+#include "ldebug.h"
1215 #include "ldo.h"
1316 #include "lmem.h"
1417 #include "lobject.h"
@@ -16,135 +19,73 @@ · 1 unmodified line
1619
1720
1821
19−
20−#ifdef LUA_DEBUG
2122 /*
22−** {======================================================================
23−** Controlled version for realloc.
24−** =======================================================================
23+** definition for realloc function. It must assure that l_realloc(NULL,
24+** 0, x) allocates a new block (ANSI C assures that). (`os' is the old
25+** block size; some allocators may use that.)
2526 */
26−
27−
28−#include <assert.h>
29−#include <limits.h>
30−#include <string.h>
31−
32−#define realloc(b, s) debug_realloc(b, s)
33−#define malloc(b) debug_realloc(NULL, b)
34−#define free(b) debug_realloc(b, 0)
35−
36−
37−/* ensures maximum alignment for HEADER */
38−#define HEADER (sizeof(union L_Umaxalign))
39−
40−#define MARKSIZE 16
41−#define MARK 0x55 /* 01010101 (a nice pattern) */
42−
43−
44−#define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
45−
46−unsigned long memdebug_numblocks = 0;
47−unsigned long memdebug_total = 0;
48−unsigned long memdebug_maxmem = 0;
49−unsigned long memdebug_memlimit = LONG_MAX;
50−
51−
52−static void *checkblock (void *block) {
53− unsigned long *b = blocksize(block);
54− unsigned long size = *b;
55− int i;
56− for (i=0;i<MARKSIZE;i++)
57− assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */
58− memdebug_numblocks--;
59− memdebug_total -= size;
60− return b;
61−}
62−
63−
64−static void freeblock (void *block) {
65− if (block) {
66− size_t size = *blocksize(block);
67− block = checkblock(block);
68− memset(block, -1, size+HEADER+MARKSIZE); /* erase block */
69− (free)(block); /* free original block */
70− }
71−}
72−
73−
74−static void *debug_realloc (void *block, size_t size) {
75− if (size == 0) {
76− freeblock(block);
77− return NULL;
78− }
79− else if (memdebug_total+size > memdebug_memlimit)
80− return NULL; /* to test memory allocation errors */
81− else {
82− size_t realsize = HEADER+size+MARKSIZE;
83− char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
84− int i;
85− if (realsize < size) return NULL; /* overflow! */
86− if (newblock == NULL) return NULL;
87− if (block) {
88− size_t oldsize = *blocksize(block);
89− if (oldsize > size) oldsize = size;
90− memcpy(newblock+HEADER, block, oldsize);
91− freeblock(block); /* erase (and check) old copy */
92− }
93− memdebug_total += size;
94− if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total;
95− memdebug_numblocks++;
96− *(unsigned long *)newblock = size;
97− for (i=0;i<MARKSIZE;i++)
98− *(newblock+HEADER+size+i) = (char)(MARK+i);
99− return newblock+HEADER;
100− }
101−}
102−
103−
104−/* }====================================================================== */
27+#ifndef l_realloc
28+#define l_realloc(b,os,s) realloc(b,s)
10529 #endif
10630
107−
108−
10931 /*
110−** Real ISO (ANSI) systems do not need these tests;
111−** but some systems (Sun OS) are not that ISO...
32+** definition for free function. (`os' is the old block size; some
33+** allocators may use that.)
11234 */
113−#ifdef OLD_ANSI
114−#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
115−#define free(b) if (b) (free)(b)
35+#ifndef l_free
36+#define l_free(b,os) free(b)
11637 #endif
11738
11839
119−void *luaM_growaux (lua_State *L, void *block, size_t nelems,
120− int inc, size_t size, const char *errormsg, size_t limit) {
121− size_t newn = nelems+inc;
122− if (nelems >= limit-inc) lua_error(L, errormsg);
123− if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */
124− (nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */
125− return block; /* do not need to reallocate */
126− else /* it crossed a power-of-2 boundary; grow to next power */
127− return luaM_realloc(L, block, luaO_power2(newn)*size);
40+#define MINSIZEARRAY 4
41+
42+
43+void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
44+ int limit, const char *errormsg) {
45+ void *newblock;
46+ int newsize = (*size)*2;
47+ if (newsize < MINSIZEARRAY)
48+ newsize = MINSIZEARRAY; /* minimum size */
49+ else if (*size >= limit/2) { /* cannot double it? */
50+ if (*size < limit - MINSIZEARRAY) /* try something smaller... */
51+ newsize = limit; /* still have at least MINSIZEARRAY free places */
52+ else luaG_runerror(L, errormsg);
53+ }
54+ newblock = luaM_realloc(L, block,
55+ cast(lu_mem, *size)*cast(lu_mem, size_elems),
56+ cast(lu_mem, newsize)*cast(lu_mem, size_elems));
57+ *size = newsize; /* update only when everything else is OK */
58+ return newblock;
12859 }
12960
13061
13162 /*
13263 ** generic allocation routine.
13364 */
134−void *luaM_realloc (lua_State *L, void *block, lint32 size) {
65+void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
66+ lua_assert((oldsize == 0) == (block == NULL));
13567 if (size == 0) {
136− free(block); /* block may be NULL; that is OK for free */
137− return NULL;
68+ if (block != NULL) {
69+ l_free(block, oldsize);
70+ block = NULL;
71+ }
72+ else return NULL; /* avoid `nblocks' computations when oldsize==size==0 */
13873 }
13974 else if (size >= MAX_SIZET)
140− lua_error(L, "memory allocation error: block too big");
141− block = realloc(block, size);
142− if (block == NULL) {
143− if (L)
144− luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */
145− else return NULL; /* error before creating state! */
75+ luaG_runerror(L, "memory allocation error: block too big");
76+ else {
77+ block = l_realloc(block, oldsize, size);
78+ if (block == NULL) {
79+ if (L)
80+ luaD_throw(L, LUA_ERRMEM);
81+ else return NULL; /* error before creating state! */
82+ }
83+ }
84+ if (L) {
85+ lua_assert(G(L) != NULL && G(L)->nblocks > 0);
86+ G(L)->nblocks -= oldsize;
87+ G(L)->nblocks += size;
14688 }
14789 return block;
14890 }
14991
150−
src/lmem.h+21−19
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lmem.h,v 1.16 2000/10/30 16:29:59 roberto Exp $
2+** $Id: lmem.h,v 1.26 2002/05/01 20:40:42 roberto Exp $
33 ** Interface to Memory Manager
44 ** See Copyright Notice in lua.h
55 */
@@ -13,29 +13,31 @@ · 7 unmodified lines
1313 #include "llimits.h"
1414 #include "lua.h"
1515
16−void *luaM_realloc (lua_State *L, void *oldblock, lint32 size);
17−void *luaM_growaux (lua_State *L, void *block, size_t nelems,
18− int inc, size_t size, const char *errormsg,
19− size_t limit);
16+#define MEMERRMSG "not enough memory"
2017
21−#define luaM_free(L, b) luaM_realloc(L, (b), 0)
22−#define luaM_malloc(L, t) luaM_realloc(L, NULL, (t))
23−#define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t)))
24−#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(lint32)sizeof(t)))
2518
26−#define luaM_growvector(L, v,nelems,inc,t,e,l) \
27− ((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l))
19+void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size);
2820
29−#define luaM_reallocvector(L, v,n,t) \
30− ((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t)))
21+void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
22+ int limit, const char *errormsg);
3123
24+#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0)
25+#define luaM_freelem(L, b) luaM_realloc(L, (b), sizeof(*(b)), 0)
26+#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \
27+ cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0)
3228
33−#ifdef LUA_DEBUG
34−extern unsigned long memdebug_numblocks;
35−extern unsigned long memdebug_total;
36−extern unsigned long memdebug_maxmem;
37−extern unsigned long memdebug_memlimit;
38−#endif
29+#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t))
30+#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t)))
31+#define luaM_newvector(L, n,t) cast(t *, luaM_malloc(L, \
32+ cast(lu_mem, n)*cast(lu_mem, sizeof(t))))
33+
34+#define luaM_growvector(L,v,nelems,size,t,limit,e) \
35+ if (((nelems)+1) > (size)) \
36+ ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e)))
37+
38+#define luaM_reallocvector(L, v,oldn,n,t) \
39+ ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \
40+ cast(lu_mem, n)*cast(lu_mem, sizeof(t)))))
3941
4042
4143 #endif
src/lobject.c+125−55
@@ -1,92 +1,162 @@
11 /*
2−** $Id: lobject.c,v 1.55 2000/10/20 16:36:32 roberto Exp $
2+** $Id: lobject.c,v 1.97 2003/04/03 13:35:34 roberto Exp $
33 ** Some generic functions over Lua objects
44 ** See Copyright Notice in lua.h
55 */
66
77 #include <ctype.h>
88 #include <stdarg.h>
9−#include <stdio.h>
109 #include <stdlib.h>
1110 #include <string.h>
1211
12+#define lobject_c
13+
1314 #include "lua.h"
1415
16+#include "ldo.h"
1517 #include "lmem.h"
1618 #include "lobject.h"
1719 #include "lstate.h"
20+#include "lstring.h"
21+#include "lvm.h"
1822
1923
24+/* function to convert a string to a lua_Number */
25+#ifndef lua_str2number
26+#define lua_str2number(s,p) strtod((s), (p))
27+#endif
2028
21−const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
22−
23−
24−const char *const luaO_typenames[] = {
25− "userdata", "nil", "number", "string", "table", "function"
26−};
2729
30+const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
2831
2932
3033 /*
31−** returns smaller power of 2 larger than `n' (minimum is MINPOWER2)
34+** converts an integer to a "floating point byte", represented as
35+** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
3236 */
33−lint32 luaO_power2 (lint32 n) {
34− lint32 p = MINPOWER2;
35− while (p<=n) p<<=1;
36− return p;
37+int luaO_int2fb (unsigned int x) {
38+ int m = 0; /* mantissa */
39+ while (x >= (1<<3)) {
40+ x = (x+1) >> 1;
41+ m++;
42+ }
43+ return (m << 3) | cast(int, x);
3744 }
3845
3946
40−int luaO_equalObj (const TObject *t1, const TObject *t2) {
41− if (ttype(t1) != ttype(t2)) return 0;
42− switch (ttype(t1)) {
43− case LUA_TNUMBER:
44− return nvalue(t1) == nvalue(t2);
45− case LUA_TSTRING: case LUA_TUSERDATA:
46− return tsvalue(t1) == tsvalue(t2);
47− case LUA_TTABLE:
48− return hvalue(t1) == hvalue(t2);
49− case LUA_TFUNCTION:
50− return clvalue(t1) == clvalue(t2);
51− default:
52− LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type");
53− return 1; /* LUA_TNIL */
47+int luaO_log2 (unsigned int x) {
48+ static const lu_byte log_8[255] = {
49+ 0,
50+ 1,1,
51+ 2,2,2,2,
52+ 3,3,3,3,3,3,3,3,
53+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
54+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
55+ 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,
56+ 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,
57+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
58+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
61+ };
62+ if (x >= 0x00010000) {
63+ if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24;
64+ else return log_8[((x>>16) & 0xff) - 1]+16;
65+ }
66+ else {
67+ if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8;
68+ else if (x) return log_8[(x & 0xff) - 1];
69+ return -1; /* special `log' for 0 */
5470 }
5571 }
5672
5773
58−char *luaO_openspace (lua_State *L, size_t n) {
59− if (n > L->Mbuffsize) {
60− luaM_reallocvector(L, L->Mbuffer, n, char);
61− L->nblocks += (n - L->Mbuffsize)*sizeof(char);
62− L->Mbuffsize = n;
74+int luaO_rawequalObj (const TObject *t1, const TObject *t2) {
75+ if (ttype(t1) != ttype(t2)) return 0;
76+ else switch (ttype(t1)) {
77+ case LUA_TNIL:
78+ return 1;
79+ case LUA_TNUMBER:
80+ return nvalue(t1) == nvalue(t2);
81+ case LUA_TBOOLEAN:
82+ return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
83+ case LUA_TLIGHTUSERDATA:
84+ return pvalue(t1) == pvalue(t2);
85+ default:
86+ lua_assert(iscollectable(t1));
87+ return gcvalue(t1) == gcvalue(t2);
6388 }
64− return L->Mbuffer;
6589 }
6690
6791
68−int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */
92+int luaO_str2d (const char *s, lua_Number *result) {
6993 char *endptr;
70− Number res = lua_str2number(s, &endptr);
94+ lua_Number res = lua_str2number(s, &endptr);
7195 if (endptr == s) return 0; /* no conversion */
72− while (isspace((unsigned char)*endptr)) endptr++;
96+ while (isspace((unsigned char)(*endptr))) endptr++;
7397 if (*endptr != '\0') return 0; /* invalid trailing characters? */
7498 *result = res;
7599 return 1;
76100 }
77101
78102
79−/* maximum length of a string format for `luaO_verror' */
80−#define MAX_VERROR 280
81103
82−/* this function needs to handle only '%d' and '%.XXs' formats */
83−void luaO_verror (lua_State *L, const char *fmt, ...) {
104+static void pushstr (lua_State *L, const char *str) {
105+ setsvalue2s(L->top, luaS_new(L, str));
106+ incr_top(L);
107+}
108+
109+
110+/* this function handles only `%d', `%c', %f, and `%s' formats */
111+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
112+ int n = 1;
113+ pushstr(L, "");
114+ for (;;) {
115+ const char *e = strchr(fmt, '%');
116+ if (e == NULL) break;
117+ setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt));
118+ incr_top(L);
119+ switch (*(e+1)) {
120+ case 's':
121+ pushstr(L, va_arg(argp, char *));
122+ break;
123+ case 'c': {
124+ char buff[2];
125+ buff[0] = cast(char, va_arg(argp, int));
126+ buff[1] = '\0';
127+ pushstr(L, buff);
128+ break;
129+ }
130+ case 'd':
131+ setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
132+ incr_top(L);
133+ break;
134+ case 'f':
135+ setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
136+ incr_top(L);
137+ break;
138+ case '%':
139+ pushstr(L, "%");
140+ break;
141+ default: lua_assert(0);
142+ }
143+ n += 2;
144+ fmt = e+2;
145+ }
146+ pushstr(L, fmt);
147+ luaV_concat(L, n+1, L->top - L->base - 1);
148+ L->top -= n;
149+ return svalue(L->top - 1);
150+}
151+
152+
153+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
154+ const char *msg;
84155 va_list argp;
85− char buff[MAX_VERROR]; /* to hold formatted message */
86156 va_start(argp, fmt);
87− vsprintf(buff, fmt, argp);
157+ msg = luaO_pushvfstring(L, fmt, argp);
88158 va_end(argp);
89− lua_error(L, buff);
159+ return msg;
90160 }
91161
92162
@@ -95,31 +165,31 @@ void luaO_chunkid (char *out, const char *source, int bufflen) { · 2 unmodified lines
95165 strncpy(out, source+1, bufflen); /* remove first char */
96166 out[bufflen-1] = '\0'; /* ensures null termination */
97167 }
98− else {
168+ else { /* out = "source", or "...source" */
99169 if (*source == '@') {
100170 int l;
101171 source++; /* skip the `@' */
102− bufflen -= sizeof("file `...%s'");
172+ bufflen -= sizeof(" `...' ");
103173 l = strlen(source);
174+ strcpy(out, "");
104175 if (l>bufflen) {
105176 source += (l-bufflen); /* get last part of file name */
106− sprintf(out, "file `...%.99s'", source);
177+ strcat(out, "...");
107178 }
108− else
109− sprintf(out, "file `%.99s'", source);
179+ strcat(out, source);
110180 }
111− else {
181+ else { /* out = [string "string"] */
112182 int len = strcspn(source, "\n"); /* stop at first newline */
113− bufflen -= sizeof("string \"%.*s...\"");
183+ bufflen -= sizeof(" [string \"...\"] ");
114184 if (len > bufflen) len = bufflen;
185+ strcpy(out, "[string \"");
115186 if (source[len] != '\0') { /* must truncate? */
116− strcpy(out, "string \"");
117− out += strlen(out);
118− strncpy(out, source, len);
119− strcpy(out+len, "...\"");
187+ strncat(out, source, len);
188+ strcat(out, "...");
120189 }
121190 else
122− sprintf(out, "string \"%.99s\"", source);
191+ strcat(out, source);
192+ strcat(out, "\"]");
123193 }
124194 }
125195 }
src/lobject.h+246−114
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lobject.h,v 1.82 2000/10/30 17:49:19 roberto Exp $
2+** $Id: lobject.h,v 1.159 2003/03/18 12:50:04 roberto Exp $
33 ** Type definitions for Lua objects
44 ** See Copyright Notice in lua.h
55 */
@@ -12,115 +12,222 @@ · 6 unmodified lines
1212 #include "lua.h"
1313
1414
15−#ifdef LUA_DEBUG
16−#undef NDEBUG
17−#include <assert.h>
18−#define LUA_INTERNALERROR(s) assert(((void)s,0))
19−#define LUA_ASSERT(c,s) assert(((void)s,(c)))
20−#else
21−#define LUA_INTERNALERROR(s) /* empty */
22−#define LUA_ASSERT(c,s) /* empty */
23−#endif
15+/* tags for values visible from Lua */
16+#define NUM_TAGS LUA_TTHREAD
2417
2518
26−#ifdef LUA_DEBUG
27−/* to avoid warnings, and make sure value is really unused */
28−#define UNUSED(x) (x=0, (void)(x))
29−#else
30−#define UNUSED(x) ((void)(x)) /* to avoid warnings */
31−#endif
19+/*
20+** Extra tags for non-values
21+*/
22+#define LUA_TPROTO (NUM_TAGS+1)
23+#define LUA_TUPVAL (NUM_TAGS+2)
24+
25+
26+/*
27+** Union of all collectable objects
28+*/
29+typedef union GCObject GCObject;
3230
3331
34−/* mark for closures active in the stack */
35−#define LUA_TMARK 6
32+/*
33+** Common Header for all collectable objects (in macro form, to be
34+** included in other objects)
35+*/
36+#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
3637
3738
38−/* tags for values visible from Lua == first user-created tag */
39−#define NUM_TAGS 6
39+/*
40+** Common header in struct form
41+*/
42+typedef struct GCheader {
43+ CommonHeader;
44+} GCheader;
4045
4146
42−/* check whether `t' is a mark */
43−#define is_T_MARK(t) ((t) == LUA_TMARK)
4447
4548
49+/*
50+** Union of all Lua values
51+*/
4652 typedef union {
47− struct TString *ts; /* LUA_TSTRING, LUA_TUSERDATA */
48− struct Closure *cl; /* LUA_TFUNCTION */
49− struct Hash *a; /* LUA_TTABLE */
50− struct CallInfo *i; /* LUA_TLMARK */
51− Number n; /* LUA_TNUMBER */
53+ GCObject *gc;
54+ void *p;
55+ lua_Number n;
56+ int b;
5257 } Value;
5358
5459
55−/* Macros to access values */
56−#define ttype(o) ((o)->ttype)
57−#define nvalue(o) ((o)->value.n)
58−#define tsvalue(o) ((o)->value.ts)
59−#define clvalue(o) ((o)->value.cl)
60−#define hvalue(o) ((o)->value.a)
61−#define infovalue(o) ((o)->value.i)
62−#define svalue(o) (tsvalue(o)->str)
63−
64−
60+/*
61+** Lua values (or `tagged objects')
62+*/
6563 typedef struct lua_TObject {
66− int ttype;
64+ int tt;
6765 Value value;
6866 } TObject;
6967
7068
69+/* Macros to test type */
70+#define ttisnil(o) (ttype(o) == LUA_TNIL)
71+#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
72+#define ttisstring(o) (ttype(o) == LUA_TSTRING)
73+#define ttistable(o) (ttype(o) == LUA_TTABLE)
74+#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
75+#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
76+#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
77+#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
78+#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
79+
80+/* Macros to access values */
81+#define ttype(o) ((o)->tt)
82+#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
83+#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
84+#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
85+#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
86+#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
87+#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
88+#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
89+#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
90+#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
91+
92+#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
93+
94+/* Macros to set values */
95+#define setnvalue(obj,x) \
96+ { TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); }
97+
98+#define chgnvalue(obj,x) \
99+ check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x))
100+
101+#define setpvalue(obj,x) \
102+ { TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); }
103+
104+#define setbvalue(obj,x) \
105+ { TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); }
106+
107+#define setsvalue(obj,x) \
108+ { TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \
109+ i_o->value.gc=cast(GCObject *, (x)); \
110+ lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); }
111+
112+#define setuvalue(obj,x) \
113+ { TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \
114+ i_o->value.gc=cast(GCObject *, (x)); \
115+ lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); }
116+
117+#define setthvalue(obj,x) \
118+ { TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \
119+ i_o->value.gc=cast(GCObject *, (x)); \
120+ lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); }
121+
122+#define setclvalue(obj,x) \
123+ { TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \
124+ i_o->value.gc=cast(GCObject *, (x)); \
125+ lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); }
126+
127+#define sethvalue(obj,x) \
128+ { TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \
129+ i_o->value.gc=cast(GCObject *, (x)); \
130+ lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); }
131+
132+#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
133+
134+
135+
71136 /*
72−** String headers for string table
137+** for internal debug only
138+*/
139+#define checkconsistency(obj) \
140+ lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
141+
142+
143+#define setobj(obj1,obj2) \
144+ { const TObject *o2=(obj2); TObject *o1=(obj1); \
145+ checkconsistency(o2); \
146+ o1->tt=o2->tt; o1->value = o2->value; }
147+
148+
149+/*
150+** different types of sets, according to destination
73151 */
74152
153+/* from stack to (same) stack */
154+#define setobjs2s setobj
155+/* to stack (not from same stack) */
156+#define setobj2s setobj
157+#define setsvalue2s setsvalue
158+/* from table to same table */
159+#define setobjt2t setobj
160+/* to table */
161+#define setobj2t setobj
162+/* to new object */
163+#define setobj2n setobj
164+#define setsvalue2n setsvalue
165+
166+#define setttype(obj, tt) (ttype(obj) = (tt))
167+
168+
169+#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
170+
171+
172+
173+typedef TObject *StkId; /* index to stack elements */
174+
175+
75176 /*
76−** most `malloc' libraries allocate memory in blocks of 8 bytes. TSPACK
77−** tries to make sizeof(TString) a multiple of this granularity, to reduce
78−** waste of space.
177+** String headers for string table
79178 */
80−#define TSPACK ((int)sizeof(int))
81−
82−typedef struct TString {
83− union {
84− struct { /* for strings */
85− unsigned long hash;
86− int constindex; /* hint to reuse constants */
87− } s;
88− struct { /* for userdata */
89− int tag;
90− void *value;
91− } d;
92− } u;
93− size_t len;
94− struct TString *nexthash; /* chain for hash table */
95− int marked;
96− char str[TSPACK]; /* variable length string!! must be the last field! */
179+typedef union TString {
180+ L_Umaxalign dummy; /* ensures maximum alignment for strings */
181+ struct {
182+ CommonHeader;
183+ lu_byte reserved;
184+ lu_hash hash;
185+ size_t len;
186+ } tsv;
97187 } TString;
98188
99189
190+#define getstr(ts) cast(const char *, (ts) + 1)
191+#define svalue(o) getstr(tsvalue(o))
192+
193+
194+
195+typedef union Udata {
196+ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
197+ struct {
198+ CommonHeader;
199+ struct Table *metatable;
200+ size_t len;
201+ } uv;
202+} Udata;
203+
204+
205+
206+
100207 /*
101208 ** Function Prototypes
102209 */
103210 typedef struct Proto {
104− Number *knum; /* Number numbers used by the function */
105− int nknum; /* size of `knum' */
106− struct TString **kstr; /* strings used by the function */
107− int nkstr; /* size of `kstr' */
108− struct Proto **kproto; /* functions defined inside the function */
109− int nkproto; /* size of `kproto' */
211+ CommonHeader;
212+ TObject *k; /* constants used by the function */
110213 Instruction *code;
111− int ncode; /* size of `code'; when 0 means an incomplete `Proto' */
112− short numparams;
113− short is_vararg;
114− short maxstacksize;
115− short marked;
116− struct Proto *next;
117− /* debug information */
214+ struct Proto **p; /* functions defined inside the function */
118215 int *lineinfo; /* map from opcodes to source lines */
119− int nlineinfo; /* size of `lineinfo' */
120− int nlocvars;
121216 struct LocVar *locvars; /* information about local variables */
122− int lineDefined;
217+ TString **upvalues; /* upvalue names */
123218 TString *source;
219+ int sizeupvalues;
220+ int sizek; /* size of `k' */
221+ int sizecode;
222+ int sizelineinfo;
223+ int sizep; /* size of `p' */
224+ int sizelocvars;
225+ int lineDefined;
226+ GCObject *gclist;
227+ lu_byte nups; /* number of upvalues */
228+ lu_byte numparams;
229+ lu_byte is_vararg;
230+ lu_byte maxstacksize;
124231 } Proto;
125232
126233
@@ -131,73 +238,98 @@ typedef struct LocVar { · 4 unmodified lines
131238 } LocVar;
132239
133240
241+
242+/*
243+** Upvalues
244+*/
245+
246+typedef struct UpVal {
247+ CommonHeader;
248+ TObject *v; /* points to stack or to its own value */
249+ TObject value; /* the value (when closed) */
250+} UpVal;
251+
252+
134253 /*
135254 ** Closures
136255 */
137−typedef struct Closure {
138− union {
139− lua_CFunction c; /* C functions */
140− struct Proto *l; /* Lua functions */
141− } f;
142− struct Closure *next;
143− struct Closure *mark; /* marked closures (point to itself when not marked) */
144− short isC; /* 0 for Lua functions, 1 for C functions */
145− short nupvalues;
256+
257+#define ClosureHeader \
258+ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
259+
260+typedef struct CClosure {
261+ ClosureHeader;
262+ lua_CFunction f;
146263 TObject upvalue[1];
264+} CClosure;
265+
266+
267+typedef struct LClosure {
268+ ClosureHeader;
269+ struct Proto *p;
270+ TObject g; /* global table for this closure */
271+ UpVal *upvals[1];
272+} LClosure;
273+
274+
275+typedef union Closure {
276+ CClosure c;
277+ LClosure l;
147278 } Closure;
148279
149280
150−#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
281+#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
282+#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
283+
151284
285+/*
286+** Tables
287+*/
152288
153289 typedef struct Node {
154− TObject key;
155− TObject val;
290+ TObject i_key;
291+ TObject i_val;
156292 struct Node *next; /* for chaining */
157293 } Node;
158294
159−typedef struct Hash {
295+
296+typedef struct Table {
297+ CommonHeader;
298+ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
299+ lu_byte lsizenode; /* log2 of size of `node' array */
300+ struct Table *metatable;
301+ TObject *array; /* array part */
160302 Node *node;
161− int htag;
162− int size;
163303 Node *firstfree; /* this position is free; all positions after it are full */
164− struct Hash *next;
165− struct Hash *mark; /* marked tables (point to itself when not marked) */
166−} Hash;
167−
304+ GCObject *gclist;
305+ int sizearray; /* size of `array' array */
306+} Table;
168307
169−/* unmarked tables and closures are represented by pointing `mark' to
170−** themselves
171−*/
172−#define ismarked(x) ((x)->mark != (x))
173308
174309
175310 /*
176−** informations about a call (for debugging)
311+** `module' operation for hashing (size is always a power of 2)
177312 */
178−typedef struct CallInfo {
179− struct Closure *func; /* function being called */
180− const Instruction **pc; /* current pc of called function */
181− int lastpc; /* last pc traced */
182− int line; /* current line */
183− int refi; /* current index in `lineinfo' */
184−} CallInfo;
313+#define lmod(s,size) \
314+ check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))
185315
186316
187−extern const TObject luaO_nilobject;
188−extern const char *const luaO_typenames[];
317+#define twoto(x) (1<<(x))
318+#define sizenode(t) (twoto((t)->lsizenode))
189319
190320
191−#define luaO_typename(o) (luaO_typenames[ttype(o)])
192321
322+extern const TObject luaO_nilobject;
193323
194−lint32 luaO_power2 (lint32 n);
195−char *luaO_openspace (lua_State *L, size_t n);
324+int luaO_log2 (unsigned int x);
325+int luaO_int2fb (unsigned int x);
326+#define fb2int(x) (((x) & 7) << ((x) >> 3))
196327
197−int luaO_equalObj (const TObject *t1, const TObject *t2);
198−int luaO_str2d (const char *s, Number *result);
328+int luaO_rawequalObj (const TObject *t1, const TObject *t2);
329+int luaO_str2d (const char *s, lua_Number *result);
199330
200−void luaO_verror (lua_State *L, const char *fmt, ...);
331+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp);
332+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
201333 void luaO_chunkid (char *out, const char *source, int len);
202334
203335
src/lopcodes.c+102−0
@@ -0,0 +1,102 @@
1+/*
2+** $Id: lopcodes.c,v 1.22 2002/12/04 17:38:31 roberto Exp $
3+** extracted automatically from lopcodes.h by mkprint.lua
4+** DO NOT EDIT
5+** See Copyright Notice in lua.h
6+*/
7+
8+
9+#define lopcodes_c
10+
11+#include "lua.h"
12+
13+#include "lobject.h"
14+#include "lopcodes.h"
15+
16+
17+#ifdef LUA_OPNAMES
18+
19+const char *const luaP_opnames[] = {
20+ "MOVE",
21+ "LOADK",
22+ "LOADBOOL",
23+ "LOADNIL",
24+ "GETUPVAL",
25+ "GETGLOBAL",
26+ "GETTABLE",
27+ "SETGLOBAL",
28+ "SETUPVAL",
29+ "SETTABLE",
30+ "NEWTABLE",
31+ "SELF",
32+ "ADD",
33+ "SUB",
34+ "MUL",
35+ "DIV",
36+ "POW",
37+ "UNM",
38+ "NOT",
39+ "CONCAT",
40+ "JMP",
41+ "EQ",
42+ "LT",
43+ "LE",
44+ "TEST",
45+ "CALL",
46+ "TAILCALL",
47+ "RETURN",
48+ "FORLOOP",
49+ "TFORLOOP",
50+ "TFORPREP",
51+ "SETLIST",
52+ "SETLISTO",
53+ "CLOSE",
54+ "CLOSURE"
55+};
56+
57+#endif
58+
59+#define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
60+ ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
61+ ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
62+
63+
64+const lu_byte luaP_opmodes[NUM_OPCODES] = {
65+/* T B Bk Ck sA K mode opcode */
66+ opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_MOVE */
67+ ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_LOADK */
68+ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_LOADBOOL */
69+ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_LOADNIL */
70+ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_GETUPVAL */
71+ ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_GETGLOBAL */
72+ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_GETTABLE */
73+ ,opmode(0, 0, 0, 0, 0, 1, iABx) /* OP_SETGLOBAL */
74+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */
75+ ,opmode(0, 0, 1, 1, 0, 0, iABC) /* OP_SETTABLE */
76+ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_NEWTABLE */
77+ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_SELF */
78+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_ADD */
79+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_SUB */
80+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_MUL */
81+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_DIV */
82+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_POW */
83+ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_UNM */
84+ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_NOT */
85+ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_CONCAT */
86+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_JMP */
87+ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_EQ */
88+ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LT */
89+ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LE */
90+ ,opmode(1, 1, 0, 0, 1, 0, iABC) /* OP_TEST */
91+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CALL */
92+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */
93+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */
94+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */
95+ ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */
96+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */
97+ ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */
98+ ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLISTO */
99+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CLOSE */
100+ ,opmode(0, 0, 0, 0, 1, 0, iABx) /* OP_CLOSURE */
101+};
102+
src/lopcodes.h+165−95
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lopcodes.h,v 1.68 2000/10/24 16:05:59 roberto Exp $
2+** $Id: lopcodes.h,v 1.102 2002/08/21 18:56:09 roberto Exp $
33 ** Opcodes for Lua virtual machine
44 ** See Copyright Notice in lua.h
55 */
@@ -12,29 +12,58 @@ · 6 unmodified lines
1212
1313 /*===========================================================================
1414 We assume that instructions are unsigned numbers.
15− All instructions have an opcode in the first 6 bits. Moreover,
16− an instruction can have 0, 1, or 2 arguments. Instructions can
17− have the following types:
18− type 0: no arguments
19− type 1: 1 unsigned argument in the higher bits (called `U')
20− type 2: 1 signed argument in the higher bits (`S')
21− type 3: 1st unsigned argument in the higher bits (`A')
22− 2nd unsigned argument in the middle bits (`B')
15+ All instructions have an opcode in the first 6 bits.
16+ Instructions can have the following fields:
17+ `A' : 8 bits
18+ `B' : 9 bits
19+ `C' : 9 bits
20+ `Bx' : 18 bits (`B' and `C' together)
21+ `sBx' : signed Bx
2322
2423 A signed argument is represented in excess K; that is, the number
2524 value is the unsigned value minus K. K is exactly the maximum value
2625 for that argument (so that -max is represented by 0, and +max is
2726 represented by 2*max), which is half the maximum for the corresponding
2827 unsigned argument.
29−
30− The size of each argument is defined in `llimits.h'. The usual is an
31− instruction with 32 bits, U arguments with 26 bits (32-6), B arguments
32− with 9 bits, and A arguments with 17 bits (32-6-9). For small
33− installations, the instruction size can be 16, so U has 10 bits,
34− and A and B have 5 bits each.
3528 ===========================================================================*/
3629
3730
31+enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
32+
33+
34+/*
35+** size and position of opcode arguments.
36+*/
37+#define SIZE_C 9
38+#define SIZE_B 9
39+#define SIZE_Bx (SIZE_C + SIZE_B)
40+#define SIZE_A 8
41+
42+#define SIZE_OP 6
43+
44+#define POS_C SIZE_OP
45+#define POS_B (POS_C + SIZE_C)
46+#define POS_Bx POS_C
47+#define POS_A (POS_B + SIZE_B)
48+
49+
50+/*
51+** limits for opcode arguments.
52+** we use (signed) int to manipulate most arguments,
53+** so they must fit in BITS_INT-1 bits (-1 for sign)
54+*/
55+#if SIZE_Bx < BITS_INT-1
56+#define MAXARG_Bx ((1<<SIZE_Bx)-1)
57+#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
58+#else
59+#define MAXARG_Bx MAX_INT
60+#define MAXARG_sBx MAX_INT
61+#endif
62+
63+
64+#define MAXARG_A ((1<<SIZE_A)-1)
65+#define MAXARG_B ((1<<SIZE_B)-1)
66+#define MAXARG_C ((1<<SIZE_C)-1)
3867
3968
4069 /* creates a mask with `n' 1 bits at position `p' */
@@ -47,122 +76,163 @@ · 6 unmodified lines
4776 ** the following macros help to manipulate instructions
4877 */
4978
50−#define CREATE_0(o) ((Instruction)(o))
51−#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0)))
52−#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o)))
79+#define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0)))
80+#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)))
5381
54−#define CREATE_U(o,u) ((Instruction)(o) | ((Instruction)(u)<<POS_U))
55−#define GETARG_U(i) ((int)((i)>>POS_U))
56−#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
57− ((Instruction)(u)<<POS_U)))
82+#define GETARG_A(i) (cast(int, (i)>>POS_A))
83+#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
84+ ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
5885
59−#define CREATE_S(o,s) CREATE_U((o),(s)+MAXARG_S)
60−#define GETARG_S(i) (GETARG_U(i)-MAXARG_S)
61−#define SETARG_S(i,s) SETARG_U((i),(s)+MAXARG_S)
86+#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
87+#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
88+ ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
89+
90+#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
91+#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
92+ ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
93+
94+#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
95+#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
96+ ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
97+
98+#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
99+#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
100+
101+
102+#define CREATE_ABC(o,a,b,c) (cast(Instruction, o) \
103+ | (cast(Instruction, a)<<POS_A) \
104+ | (cast(Instruction, b)<<POS_B) \
105+ | (cast(Instruction, c)<<POS_C))
106+
107+#define CREATE_ABx(o,a,bc) (cast(Instruction, o) \
108+ | (cast(Instruction, a)<<POS_A) \
109+ | (cast(Instruction, bc)<<POS_Bx))
62110
63111
64−#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
65− | ((Instruction)(b)<<POS_B))
66−#define GETARG_A(i) ((int)((i)>>POS_A))
67−#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
68− ((Instruction)(a)<<POS_A)))
69−#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0)))
70−#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
71− ((Instruction)(b)<<POS_B)))
72112
73113
74114 /*
75−** K = U argument used as index to `kstr'
76−** J = S argument used as jump offset (relative to pc of next instruction)
77−** L = unsigned argument used as index of local variable
78−** N = U argument used as index to `knum'
115+** invalid register that fits in 8 bits
116+*/
117+#define NO_REG MAXARG_A
118+
119+
120+/*
121+** R(x) - register
122+** Kst(x) - constant (in constant table)
123+** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
124+*/
125+
126+
127+/*
128+** grep "ORDER OP" if you change these enums
79129 */
80130
81131 typedef enum {
82132 /*----------------------------------------------------------------------
83−name args stack before stack after side effects
133+name args description
84134 ------------------------------------------------------------------------*/
85−OP_END,/* - - (return) no results */
86−OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */
135+OP_MOVE,/* A B R(A) := R(B) */
136+OP_LOADK,/* A Bx R(A) := Kst(Bx) */
137+OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) PC++ */
138+OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
139+OP_GETUPVAL,/* A B R(A) := UpValue[B] */
87140
88−OP_CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */
89−OP_TAILCALL,/* A B v_n-v_1 f(at a) (return) f(v1,...,v_n) */
141+OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
142+OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
90143
91−OP_PUSHNIL,/* U - nil_1-nil_u */
92−OP_POP,/* U a_u-a_1 - */
144+OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
145+OP_SETUPVAL,/* A B UpValue[B] := R(A) */
146+OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
93147
94−OP_PUSHINT,/* S - (Number)s */
95−OP_PUSHSTRING,/* K - KSTR[k] */
96−OP_PUSHNUM,/* N - KNUM[n] */
97−OP_PUSHNEGNUM,/* N - -KNUM[n] */
148+OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
98149
99−OP_PUSHUPVALUE,/* U - Closure[u] */
150+OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
100151
101−OP_GETLOCAL,/* L - LOC[l] */
102−OP_GETGLOBAL,/* K - VAR[KSTR[k]] */
152+OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
153+OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
154+OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
155+OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
156+OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
157+OP_UNM,/* A B R(A) := -R(B) */
158+OP_NOT,/* A B R(A) := not R(B) */
103159
104−OP_GETTABLE,/* - i t t[i] */
105−OP_GETDOTTED,/* K t t[KSTR[k]] */
106−OP_GETINDEXED,/* L t t[LOC[l]] */
107−OP_PUSHSELF,/* K t t t[KSTR[k]] */
160+OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
108161
109−OP_CREATETABLE,/* U - newarray(size = u) */
162+OP_JMP,/* sBx PC += sBx */
110163
111−OP_SETLOCAL,/* L x - LOC[l]=x */
112−OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */
113−OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */
164+OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
165+OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
166+OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
114167
115−OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */
116−OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */
168+OP_TEST,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
117169
118−OP_ADD,/* - y x x+y */
119−OP_ADDI,/* S x x+s */
120−OP_SUB,/* - y x x-y */
121−OP_MULT,/* - y x x*y */
122−OP_DIV,/* - y x x/y */
123−OP_POW,/* - y x x^y */
124−OP_CONCAT,/* U v_u-v_1 v1..-..v_u */
125−OP_MINUS,/* - x -x */
126−OP_NOT,/* - x (x==nil)? 1 : nil */
170+OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
171+OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
172+OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
127173
128−OP_JMPNE,/* J y x - (x~=y)? PC+=s */
129−OP_JMPEQ,/* J y x - (x==y)? PC+=s */
130−OP_JMPLT,/* J y x - (x<y)? PC+=s */
131−OP_JMPLE,/* J y x - (x<y)? PC+=s */
132−OP_JMPGT,/* J y x - (x>y)? PC+=s */
133−OP_JMPGE,/* J y x - (x>=y)? PC+=s */
174+OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */
134175
135−OP_JMPT,/* J x - (x~=nil)? PC+=s */
136−OP_JMPF,/* J x - (x==nil)? PC+=s */
137−OP_JMPONT,/* J x (x~=nil)? x : - (x~=nil)? PC+=s */
138−OP_JMPONF,/* J x (x==nil)? x : - (x==nil)? PC+=s */
139−OP_JMP,/* J - - PC+=s */
176+OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
177+ if R(A+2) ~= nil then pc++ */
178+OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
179+ PC += sBx */
140180
141−OP_PUSHNILJMP,/* - - nil PC++; */
181+OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */
182+OP_SETLISTO,/* A Bx */
142183
143−OP_FORPREP,/* J */
144−OP_FORLOOP,/* J */
184+OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
185+OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
186+} OpCode;
145187
146−OP_LFORPREP,/* J */
147−OP_LFORLOOP,/* J */
148188
149−OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
189+#define NUM_OPCODES (cast(int, OP_CLOSURE+1))
190+
150191
151−} OpCode;
152192
153−#define NUM_OPCODES ((int)OP_CLOSURE+1)
193+/*===========================================================================
194+ Notes:
195+ (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
196+ and can be 0: OP_CALL then sets `top' to last_result+1, so
197+ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
198+
199+ (2) In OP_RETURN, if (B == 0) then return up to `top'
200+
201+ (3) For comparisons, B specifies what conditions the test should accept.
202+
203+ (4) All `skips' (pc++) assume that next instruction is a jump
204+===========================================================================*/
154205
155206
156−#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)
207+/*
208+** masks for instruction properties
209+*/
210+enum OpModeMask {
211+ OpModeBreg = 2, /* B is a register */
212+ OpModeBrk, /* B is a register/constant */
213+ OpModeCrk, /* C is a register/constant */
214+ OpModesetA, /* instruction set register A */
215+ OpModeK, /* Bx is a constant */
216+ OpModeT /* operator is a test */
217+
218+};
157219
158220
221+extern const lu_byte luaP_opmodes[NUM_OPCODES];
159222
160−/* special code to fit a LUA_MULTRET inside an argB */
161−#define MULT_RET 255 /* (<=MAXARG_B) */
162−#if MULT_RET>MAXARG_B
163−#undef MULT_RET
164−#define MULT_RET MAXARG_B
223+#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
224+#define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b)))
225+
226+
227+#ifdef LUA_OPNAMES
228+extern const char *const luaP_opnames[]; /* opcode names */
165229 #endif
166230
167231
232+
233+/* number of list items to accumulate before a SETLIST instruction */
234+/* (must be a power of 2) */
235+#define LFIELDS_PER_FLUSH 32
236+
237+
168238 #endif
src/lparser.c+787−582
@@ -1,16 +1,18 @@
11 /*
2−** $Id: lparser.c,v 1.117 2000/11/29 11:57:42 roberto Exp $
3−** LL(1) Parser and code generator for Lua
2+** $Id: lparser.c,v 1.208 2003/04/03 13:35:34 roberto Exp $
3+** Lua Parser
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <stdio.h>
98 #include <string.h>
109
10+#define lparser_c
11+
1112 #include "lua.h"
1213
1314 #include "lcode.h"
15+#include "ldebug.h"
1416 #include "lfunc.h"
1517 #include "llex.h"
1618 #include "lmem.h"
@@ -21,35 +23,34 @@ · 4 unmodified lines
2123 #include "lstring.h"
2224
2325
24−/*
25−** Constructors descriptor:
26−** `n' indicates number of elements, and `k' signals whether
27−** it is a list constructor (k = 0) or a record constructor (k = 1)
28−** or empty (k = ';' or '}')
29−*/
30−typedef struct Constdesc {
31− int n;
32− int k;
33−} Constdesc;
3426
3527
36−typedef struct Breaklabel {
37− struct Breaklabel *previous; /* chain */
38− int breaklist;
39− int stacklevel;
40−} Breaklabel;
28+#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
29+
30+
31+#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \
32+ luaX_syntaxerror(ls, "too many syntax levels");
33+#define leavelevel(ls) ((ls)->nestlevel--)
4134
4235
36+/*
37+** nodes for block list (list of active blocks)
38+*/
39+typedef struct BlockCnt {
40+ struct BlockCnt *previous; /* chain */
41+ int breaklist; /* list of jumps out of this loop */
42+ int nactvar; /* # active local variables outside the breakable structure */
43+ int upval; /* true if some variable in the block is an upvalue */
44+ int isbreakable; /* true if `block' is a loop */
45+} BlockCnt;
46+
4347
4448
4549 /*
4650 ** prototypes for recursive non-terminal functions
4751 */
48−static void body (LexState *ls, int needself, int line);
4952 static void chunk (LexState *ls);
50−static void constructor (LexState *ls);
5153 static void expr (LexState *ls, expdesc *v);
52−static void exp1 (LexState *ls);
5354
5455
5556
@@ -65,32 +66,18 @@ static void next (LexState *ls) { · 9 unmodified lines
6566
6667
6768 static void lookahead (LexState *ls) {
68− LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads");
69+ lua_assert(ls->lookahead.token == TK_EOS);
6970 ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
7071 }
7172
7273
7374 static void error_expected (LexState *ls, int token) {
74− char buff[100], t[TOKEN_LEN];
75− luaX_token2str(token, t);
76− sprintf(buff, "`%.20s' expected", t);
77− luaK_error(ls, buff);
75+ luaX_syntaxerror(ls,
76+ luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token)));
7877 }
7978
8079
81−static void check (LexState *ls, int c) {
82− if (ls->t.token != c)
83− error_expected(ls, c);
84− next(ls);
85−}
86−
87−
88−static void check_condition (LexState *ls, int c, const char *msg) {
89− if (!c) luaK_error(ls, msg);
90−}
91−
92−
93−static int optional (LexState *ls, int c) {
80+static int testnext (LexState *ls, int c) {
9481 if (ls->t.token == c) {
9582 next(ls);
9683 return 1;
@@ -99,40 +86,26 @@ static int optional (LexState *ls, int c) { · 2 unmodified lines
9986 }
10087
10188
89+static void check (LexState *ls, int c) {
90+ if (!testnext(ls, c))
91+ error_expected(ls, c);
92+}
93+
94+
95+#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
96+
97+
98+
10299 static void check_match (LexState *ls, int what, int who, int where) {
103− if (ls->t.token != what) {
100+ if (!testnext(ls, what)) {
104101 if (where == ls->linenumber)
105102 error_expected(ls, what);
106103 else {
107− char buff[100];
108− char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
109− luaX_token2str(what, t_what);
110− luaX_token2str(who, t_who);
111− sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
112− t_what, t_who, where);
113− luaK_error(ls, buff);
104+ luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
105+ "`%s' expected (to close `%s' at line %d)",
106+ luaX_token2str(ls, what), luaX_token2str(ls, who), where));
114107 }
115108 }
116− next(ls);
117−}
118−
119−
120−static int string_constant (FuncState *fs, TString *s) {
121− Proto *f = fs->f;
122− int c = s->u.s.constindex;
123− if (c >= f->nkstr || f->kstr[c] != s) {
124− luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *,
125− "constant table overflow", MAXARG_U);
126− c = f->nkstr++;
127− f->kstr[c] = s;
128− s->u.s.constindex = c; /* hint for next time */
129− }
130− return c;
131−}
132−
133−
134−static void code_string (LexState *ls, TString *s) {
135− luaK_kstr(ls, string_constant(ls->fs, s));
136109 }
137110
138111
@@ -145,182 +118,224 @@ static TString *str_checkname (LexState *ls) { · 6 unmodified lines
145118 }
146119
147120
148−static int checkname (LexState *ls) {
149− return string_constant(ls->fs, str_checkname(ls));
121+static void init_exp (expdesc *e, expkind k, int i) {
122+ e->f = e->t = NO_JUMP;
123+ e->k = k;
124+ e->info = i;
125+}
126+
127+
128+static void codestring (LexState *ls, expdesc *e, TString *s) {
129+ init_exp(e, VK, luaK_stringK(ls->fs, s));
130+}
131+
132+
133+static void checkname(LexState *ls, expdesc *e) {
134+ codestring(ls, e, str_checkname(ls));
150135 }
151136
152137
153138 static int luaI_registerlocalvar (LexState *ls, TString *varname) {
154− Proto *f = ls->fs->f;
155− luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT);
156− f->locvars[f->nlocvars].varname = varname;
157− return f->nlocvars++;
139+ FuncState *fs = ls->fs;
140+ Proto *f = fs->f;
141+ luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
142+ LocVar, MAX_INT, "");
143+ f->locvars[fs->nlocvars].varname = varname;
144+ return fs->nlocvars++;
158145 }
159146
160147
161148 static void new_localvar (LexState *ls, TString *name, int n) {
162149 FuncState *fs = ls->fs;
163− luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables");
164− fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name);
150+ luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables");
151+ fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name);
165152 }
166153
167154
168155 static void adjustlocalvars (LexState *ls, int nvars) {
169156 FuncState *fs = ls->fs;
170− while (nvars--)
171− fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc;
157+ fs->nactvar += nvars;
158+ for (; nvars; nvars--) {
159+ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
160+ }
172161 }
173162
174163
175−static void removelocalvars (LexState *ls, int nvars) {
164+static void removevars (LexState *ls, int tolevel) {
176165 FuncState *fs = ls->fs;
177− while (nvars--)
178− fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
166+ while (fs->nactvar > tolevel)
167+ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
179168 }
180169
181170
182171 static void new_localvarstr (LexState *ls, const char *name, int n) {
183− new_localvar(ls, luaS_newfixed(ls->L, name), n);
172+ new_localvar(ls, luaS_new(ls->L, name), n);
184173 }
185174
186175
187−static int search_local (LexState *ls, TString *n, expdesc *var) {
188− FuncState *fs;
189− int level = 0;
190− for (fs=ls->fs; fs; fs=fs->prev) {
191− int i;
192− for (i=fs->nactloc-1; i >= 0; i--) {
193− if (n == fs->f->locvars[fs->actloc[i]].varname) {
194− var->k = VLOCAL;
195− var->u.index = i;
196− return level;
197− }
198− }
199− level++; /* `var' not found; check outer level */
200− }
201− var->k = VGLOBAL; /* not found in any level; must be global */
202− return -1;
176+static void create_local (LexState *ls, const char *name) {
177+ new_localvarstr(ls, name, 0);
178+ adjustlocalvars(ls, 1);
203179 }
204180
205181
206−static void singlevar (LexState *ls, TString *n, expdesc *var) {
207− int level = search_local(ls, n, var);
208− if (level >= 1) /* neither local (0) nor global (-1)? */
209− luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str);
210− else if (level == -1) /* global? */
211− var->u.index = string_constant(ls->fs, n);
182+static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
183+ int i;
184+ Proto *f = fs->f;
185+ for (i=0; i<f->nups; i++) {
186+ if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
187+ lua_assert(fs->f->upvalues[i] == name);
188+ return i;
189+ }
190+ }
191+ /* new one */
192+ luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
193+ luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues,
194+ TString *, MAX_INT, "");
195+ fs->f->upvalues[f->nups] = name;
196+ fs->upvalues[f->nups] = *v;
197+ return f->nups++;
212198 }
213199
214200
215−static int indexupvalue (LexState *ls, expdesc *v) {
216− FuncState *fs = ls->fs;
201+static int searchvar (FuncState *fs, TString *n) {
217202 int i;
218− for (i=0; i<fs->nupvalues; i++) {
219− if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index)
203+ for (i=fs->nactvar-1; i >= 0; i--) {
204+ if (n == getlocvar(fs, i).varname)
220205 return i;
221206 }
222− /* new one */
223− luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues");
224− fs->upvalues[fs->nupvalues] = *v;
225− return fs->nupvalues++;
207+ return -1; /* not found */
226208 }
227209
228210
229−static void pushupvalue (LexState *ls, TString *n) {
230− FuncState *fs = ls->fs;
231− expdesc v;
232− int level = search_local(ls, n, &v);
233− if (level == -1) { /* global? */
234− if (fs->prev == NULL)
235− luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
236− v.u.index = string_constant(fs->prev, n);
211+static void markupval (FuncState *fs, int level) {
212+ BlockCnt *bl = fs->bl;
213+ while (bl && bl->nactvar > level) bl = bl->previous;
214+ if (bl) bl->upval = 1;
215+}
216+
217+
218+static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
219+ if (fs == NULL) /* no more levels? */
220+ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
221+ else {
222+ int v = searchvar(fs, n); /* look up at current level */
223+ if (v >= 0) {
224+ init_exp(var, VLOCAL, v);
225+ if (!base)
226+ markupval(fs, v); /* local will be used as an upval */
227+ }
228+ else { /* not found at current level; try upper one */
229+ singlevaraux(fs->prev, n, var, 0);
230+ if (var->k == VGLOBAL) {
231+ if (base)
232+ var->info = luaK_stringK(fs, n); /* info points to global name */
233+ }
234+ else { /* LOCAL or UPVAL */
235+ var->info = indexupvalue(fs, n, var);
236+ var->k = VUPVAL; /* upvalue in this level */
237+ }
238+ }
237239 }
238− else if (level != 1)
239− luaX_syntaxerror(ls,
240− "upvalue must be global or local to immediately outer scope", n->str);
241− luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v));
242240 }
243241
244242
245−static void adjust_mult_assign (LexState *ls, int nvars, int nexps) {
243+static TString *singlevar (LexState *ls, expdesc *var, int base) {
244+ TString *varname = str_checkname(ls);
245+ singlevaraux(ls->fs, varname, var, base);
246+ return varname;
247+}
248+
249+
250+static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
246251 FuncState *fs = ls->fs;
247− int diff = nexps - nvars;
248− if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */
249− diff--; /* do not count function call itself */
250− if (diff <= 0) { /* more variables than values? */
251− luaK_setcallreturns(fs, -diff); /* function call provide extra values */
252− diff = 0; /* no more difference */
252+ int extra = nvars - nexps;
253+ if (e->k == VCALL) {
254+ extra++; /* includes call itself */
255+ if (extra <= 0) extra = 0;
256+ else luaK_reserveregs(fs, extra-1);
257+ luaK_setcallreturns(fs, e, extra); /* call provides the difference */
258+ }
259+ else {
260+ if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
261+ if (extra > 0) {
262+ int reg = fs->freereg;
263+ luaK_reserveregs(fs, extra);
264+ luaK_nil(fs, reg, extra);
253265 }
254− else /* more values than variables */
255− luaK_setcallreturns(fs, 0); /* call should provide no value */
256266 }
257− /* push or pop eventual difference between list lengths */
258− luaK_adjuststack(fs, diff);
259267 }
260268
261269
262270 static void code_params (LexState *ls, int nparams, int dots) {
263271 FuncState *fs = ls->fs;
264272 adjustlocalvars(ls, nparams);
265− luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters");
266− fs->f->numparams = fs->nactloc; /* `self' could be there already */
267− fs->f->is_vararg = dots;
268− if (dots) {
269− new_localvarstr(ls, "arg", 0);
270− adjustlocalvars(ls, 1);
271− }
272− luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */
273+ luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters");
274+ fs->f->numparams = cast(lu_byte, fs->nactvar);
275+ fs->f->is_vararg = cast(lu_byte, dots);
276+ if (dots)
277+ create_local(ls, "arg");
278+ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
273279 }
274280
275281
276−static void enterbreak (FuncState *fs, Breaklabel *bl) {
277− bl->stacklevel = fs->stacklevel;
282+static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) {
278283 bl->breaklist = NO_JUMP;
284+ bl->isbreakable = isbreakable;
285+ bl->nactvar = fs->nactvar;
286+ bl->upval = 0;
279287 bl->previous = fs->bl;
280288 fs->bl = bl;
289+ lua_assert(fs->freereg == fs->nactvar);
281290 }
282291
283292
284−static void leavebreak (FuncState *fs, Breaklabel *bl) {
293+static void leaveblock (FuncState *fs) {
294+ BlockCnt *bl = fs->bl;
285295 fs->bl = bl->previous;
286− LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels");
287− luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
296+ removevars(fs->ls, bl->nactvar);
297+ if (bl->upval)
298+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
299+ lua_assert(bl->nactvar == fs->nactvar);
300+ fs->freereg = fs->nactvar; /* free registers */
301+ luaK_patchtohere(fs, bl->breaklist);
288302 }
289303
290304
291−static void pushclosure (LexState *ls, FuncState *func) {
305+static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
292306 FuncState *fs = ls->fs;
293307 Proto *f = fs->f;
294308 int i;
295− for (i=0; i<func->nupvalues; i++)
296− luaK_tostack(ls, &func->upvalues[i], 1);
297− luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *,
298− "constant table overflow", MAXARG_A);
299− f->kproto[f->nkproto++] = func->f;
300− luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues);
309+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
310+ MAXARG_Bx, "constant table overflow");
311+ f->p[fs->np++] = func->f;
312+ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
313+ for (i=0; i<func->f->nups; i++) {
314+ OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
315+ luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
316+ }
301317 }
302318
303319
304320 static void open_func (LexState *ls, FuncState *fs) {
305321 Proto *f = luaF_newproto(ls->L);
322+ fs->f = f;
306323 fs->prev = ls->fs; /* linked list of funcstates */
307324 fs->ls = ls;
308325 fs->L = ls->L;
309326 ls->fs = fs;
310− fs->stacklevel = 0;
311− fs->nactloc = 0;
312− fs->nupvalues = 0;
313− fs->bl = NULL;
314− fs->f = f;
315− f->source = ls->source;
316327 fs->pc = 0;
317328 fs->lasttarget = 0;
318− fs->lastline = 0;
319− fs->jlt = NO_JUMP;
320− f->code = NULL;
321− f->maxstacksize = 0;
322− f->numparams = 0; /* default for main chunk */
323− f->is_vararg = 0; /* default for main chunk */
329+ fs->jpc = NO_JUMP;
330+ fs->freereg = 0;
331+ fs->nk = 0;
332+ fs->h = luaH_new(ls->L, 0, 0);
333+ fs->np = 0;
334+ fs->nlocvars = 0;
335+ fs->nactvar = 0;
336+ fs->bl = NULL;
337+ f->source = ls->source;
338+ f->maxstacksize = 2; /* registers 0/1 are always valid */
324339 }
325340
326341
@@ -328,33 +343,40 @@ static void close_func (LexState *ls) { · 1 unmodified line
328343 lua_State *L = ls->L;
329344 FuncState *fs = ls->fs;
330345 Proto *f = fs->f;
331− luaK_code0(fs, OP_END);
332− luaK_getlabel(fs); /* close eventual list of pending jumps */
333− luaM_reallocvector(L, f->code, fs->pc, Instruction);
334− luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
335− luaM_reallocvector(L, f->knum, f->nknum, Number);
336− luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
337− removelocalvars(ls, fs->nactloc);
338− luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar);
339− luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int);
340− f->lineinfo[f->nlineinfo++] = MAX_INT; /* end flag */
341− luaF_protook(L, f, fs->pc); /* proto is ok now */
346+ removevars(ls, 0);
347+ luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */
348+ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
349+ f->sizecode = fs->pc;
350+ luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
351+ f->sizelineinfo = fs->pc;
352+ luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject);
353+ f->sizek = fs->nk;
354+ luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
355+ f->sizep = fs->np;
356+ luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
357+ f->sizelocvars = fs->nlocvars;
358+ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
359+ f->sizeupvalues = f->nups;
360+ lua_assert(luaG_checkcode(f));
361+ lua_assert(fs->bl == NULL);
342362 ls->fs = fs->prev;
343− LUA_ASSERT(fs->bl == NULL, "wrong list end");
344363 }
345364
346365
347−Proto *luaY_parser (lua_State *L, ZIO *z) {
366+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
348367 struct LexState lexstate;
349368 struct FuncState funcstate;
369+ lexstate.buff = buff;
370+ lexstate.nestlevel = 0;
350371 luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
351372 open_func(&lexstate, &funcstate);
352373 next(&lexstate); /* read first token */
353374 chunk(&lexstate);
354375 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
355376 close_func(&lexstate);
356− LUA_ASSERT(funcstate.prev == NULL, "wrong list end");
357− LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main");
377+ lua_assert(funcstate.prev == NULL);
378+ lua_assert(funcstate.f->nups == 0);
379+ lua_assert(lexstate.nestlevel == 0);
358380 return funcstate.f;
359381 }
360382
@@ -365,235 +387,239 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { · 4 unmodified lines
365387 /*============================================================*/
366388
367389
368−static int explist1 (LexState *ls) {
369− /* explist1 -> expr { ',' expr } */
370− int n = 1; /* at least one expression */
371− expdesc v;
372− expr(ls, &v);
373− while (ls->t.token == ',') {
374− luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */
375− next(ls); /* skip comma */
376− expr(ls, &v);
377− n++;
378− }
379− luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */
380− return n;
390+static void luaY_field (LexState *ls, expdesc *v) {
391+ /* field -> ['.' | ':'] NAME */
392+ FuncState *fs = ls->fs;
393+ expdesc key;
394+ luaK_exp2anyreg(fs, v);
395+ next(ls); /* skip the dot or colon */
396+ checkname(ls, &key);
397+ luaK_indexed(fs, v, &key);
381398 }
382399
383400
384−static void funcargs (LexState *ls, int slf) {
401+static void luaY_index (LexState *ls, expdesc *v) {
402+ /* index -> '[' expr ']' */
403+ next(ls); /* skip the '[' */
404+ expr(ls, v);
405+ luaK_exp2val(ls->fs, v);
406+ check(ls, ']');
407+}
408+
409+
410+/*
411+** {======================================================================
412+** Rules for Constructors
413+** =======================================================================
414+*/
415+
416+
417+struct ConsControl {
418+ expdesc v; /* last list item read */
419+ expdesc *t; /* table descriptor */
420+ int nh; /* total number of `record' elements */
421+ int na; /* total number of array elements */
422+ int tostore; /* number of array elements pending to be stored */
423+};
424+
425+
426+static void recfield (LexState *ls, struct ConsControl *cc) {
427+ /* recfield -> (NAME | `['exp1`]') = exp1 */
385428 FuncState *fs = ls->fs;
386− int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */
387− switch (ls->t.token) {
388− case '(': { /* funcargs -> '(' [ explist1 ] ')' */
389− int line = ls->linenumber;
390− int nargs = 0;
391− next(ls);
392− if (ls->t.token != ')') /* arg list not empty? */
393− nargs = explist1(ls);
394− check_match(ls, ')', '(', line);
395−#ifdef LUA_COMPAT_ARGRET
396− if (nargs > 0) /* arg list is not empty? */
397− luaK_setcallreturns(fs, 1); /* last call returns only 1 value */
398−#else
399− UNUSED(nargs); /* to avoid warnings */
400−#endif
401− break;
402− }
403− case '{': { /* funcargs -> constructor */
404− constructor(ls);
405− break;
406− }
407− case TK_STRING: { /* funcargs -> STRING */
408− code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */
409− next(ls);
410− break;
411− }
412− default: {
413− luaK_error(ls, "function arguments expected");
414− break;
415− }
429+ int reg = ls->fs->freereg;
430+ expdesc key, val;
431+ if (ls->t.token == TK_NAME) {
432+ luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor");
433+ cc->nh++;
434+ checkname(ls, &key);
435+ }
436+ else /* ls->t.token == '[' */
437+ luaY_index(ls, &key);
438+ check(ls, '=');
439+ luaK_exp2RK(fs, &key);
440+ expr(ls, &val);
441+ luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key),
442+ luaK_exp2RK(fs, &val));
443+ fs->freereg = reg; /* free registers */
444+}
445+
446+
447+static void closelistfield (FuncState *fs, struct ConsControl *cc) {
448+ if (cc->v.k == VVOID) return; /* there is no list item */
449+ luaK_exp2nextreg(fs, &cc->v);
450+ cc->v.k = VVOID;
451+ if (cc->tostore == LFIELDS_PER_FLUSH) {
452+ luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */
453+ cc->tostore = 0; /* no more items pending */
454+ fs->freereg = cc->t->info + 1; /* free registers */
416455 }
417− fs->stacklevel = slevel; /* call will remove function and arguments */
418− luaK_code2(fs, OP_CALL, slevel, MULT_RET);
419456 }
420457
421458
422−static void var_or_func_tail (LexState *ls, expdesc *v) {
423− for (;;) {
424− switch (ls->t.token) {
425− case '.': { /* var_or_func_tail -> '.' NAME */
426− next(ls);
427− luaK_tostack(ls, v, 1); /* `v' must be on stack */
428− luaK_kstr(ls, checkname(ls));
429− v->k = VINDEXED;
430− break;
431− }
432− case '[': { /* var_or_func_tail -> '[' exp1 ']' */
433− next(ls);
434− luaK_tostack(ls, v, 1); /* `v' must be on stack */
435− v->k = VINDEXED;
436− exp1(ls);
437− check(ls, ']');
459+static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
460+ if (cc->tostore == 0) return;
461+ if (cc->v.k == VCALL) {
462+ luaK_setcallreturns(fs, &cc->v, LUA_MULTRET);
463+ luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
464+ }
465+ else {
466+ if (cc->v.k != VVOID)
467+ luaK_exp2nextreg(fs, &cc->v);
468+ luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1);
469+ }
470+ fs->freereg = cc->t->info + 1; /* free registers */
471+}
472+
473+
474+static void listfield (LexState *ls, struct ConsControl *cc) {
475+ expr(ls, &cc->v);
476+ luaX_checklimit(ls, cc->na, MAXARG_Bx, "items in a constructor");
477+ cc->na++;
478+ cc->tostore++;
479+}
480+
481+
482+static void constructor (LexState *ls, expdesc *t) {
483+ /* constructor -> ?? */
484+ FuncState *fs = ls->fs;
485+ int line = ls->linenumber;
486+ int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
487+ struct ConsControl cc;
488+ cc.na = cc.nh = cc.tostore = 0;
489+ cc.t = t;
490+ init_exp(t, VRELOCABLE, pc);
491+ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
492+ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
493+ check(ls, '{');
494+ do {
495+ lua_assert(cc.v.k == VVOID || cc.tostore > 0);
496+ testnext(ls, ';'); /* compatibility only */
497+ if (ls->t.token == '}') break;
498+ closelistfield(fs, &cc);
499+ switch(ls->t.token) {
500+ case TK_NAME: { /* may be listfields or recfields */
501+ lookahead(ls);
502+ if (ls->lookahead.token != '=') /* expression? */
503+ listfield(ls, &cc);
504+ else
505+ recfield(ls, &cc);
438506 break;
439507 }
440− case ':': { /* var_or_func_tail -> ':' NAME funcargs */
441− int name;
442− next(ls);
443− name = checkname(ls);
444− luaK_tostack(ls, v, 1); /* `v' must be on stack */
445− luaK_code1(ls->fs, OP_PUSHSELF, name);
446− funcargs(ls, 1);
447− v->k = VEXP;
448− v->u.l.t = v->u.l.f = NO_JUMP;
508+ case '[': { /* constructor_item -> recfield */
509+ recfield(ls, &cc);
449510 break;
450511 }
451− case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */
452− luaK_tostack(ls, v, 1); /* `v' must be on stack */
453− funcargs(ls, 0);
454− v->k = VEXP;
455− v->u.l.t = v->u.l.f = NO_JUMP;
512+ default: { /* constructor_part -> listfield */
513+ listfield(ls, &cc);
456514 break;
457515 }
458− default: return; /* should be follow... */
459516 }
460− }
461−}
462−
463−
464−static void var_or_func (LexState *ls, expdesc *v) {
465− /* var_or_func -> ['%'] NAME var_or_func_tail */
466− if (optional(ls, '%')) { /* upvalue? */
467− pushupvalue(ls, str_checkname(ls));
468− v->k = VEXP;
469− v->u.l.t = v->u.l.f = NO_JUMP;
470− }
471− else /* variable name */
472− singlevar(ls, str_checkname(ls), v);
473− var_or_func_tail(ls, v);
517+ } while (testnext(ls, ',') || testnext(ls, ';'));
518+ check_match(ls, '}', '{', line);
519+ lastlistfield(fs, &cc);
520+ SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
521+ SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
474522 }
475523
524+/* }====================================================================== */
476525
477526
478−/*
479−** {======================================================================
480−** Rules for Constructors
481−** =======================================================================
482−*/
483−
484527
485−static void recfield (LexState *ls) {
486− /* recfield -> (NAME | '['exp1']') = exp1 */
487− switch (ls->t.token) {
488− case TK_NAME: {
489− luaK_kstr(ls, checkname(ls));
490− break;
491− }
492− case '[': {
493− next(ls);
494− exp1(ls);
495− check(ls, ']');
496− break;
497− }
498− default: luaK_error(ls, "<name> or `[' expected");
528+static void parlist (LexState *ls) {
529+ /* parlist -> [ param { `,' param } ] */
530+ int nparams = 0;
531+ int dots = 0;
532+ if (ls->t.token != ')') { /* is `parlist' not empty? */
533+ do {
534+ switch (ls->t.token) {
535+ case TK_DOTS: dots = 1; next(ls); break;
536+ case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
537+ default: luaX_syntaxerror(ls, "<name> or `...' expected");
538+ }
539+ } while (!dots && testnext(ls, ','));
499540 }
500− check(ls, '=');
501− exp1(ls);
541+ code_params(ls, nparams, dots);
502542 }
503543
504544
505−static int recfields (LexState *ls) {
506− /* recfields -> recfield { ',' recfield } [','] */
507− FuncState *fs = ls->fs;
508− int n = 1; /* at least one element */
509− recfield(ls);
510− while (ls->t.token == ',') {
511− next(ls);
512− if (ls->t.token == ';' || ls->t.token == '}')
513− break;
514− recfield(ls);
515− n++;
516− if (n%RFIELDS_PER_FLUSH == 0)
517− luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH);
518− }
519− luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH);
520− return n;
545+static void body (LexState *ls, expdesc *e, int needself, int line) {
546+ /* body -> `(' parlist `)' chunk END */
547+ FuncState new_fs;
548+ open_func(ls, &new_fs);
549+ new_fs.f->lineDefined = line;
550+ check(ls, '(');
551+ if (needself)
552+ create_local(ls, "self");
553+ parlist(ls);
554+ check(ls, ')');
555+ chunk(ls);
556+ check_match(ls, TK_END, TK_FUNCTION, line);
557+ close_func(ls);
558+ pushclosure(ls, &new_fs, e);
521559 }
522560
523561
524−static int listfields (LexState *ls) {
525− /* listfields -> exp1 { ',' exp1 } [','] */
526− FuncState *fs = ls->fs;
527− int n = 1; /* at least one element */
528− exp1(ls);
529− while (ls->t.token == ',') {
530− next(ls);
531− if (ls->t.token == ';' || ls->t.token == '}')
532− break;
533− exp1(ls);
562+static int explist1 (LexState *ls, expdesc *v) {
563+ /* explist1 -> expr { `,' expr } */
564+ int n = 1; /* at least one expression */
565+ expr(ls, v);
566+ while (testnext(ls, ',')) {
567+ luaK_exp2nextreg(ls->fs, v);
568+ expr(ls, v);
534569 n++;
535− luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A,
536− "`item groups' in a list initializer");
537− if (n%LFIELDS_PER_FLUSH == 0)
538− luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
539570 }
540− luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
541571 return n;
542572 }
543573
544574
545−
546−static void constructor_part (LexState *ls, Constdesc *cd) {
575+static void funcargs (LexState *ls, expdesc *f) {
576+ FuncState *fs = ls->fs;
577+ expdesc args;
578+ int base, nparams;
579+ int line = ls->linenumber;
547580 switch (ls->t.token) {
548− case ';': case '}': { /* constructor_part -> empty */
549− cd->n = 0;
550− cd->k = ls->t.token;
581+ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
582+ if (line != ls->lastline)
583+ luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
584+ next(ls);
585+ if (ls->t.token == ')') /* arg list is empty? */
586+ args.k = VVOID;
587+ else {
588+ explist1(ls, &args);
589+ luaK_setcallreturns(fs, &args, LUA_MULTRET);
590+ }
591+ check_match(ls, ')', '(', line);
551592 break;
552593 }
553− case TK_NAME: { /* may be listfields or recfields */
554− lookahead(ls);
555− if (ls->lookahead.token != '=') /* expression? */
556− goto case_default;
557− /* else go through to recfields */
558− }
559− case '[': { /* constructor_part -> recfields */
560− cd->n = recfields(ls);
561− cd->k = 1; /* record */
594+ case '{': { /* funcargs -> constructor */
595+ constructor(ls, &args);
562596 break;
563597 }
564− default: { /* constructor_part -> listfields */
565− case_default:
566− cd->n = listfields(ls);
567− cd->k = 0; /* list */
598+ case TK_STRING: { /* funcargs -> STRING */
599+ codestring(ls, &args, ls->t.seminfo.ts);
600+ next(ls); /* must use `seminfo' before `next' */
568601 break;
569602 }
603+ default: {
604+ luaX_syntaxerror(ls, "function arguments expected");
605+ return;
606+ }
570607 }
571−}
572−
573−
574−static void constructor (LexState *ls) {
575− /* constructor -> '{' constructor_part [';' constructor_part] '}' */
576− FuncState *fs = ls->fs;
577− int line = ls->linenumber;
578− int pc = luaK_code1(fs, OP_CREATETABLE, 0);
579− int nelems;
580− Constdesc cd;
581− check(ls, '{');
582− constructor_part(ls, &cd);
583− nelems = cd.n;
584− if (optional(ls, ';')) {
585− Constdesc other_cd;
586− constructor_part(ls, &other_cd);
587− check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax");
588− nelems += other_cd.n;
608+ lua_assert(f->k == VNONRELOC);
609+ base = f->info; /* base register for call */
610+ if (args.k == VCALL)
611+ nparams = LUA_MULTRET; /* open call */
612+ else {
613+ if (args.k != VVOID)
614+ luaK_exp2nextreg(fs, &args); /* close last argument */
615+ nparams = fs->freereg - (base+1);
589616 }
590− check_match(ls, '}', '{', line);
591− luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor");
592− SETARG_U(fs->f->code[pc], nelems); /* set initial table size */
617+ init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
618+ luaK_fixline(fs, line);
619+ fs->freereg = base+1; /* call remove function and arguments and leaves
620+ (unless changed) one result */
593621 }
594622
595−/* }====================================================================== */
596−
597623
598624
599625
@@ -604,58 +630,121 @@ static void constructor (LexState *ls) { · 4 unmodified lines
604630 */
605631
606632
607−static void simpleexp (LexState *ls, expdesc *v) {
608− FuncState *fs = ls->fs;
633+static void prefixexp (LexState *ls, expdesc *v) {
634+ /* prefixexp -> NAME | '(' expr ')' */
609635 switch (ls->t.token) {
610− case TK_NUMBER: { /* simpleexp -> NUMBER */
611− Number r = ls->t.seminfo.r;
636+ case '(': {
637+ int line = ls->linenumber;
612638 next(ls);
613− luaK_number(fs, r);
639+ expr(ls, v);
640+ check_match(ls, ')', '(', line);
641+ luaK_dischargevars(ls->fs, v);
642+ return;
643+ }
644+ case TK_NAME: {
645+ singlevar(ls, v, 1);
646+ return;
647+ }
648+#ifdef LUA_COMPATUPSYNTAX
649+ case '%': { /* for compatibility only */
650+ TString *varname;
651+ int line = ls->linenumber;
652+ next(ls); /* skip `%' */
653+ varname = singlevar(ls, v, 1);
654+ if (v->k != VUPVAL)
655+ luaX_errorline(ls, "global upvalues are obsolete",
656+ getstr(varname), line);
657+ return;
658+ }
659+#endif
660+ default: {
661+ luaX_syntaxerror(ls, "unexpected symbol");
662+ return;
663+ }
664+ }
665+}
666+
667+
668+static void primaryexp (LexState *ls, expdesc *v) {
669+ /* primaryexp ->
670+ prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
671+ FuncState *fs = ls->fs;
672+ prefixexp(ls, v);
673+ for (;;) {
674+ switch (ls->t.token) {
675+ case '.': { /* field */
676+ luaY_field(ls, v);
677+ break;
678+ }
679+ case '[': { /* `[' exp1 `]' */
680+ expdesc key;
681+ luaK_exp2anyreg(fs, v);
682+ luaY_index(ls, &key);
683+ luaK_indexed(fs, v, &key);
684+ break;
685+ }
686+ case ':': { /* `:' NAME funcargs */
687+ expdesc key;
688+ next(ls);
689+ checkname(ls, &key);
690+ luaK_self(fs, v, &key);
691+ funcargs(ls, v);
692+ break;
693+ }
694+ case '(': case TK_STRING: case '{': { /* funcargs */
695+ luaK_exp2nextreg(fs, v);
696+ funcargs(ls, v);
697+ break;
698+ }
699+ default: return;
700+ }
701+ }
702+}
703+
704+
705+static void simpleexp (LexState *ls, expdesc *v) {
706+ /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body
707+ | primaryexp */
708+ switch (ls->t.token) {
709+ case TK_NUMBER: {
710+ init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r));
711+ next(ls); /* must use `seminfo' before `next' */
614712 break;
615713 }
616− case TK_STRING: { /* simpleexp -> STRING */
617− code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */
618− next(ls);
714+ case TK_STRING: {
715+ codestring(ls, v, ls->t.seminfo.ts);
716+ next(ls); /* must use `seminfo' before `next' */
619717 break;
620718 }
621− case TK_NIL: { /* simpleexp -> NIL */
622− luaK_adjuststack(fs, -1);
719+ case TK_NIL: {
720+ init_exp(v, VNIL, 0);
623721 next(ls);
624722 break;
625723 }
626− case '{': { /* simpleexp -> constructor */
627− constructor(ls);
724+ case TK_TRUE: {
725+ init_exp(v, VTRUE, 0);
726+ next(ls);
628727 break;
629728 }
630− case TK_FUNCTION: { /* simpleexp -> FUNCTION body */
729+ case TK_FALSE: {
730+ init_exp(v, VFALSE, 0);
631731 next(ls);
632− body(ls, 0, ls->linenumber);
633732 break;
634733 }
635− case '(': { /* simpleexp -> '(' expr ')' */
636− next(ls);
637− expr(ls, v);
638− check(ls, ')');
639− return;
734+ case '{': { /* constructor */
735+ constructor(ls, v);
736+ break;
640737 }
641− case TK_NAME: case '%': {
642− var_or_func(ls, v);
643− return;
738+ case TK_FUNCTION: {
739+ next(ls);
740+ body(ls, v, 0, ls->linenumber);
741+ break;
644742 }
645743 default: {
646− luaK_error(ls, "<expression> expected");
647− return;
744+ primaryexp(ls, v);
745+ break;
648746 }
649747 }
650− v->k = VEXP;
651− v->u.l.t = v->u.l.f = NO_JUMP;
652−}
653−
654−
655−static void exp1 (LexState *ls) {
656− expdesc v;
657− expr(ls, &v);
658− luaK_tostack(ls, &v, 1);
659748 }
660749
661750
@@ -690,17 +779,17 @@ static BinOpr getbinopr (int op) { · 28 unmodified lines
690779
691780
692781 static const struct {
693− char left; /* left priority for each binary operator */
694− char right; /* right priority */
782+ lu_byte left; /* left priority for each binary operator */
783+ lu_byte right; /* right priority */
695784 } priority[] = { /* ORDER OPR */
696− {5, 5}, {5, 5}, {6, 6}, {6, 6}, /* arithmetic */
697− {9, 8}, {4, 3}, /* power and concat (right associative) */
698− {2, 2}, {2, 2}, /* equality */
699− {2, 2}, {2, 2}, {2, 2}, {2, 2}, /* order */
700− {1, 1}, {1, 1} /* logical */
785+ {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */
786+ {10, 9}, {5, 4}, /* power and concat (right associative) */
787+ {3, 3}, {3, 3}, /* equality */
788+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
789+ {2, 2}, {1, 1} /* logical (and/or) */
701790 };
702791
703−#define UNARY_PRIORITY 7 /* priority for unary operators */
792+#define UNARY_PRIORITY 8 /* priority for unary operators */
704793
705794
706795 /*
@@ -709,25 +798,28 @@ static const struct { · 2 unmodified lines
709798 */
710799 static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
711800 BinOpr op;
712− UnOpr uop = getunopr(ls->t.token);
801+ UnOpr uop;
802+ enterlevel(ls);
803+ uop = getunopr(ls->t.token);
713804 if (uop != OPR_NOUNOPR) {
714805 next(ls);
715806 subexpr(ls, v, UNARY_PRIORITY);
716− luaK_prefix(ls, uop, v);
807+ luaK_prefix(ls->fs, uop, v);
717808 }
718809 else simpleexp(ls, v);
719810 /* expand while operators have priorities higher than `limit' */
720811 op = getbinopr(ls->t.token);
721− while (op != OPR_NOBINOPR && priority[op].left > limit) {
812+ while (op != OPR_NOBINOPR && cast(int, priority[op].left) > limit) {
722813 expdesc v2;
723814 BinOpr nextop;
724815 next(ls);
725− luaK_infix(ls, op, v);
816+ luaK_infix(ls->fs, op, v);
726817 /* read sub-expression with higher priority */
727− nextop = subexpr(ls, &v2, priority[op].right);
728− luaK_posfix(ls, op, v, &v2);
818+ nextop = subexpr(ls, &v2, cast(int, priority[op].right));
819+ luaK_posfix(ls->fs, op, v, &v2);
729820 op = nextop;
730821 }
822+ leavelevel(ls);
731823 return op; /* return first untreated operator */
732824 }
733825
@@ -739,6 +831,7 @@ static void expr (LexState *ls, expdesc *v) { · 5 unmodified lines
739831 /* }==================================================================== */
740832
741833
834+
742835 /*
743836 ** {======================================================================
744837 ** Rules for Statements
@@ -759,61 +852,151 @@ static int block_follow (int token) { · 14 unmodified lines
759852 static void block (LexState *ls) {
760853 /* block -> chunk */
761854 FuncState *fs = ls->fs;
762− int nactloc = fs->nactloc;
855+ BlockCnt bl;
856+ enterblock(fs, &bl, 0);
763857 chunk(ls);
764− luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */
765− removelocalvars(ls, fs->nactloc - nactloc);
858+ lua_assert(bl.breaklist == NO_JUMP);
859+ leaveblock(fs);
766860 }
767861
768862
769−static int assignment (LexState *ls, expdesc *v, int nvars) {
770− int left = 0; /* number of values left in the stack after assignment */
771− luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment");
772− if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */
773− expdesc nv;
774− next(ls);
775− var_or_func(ls, &nv);
776− check_condition(ls, (nv.k != VEXP), "syntax error");
777− left = assignment(ls, &nv, nvars+1);
863+/*
864+** structure to chain all variables in the left-hand side of an
865+** assignment
866+*/
867+struct LHS_assign {
868+ struct LHS_assign *prev;
869+ expdesc v; /* variable (global, local, upvalue, or indexed) */
870+};
871+
872+
873+/*
874+** check whether, in an assignment to a local variable, the local variable
875+** is needed in a previous assignment (to a table). If so, save original
876+** local value in a safe place and use this safe copy in the previous
877+** assignment.
878+*/
879+static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
880+ FuncState *fs = ls->fs;
881+ int extra = fs->freereg; /* eventual position to save local variable */
882+ int conflict = 0;
883+ for (; lh; lh = lh->prev) {
884+ if (lh->v.k == VINDEXED) {
885+ if (lh->v.info == v->info) { /* conflict? */
886+ conflict = 1;
887+ lh->v.info = extra; /* previous assignment will use safe copy */
888+ }
889+ if (lh->v.aux == v->info) { /* conflict? */
890+ conflict = 1;
891+ lh->v.aux = extra; /* previous assignment will use safe copy */
892+ }
893+ }
894+ }
895+ if (conflict) {
896+ luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */
897+ luaK_reserveregs(fs, 1);
778898 }
779− else { /* assignment -> '=' explist1 */
899+}
900+
901+
902+static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
903+ expdesc e;
904+ check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
905+ "syntax error");
906+ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
907+ struct LHS_assign nv;
908+ nv.prev = lh;
909+ primaryexp(ls, &nv.v);
910+ if (nv.v.k == VLOCAL)
911+ check_conflict(ls, lh, &nv.v);
912+ assignment(ls, &nv, nvars+1);
913+ }
914+ else { /* assignment -> `=' explist1 */
780915 int nexps;
781916 check(ls, '=');
782− nexps = explist1(ls);
783− adjust_mult_assign(ls, nvars, nexps);
784− }
785− if (v->k != VINDEXED)
786− luaK_storevar(ls, v);
787− else { /* there may be garbage between table-index and value */
788− luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1);
789− left += 2;
917+ nexps = explist1(ls, &e);
918+ if (nexps != nvars) {
919+ adjust_assign(ls, nvars, nexps, &e);
920+ if (nexps > nvars)
921+ ls->fs->freereg -= nexps - nvars; /* remove extra values */
922+ }
923+ else {
924+ luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */
925+ luaK_storevar(ls->fs, &lh->v, &e);
926+ return; /* avoid default */
927+ }
790928 }
791− return left;
929+ init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
930+ luaK_storevar(ls->fs, &lh->v, &e);
792931 }
793932
794933
795934 static void cond (LexState *ls, expdesc *v) {
796935 /* cond -> exp */
797936 expr(ls, v); /* read condition */
798− luaK_goiftrue(ls->fs, v, 0);
937+ if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */
938+ luaK_goiftrue(ls->fs, v);
939+ luaK_patchtohere(ls->fs, v->t);
799940 }
800941
801942
943+/*
944+** The while statement optimizes its code by coding the condition
945+** after its body (and thus avoiding one jump in the loop).
946+*/
947+
948+/*
949+** maximum size of expressions for optimizing `while' code
950+*/
951+#ifndef MAXEXPWHILE
952+#define MAXEXPWHILE 100
953+#endif
954+
955+/*
956+** the call `luaK_goiffalse' may grow the size of an expression by
957+** at most this:
958+*/
959+#define EXTRAEXP 5
960+
802961 static void whilestat (LexState *ls, int line) {
803962 /* whilestat -> WHILE cond DO block END */
963+ Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
964+ int lineexp;
965+ int i;
966+ int sizeexp;
804967 FuncState *fs = ls->fs;
805− int while_init = luaK_getlabel(fs);
968+ int whileinit, blockinit, expinit;
806969 expdesc v;
807− Breaklabel bl;
808− enterbreak(fs, &bl);
809− next(ls);
810− cond(ls, &v);
970+ BlockCnt bl;
971+ next(ls); /* skip WHILE */
972+ whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */
973+ expinit = luaK_getlabel(fs);
974+ expr(ls, &v); /* parse condition */
975+ if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */
976+ lineexp = ls->linenumber;
977+ luaK_goiffalse(fs, &v);
978+ luaK_concat(fs, &v.f, fs->jpc);
979+ fs->jpc = NO_JUMP;
980+ sizeexp = fs->pc - expinit; /* size of expression code */
981+ if (sizeexp > MAXEXPWHILE)
982+ luaX_syntaxerror(ls, "`while' condition too complex");
983+ for (i = 0; i < sizeexp; i++) /* save `exp' code */
984+ codeexp[i] = fs->f->code[expinit + i];
985+ fs->pc = expinit; /* remove `exp' code */
986+ enterblock(fs, &bl, 1);
811987 check(ls, TK_DO);
988+ blockinit = luaK_getlabel(fs);
812989 block(ls);
813− luaK_patchlist(fs, luaK_jump(fs), while_init);
814− luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
990+ luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */
991+ /* move `exp' back to code */
992+ if (v.t != NO_JUMP) v.t += fs->pc - expinit;
993+ if (v.f != NO_JUMP) v.f += fs->pc - expinit;
994+ for (i=0; i<sizeexp; i++)
995+ luaK_code(fs, codeexp[i], lineexp);
815996 check_match(ls, TK_END, TK_WHILE, line);
816− leavebreak(fs, &bl);
997+ leaveblock(fs);
998+ luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */
999+ luaK_patchtohere(fs, v.f); /* false conditions finish the loop */
8171000 }
8181001
8191002
@@ -822,64 +1005,86 @@ static void repeatstat (LexState *ls, int line) { · 2 unmodified lines
8221005 FuncState *fs = ls->fs;
8231006 int repeat_init = luaK_getlabel(fs);
8241007 expdesc v;
825− Breaklabel bl;
826− enterbreak(fs, &bl);
1008+ BlockCnt bl;
1009+ enterblock(fs, &bl, 1);
8271010 next(ls);
8281011 block(ls);
8291012 check_match(ls, TK_UNTIL, TK_REPEAT, line);
8301013 cond(ls, &v);
831− luaK_patchlist(fs, v.u.l.f, repeat_init);
832− leavebreak(fs, &bl);
1014+ luaK_patchlist(fs, v.f, repeat_init);
1015+ leaveblock(fs);
8331016 }
8341017
8351018
836−static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
837− /* forbody -> DO block END */
1019+static int exp1 (LexState *ls) {
1020+ expdesc e;
1021+ int k;
1022+ expr(ls, &e);
1023+ k = e.k;
1024+ luaK_exp2nextreg(ls->fs, &e);
1025+ return k;
1026+}
1027+
1028+
1029+static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1030+ BlockCnt bl;
8381031 FuncState *fs = ls->fs;
839− int prep = luaK_code1(fs, prepfor, NO_JUMP);
840− int blockinit = luaK_getlabel(fs);
1032+ int prep, endfor;
1033+ adjustlocalvars(ls, nvars); /* scope for all variables */
8411034 check(ls, TK_DO);
842− adjustlocalvars(ls, nvar); /* scope for control variables */
1035+ enterblock(fs, &bl, 1); /* loop block */
1036+ prep = luaK_getlabel(fs);
8431037 block(ls);
844− luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
845− luaK_patchlist(fs, prep, luaK_getlabel(fs));
846− removelocalvars(ls, nvar);
1038+ luaK_patchtohere(fs, prep-1);
1039+ endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
1040+ luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3);
1041+ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
1042+ luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep);
1043+ leaveblock(fs);
8471044 }
8481045
8491046
850−static void fornum (LexState *ls, TString *varname) {
851− /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1047+static void fornum (LexState *ls, TString *varname, int line) {
1048+ /* fornum -> NAME = exp1,exp1[,exp1] DO body */
8521049 FuncState *fs = ls->fs;
1050+ int base = fs->freereg;
1051+ new_localvar(ls, varname, 0);
1052+ new_localvarstr(ls, "(for limit)", 1);
1053+ new_localvarstr(ls, "(for step)", 2);
8531054 check(ls, '=');
8541055 exp1(ls); /* initial value */
8551056 check(ls, ',');
8561057 exp1(ls); /* limit */
857− if (optional(ls, ','))
1058+ if (testnext(ls, ','))
8581059 exp1(ls); /* optional step */
859− else
860− luaK_code1(fs, OP_PUSHINT, 1); /* default step */
861− new_localvar(ls, varname, 0);
862− new_localvarstr(ls, "(limit)", 1);
863− new_localvarstr(ls, "(step)", 2);
864− forbody(ls, 3, OP_FORPREP, OP_FORLOOP);
1060+ else { /* default step = 1 */
1061+ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1062+ luaK_reserveregs(fs, 1);
1063+ }
1064+ luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
1065+ luaK_jump(fs);
1066+ forbody(ls, base, line, 3, 1);
8651067 }
8661068
8671069
8681070 static void forlist (LexState *ls, TString *indexname) {
869− /* forlist -> NAME,NAME IN exp1 forbody */
870− TString *valname;
871− check(ls, ',');
872− valname = str_checkname(ls);
873− /* next test is dirty, but avoids `in' being a reserved word */
874− check_condition(ls,
875− (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")),
876− "`in' expected");
877− next(ls); /* skip `in' */
878− exp1(ls); /* table */
879− new_localvarstr(ls, "(table)", 0);
880− new_localvar(ls, indexname, 1);
881− new_localvar(ls, valname, 2);
882− forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP);
1071+ /* forlist -> NAME {,NAME} IN explist1 DO body */
1072+ FuncState *fs = ls->fs;
1073+ expdesc e;
1074+ int nvars = 0;
1075+ int line;
1076+ int base = fs->freereg;
1077+ new_localvarstr(ls, "(for generator)", nvars++);
1078+ new_localvarstr(ls, "(for state)", nvars++);
1079+ new_localvar(ls, indexname, nvars++);
1080+ while (testnext(ls, ','))
1081+ new_localvar(ls, str_checkname(ls), nvars++);
1082+ check(ls, TK_IN);
1083+ line = ls->linenumber;
1084+ adjust_assign(ls, nvars, explist1(ls, &e), &e);
1085+ luaK_checkstack(fs, 3); /* extra space to call generator */
1086+ luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP);
1087+ forbody(ls, base, line, nvars, 0);
8831088 }
8841089
8851090
@@ -887,17 +1092,17 @@ static void forstat (LexState *ls, int line) { · 1 unmodified line
8871092 /* forstat -> fornum | forlist */
8881093 FuncState *fs = ls->fs;
8891094 TString *varname;
890− Breaklabel bl;
891− enterbreak(fs, &bl);
1095+ BlockCnt bl;
1096+ enterblock(fs, &bl, 0); /* block to control variable scope */
8921097 next(ls); /* skip `for' */
8931098 varname = str_checkname(ls); /* first variable name */
8941099 switch (ls->t.token) {
895− case '=': fornum(ls, varname); break;
896− case ',': forlist(ls, varname); break;
897− default: luaK_error(ls, "`=' or `,' expected");
1100+ case '=': fornum(ls, varname, line); break;
1101+ case ',': case TK_IN: forlist(ls, varname); break;
1102+ default: luaX_syntaxerror(ls, "`=' or `in' expected");
8981103 }
8991104 check_match(ls, TK_END, TK_FOR, line);
900− leavebreak(fs, &bl);
1105+ leaveblock(fs);
9011106 }
9021107
9031108
@@ -918,49 +1123,60 @@ static void ifstat (LexState *ls, int line) { · 14 unmodified lines
9181123 test_then_block(ls, &v); /* IF cond THEN block */
9191124 while (ls->t.token == TK_ELSEIF) {
9201125 luaK_concat(fs, &escapelist, luaK_jump(fs));
921− luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
1126+ luaK_patchtohere(fs, v.f);
9221127 test_then_block(ls, &v); /* ELSEIF cond THEN block */
9231128 }
9241129 if (ls->t.token == TK_ELSE) {
9251130 luaK_concat(fs, &escapelist, luaK_jump(fs));
926− luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
927− next(ls); /* skip ELSE */
1131+ luaK_patchtohere(fs, v.f);
1132+ next(ls); /* skip ELSE (after patch, for correct line info) */
9281133 block(ls); /* `else' part */
9291134 }
9301135 else
931− luaK_concat(fs, &escapelist, v.u.l.f);
932− luaK_patchlist(fs, escapelist, luaK_getlabel(fs));
1136+ luaK_concat(fs, &escapelist, v.f);
1137+ luaK_patchtohere(fs, escapelist);
9331138 check_match(ls, TK_END, TK_IF, line);
9341139 }
9351140
9361141
1142+static void localfunc (LexState *ls) {
1143+ expdesc v, b;
1144+ new_localvar(ls, str_checkname(ls), 0);
1145+ init_exp(&v, VLOCAL, ls->fs->freereg++);
1146+ adjustlocalvars(ls, 1);
1147+ body(ls, &b, 0, ls->linenumber);
1148+ luaK_storevar(ls->fs, &v, &b);
1149+}
1150+
1151+
9371152 static void localstat (LexState *ls) {
938− /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */
1153+ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
9391154 int nvars = 0;
9401155 int nexps;
1156+ expdesc e;
9411157 do {
942− next(ls); /* skip LOCAL or ',' */
9431158 new_localvar(ls, str_checkname(ls), nvars++);
944− } while (ls->t.token == ',');
945− if (optional(ls, '='))
946− nexps = explist1(ls);
947− else
1159+ } while (testnext(ls, ','));
1160+ if (testnext(ls, '='))
1161+ nexps = explist1(ls, &e);
1162+ else {
1163+ e.k = VVOID;
9481164 nexps = 0;
949− adjust_mult_assign(ls, nvars, nexps);
1165+ }
1166+ adjust_assign(ls, nvars, nexps, &e);
9501167 adjustlocalvars(ls, nvars);
9511168 }
9521169
9531170
9541171 static int funcname (LexState *ls, expdesc *v) {
955− /* funcname -> NAME [':' NAME | '.' NAME] */
1172+ /* funcname -> NAME {field} [`:' NAME] */
9561173 int needself = 0;
957− singlevar(ls, str_checkname(ls), v);
958− if (ls->t.token == ':' || ls->t.token == '.') {
959− needself = (ls->t.token == ':');
960− next(ls);
961− luaK_tostack(ls, v, 1);
962− luaK_kstr(ls, checkname(ls));
963− v->k = VINDEXED;
1174+ singlevar(ls, v, 1);
1175+ while (ls->t.token == '.')
1176+ luaY_field(ls, v);
1177+ if (ls->t.token == ':') {
1178+ needself = 1;
1179+ luaY_field(ls, v);
9641180 }
9651181 return needself;
9661182 }
@@ -969,26 +1185,26 @@ static int funcname (LexState *ls, expdesc *v) { · 2 unmodified lines
9691185 static void funcstat (LexState *ls, int line) {
9701186 /* funcstat -> FUNCTION funcname body */
9711187 int needself;
972− expdesc v;
1188+ expdesc v, b;
9731189 next(ls); /* skip FUNCTION */
9741190 needself = funcname(ls, &v);
975− body(ls, needself, line);
976− luaK_storevar(ls, &v);
1191+ body(ls, &b, needself, line);
1192+ luaK_storevar(ls->fs, &v, &b);
1193+ luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
9771194 }
9781195
9791196
980−static void namestat (LexState *ls) {
981− /* stat -> func | ['%'] NAME assignment */
1197+static void exprstat (LexState *ls) {
1198+ /* stat -> func | assignment */
9821199 FuncState *fs = ls->fs;
983− expdesc v;
984− var_or_func(ls, &v);
985− if (v.k == VEXP) { /* stat -> func */
986− check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */
987− luaK_setcallreturns(fs, 0); /* call statement uses no results */
1200+ struct LHS_assign v;
1201+ primaryexp(ls, &v.v);
1202+ if (v.v.k == VCALL) { /* stat -> func */
1203+ luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */
9881204 }
989− else { /* stat -> ['%'] NAME assignment */
990− int left = assignment(ls, &v, 1);
991− luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */
1205+ else { /* stat -> assignment */
1206+ v.prev = NULL;
1207+ assignment(ls, &v, 1);
9921208 }
9931209 }
9941210
@@ -996,30 +1212,55 @@ static void namestat (LexState *ls) { · 1 unmodified line
9961212 static void retstat (LexState *ls) {
9971213 /* stat -> RETURN explist */
9981214 FuncState *fs = ls->fs;
1215+ expdesc e;
1216+ int first, nret; /* registers with returned values */
9991217 next(ls); /* skip RETURN */
1000− if (!block_follow(ls->t.token) && ls->t.token != ';')
1001− explist1(ls); /* optional return values */
1002− luaK_code1(fs, OP_RETURN, ls->fs->nactloc);
1003− fs->stacklevel = fs->nactloc; /* removes all temp values */
1218+ if (block_follow(ls->t.token) || ls->t.token == ';')
1219+ first = nret = 0; /* return no values */
1220+ else {
1221+ nret = explist1(ls, &e); /* optional return values */
1222+ if (e.k == VCALL) {
1223+ luaK_setcallreturns(fs, &e, LUA_MULTRET);
1224+ if (nret == 1) { /* tail call? */
1225+ SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1226+ lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1227+ }
1228+ first = fs->nactvar;
1229+ nret = LUA_MULTRET; /* return all values */
1230+ }
1231+ else {
1232+ if (nret == 1) /* only one single value? */
1233+ first = luaK_exp2anyreg(fs, &e);
1234+ else {
1235+ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1236+ first = fs->nactvar; /* return all `active' values */
1237+ lua_assert(nret == fs->freereg - first);
1238+ }
1239+ }
1240+ }
1241+ luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
10041242 }
10051243
10061244
10071245 static void breakstat (LexState *ls) {
10081246 /* stat -> BREAK [NAME] */
10091247 FuncState *fs = ls->fs;
1010− int currentlevel = fs->stacklevel;
1011− Breaklabel *bl = fs->bl;
1012− if (!bl)
1013− luaK_error(ls, "no loop to break");
1248+ BlockCnt *bl = fs->bl;
1249+ int upval = 0;
10141250 next(ls); /* skip BREAK */
1015− luaK_adjuststack(fs, currentlevel - bl->stacklevel);
1251+ while (bl && !bl->isbreakable) {
1252+ upval |= bl->upval;
1253+ bl = bl->previous;
1254+ }
1255+ if (!bl)
1256+ luaX_syntaxerror(ls, "no loop to break");
1257+ if (upval)
1258+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
10161259 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1017− /* correct stack for compiler and symbolic execution */
1018− luaK_adjuststack(fs, bl->stacklevel - currentlevel);
10191260 }
10201261
10211262
1022−static int stat (LexState *ls) {
1263+static int statement (LexState *ls) {
10231264 int line = ls->linenumber; /* may be needed for error messages */
10241265 switch (ls->t.token) {
10251266 case TK_IF: { /* stat -> ifstat */
@@ -1044,16 +1285,16 @@ static int stat (LexState *ls) { · 18 unmodified lines
10441285 repeatstat(ls, line);
10451286 return 0;
10461287 }
1047− case TK_FUNCTION: { /* stat -> funcstat */
1048− funcstat(ls, line);
1288+ case TK_FUNCTION: {
1289+ funcstat(ls, line); /* stat -> funcstat */
10491290 return 0;
10501291 }
10511292 case TK_LOCAL: { /* stat -> localstat */
1052− localstat(ls);
1053− return 0;
1054− }
1055− case TK_NAME: case '%': { /* stat -> namestat */
1056− namestat(ls);
1293+ next(ls); /* skip LOCAL */
1294+ if (testnext(ls, TK_FUNCTION)) /* local function? */
1295+ localfunc(ls);
1296+ else
1297+ localstat(ls);
10571298 return 0;
10581299 }
10591300 case TK_RETURN: { /* stat -> retstat */
@@ -1065,60 +1306,24 @@ static int stat (LexState *ls) { · 5 unmodified lines
10651306 return 1; /* must be last statement */
10661307 }
10671308 default: {
1068− luaK_error(ls, "<statement> expected");
1309+ exprstat(ls);
10691310 return 0; /* to avoid warnings */
10701311 }
10711312 }
10721313 }
10731314
10741315
1075−static void parlist (LexState *ls) {
1076− /* parlist -> [ param { ',' param } ] */
1077− int nparams = 0;
1078− int dots = 0;
1079− if (ls->t.token != ')') { /* is `parlist' not empty? */
1080− do {
1081− switch (ls->t.token) {
1082− case TK_DOTS: next(ls); dots = 1; break;
1083− case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
1084− default: luaK_error(ls, "<name> or `...' expected");
1085− }
1086− } while (!dots && optional(ls, ','));
1087− }
1088− code_params(ls, nparams, dots);
1089−}
1090−
1091−
1092−static void body (LexState *ls, int needself, int line) {
1093− /* body -> '(' parlist ')' chunk END */
1094− FuncState new_fs;
1095− open_func(ls, &new_fs);
1096− new_fs.f->lineDefined = line;
1097− check(ls, '(');
1098− if (needself) {
1099− new_localvarstr(ls, "self", 0);
1100− adjustlocalvars(ls, 1);
1101− }
1102− parlist(ls);
1103− check(ls, ')');
1104− chunk(ls);
1105− check_match(ls, TK_END, TK_FUNCTION, line);
1106− close_func(ls);
1107− pushclosure(ls, &new_fs);
1108−}
1109−
1110−
1111−/* }====================================================================== */
1112−
1113−
11141316 static void chunk (LexState *ls) {
1115− /* chunk -> { stat [';'] } */
1317+ /* chunk -> { stat [`;'] } */
11161318 int islast = 0;
1319+ enterlevel(ls);
11171320 while (!islast && !block_follow(ls->t.token)) {
1118− islast = stat(ls);
1119− optional(ls, ';');
1120− LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc,
1121− "stack size != # local vars");
1321+ islast = statement(ls);
1322+ testnext(ls, ';');
1323+ lua_assert(ls->fs->freereg >= ls->fs->nactvar);
1324+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
11221325 }
1326+ leavelevel(ls);
11231327 }
11241328
1329+/* }====================================================================== */
src/lparser.h+33−22
@@ -1,13 +1,15 @@
11 /*
2−** $Id: lparser.h,v 1.26 2000/10/09 13:47:46 roberto Exp $
3−** LL(1) Parser and code generator for Lua
2+** $Id: lparser.h,v 1.47 2003/02/11 10:46:24 roberto Exp $
3+** Lua Parser
44 ** See Copyright Notice in lua.h
55 */
66
77 #ifndef lparser_h
88 #define lparser_h
99
10+#include "llimits.h"
1011 #include "lobject.h"
12+#include "ltable.h"
1113 #include "lzio.h"
1214
1315
@@ -16,45 +18,54 @@ · 2 unmodified lines
1618 */
1719
1820 typedef enum {
19− VGLOBAL,
20− VLOCAL,
21− VINDEXED,
22− VEXP
21+ VVOID, /* no value */
22+ VNIL,
23+ VTRUE,
24+ VFALSE,
25+ VK, /* info = index of constant in `k' */
26+ VLOCAL, /* info = local register */
27+ VUPVAL, /* info = index of upvalue in `upvalues' */
28+ VGLOBAL, /* info = index of table; aux = index of global name in `k' */
29+ VINDEXED, /* info = table register; aux = index register (or `k') */
30+ VJMP, /* info = instruction pc */
31+ VRELOCABLE, /* info = instruction pc */
32+ VNONRELOC, /* info = result register */
33+ VCALL /* info = result register */
2334 } expkind;
2435
2536 typedef struct expdesc {
2637 expkind k;
27− union {
28− int index; /* VGLOBAL: `kstr' index of global name; VLOCAL: stack index */
29− struct {
30− int t; /* patch list of `exit when true' */
31− int f; /* patch list of `exit when false' */
32− } l;
33− } u;
38+ int info, aux;
39+ int t; /* patch list of `exit when true' */
40+ int f; /* patch list of `exit when false' */
3441 } expdesc;
3542
3643
44+struct BlockCnt; /* defined in lparser.c */
45+
3746
3847 /* state needed to generate code for a given function */
3948 typedef struct FuncState {
4049 Proto *f; /* current function header */
50+ Table *h; /* table to find (and reuse) elements in `k' */
4151 struct FuncState *prev; /* enclosing function */
4252 struct LexState *ls; /* lexical state */
4353 struct lua_State *L; /* copy of the Lua state */
44− int pc; /* next position to code */
54+ struct BlockCnt *bl; /* chain of current blocks */
55+ int pc; /* next position to code (equivalent to `ncode') */
4556 int lasttarget; /* `pc' of last `jump target' */
46− int jlt; /* list of jumps to `lasttarget' */
47− short stacklevel; /* number of values on activation register */
48− short nactloc; /* number of active local variables */
49− short nupvalues; /* number of upvalues */
50− int lastline; /* line where last `lineinfo' was generated */
51− struct Breaklabel *bl; /* chain of breakable blocks */
57+ int jpc; /* list of pending jumps to `pc' */
58+ int freereg; /* first free register */
59+ int nk; /* number of elements in `k' */
60+ int np; /* number of elements in `p' */
61+ int nlocvars; /* number of elements in `locvars' */
62+ int nactvar; /* number of active local variables */
5263 expdesc upvalues[MAXUPVALUES]; /* upvalues */
53− int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
64+ int actvar[MAXVARS]; /* declared-variable stack */
5465 } FuncState;
5566
5667
57−Proto *luaY_parser (lua_State *L, ZIO *z);
68+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff);
5869
5970
6071 #endif
src/lstate.c+174−75
@@ -1,15 +1,19 @@
11 /*
2−** $Id: lstate.c,v 1.48 2000/10/30 16:29:59 roberto Exp $
2+** $Id: lstate.c,v 1.123 2003/04/03 13:35:34 roberto Exp $
33 ** Global State
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <stdio.h>
8+#include <stdlib.h>
9+
10+#define lstate_c
911
1012 #include "lua.h"
1113
14+#include "ldebug.h"
1215 #include "ldo.h"
16+#include "lfunc.h"
1317 #include "lgc.h"
1418 #include "llex.h"
1519 #include "lmem.h"
@@ -19,103 +23,198 @@ · 3 unmodified lines
1923 #include "ltm.h"
2024
2125
22−#ifdef LUA_DEBUG
23−static lua_State *lua_state = NULL;
24−void luaB_opentests (lua_State *L);
26+/*
27+** macro to allow the inclusion of user information in Lua state
28+*/
29+#ifndef LUA_USERSTATE
30+#define EXTRASPACE 0
31+#else
32+union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
33+#define EXTRASPACE (sizeof(union UEXTRASPACE))
2534 #endif
2635
2736
37+
2838 /*
29−** built-in implementation for ERRORMESSAGE. In a "correct" environment
30−** ERRORMESSAGE should have an external definition, and so this function
31−** would not be used.
39+** you can change this function through the official API:
40+** call `lua_setpanicf'
3241 */
33−static int errormessage (lua_State *L) {
34− const char *s = lua_tostring(L, 1);
35− if (s == NULL) s = "(no message)";
36− fprintf(stderr, "error: %s\n", s);
42+static int default_panic (lua_State *L) {
43+ UNUSED(L);
3744 return 0;
3845 }
3946
4047
48+static lua_State *mallocstate (lua_State *L) {
49+ lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE);
50+ if (block == NULL) return NULL;
51+ else {
52+ block += EXTRASPACE;
53+ return cast(lua_State *, block);
54+ }
55+}
56+
57+
58+static void freestate (lua_State *L, lua_State *L1) {
59+ luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
60+ sizeof(lua_State) + EXTRASPACE);
61+}
62+
63+
64+static void stack_init (lua_State *L1, lua_State *L) {
65+ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
66+ L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
67+ L1->top = L1->stack;
68+ L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
69+ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
70+ L1->ci = L1->base_ci;
71+ L1->ci->state = CI_C; /* not a Lua function */
72+ setnilvalue(L1->top++); /* `function' entry for this `ci' */
73+ L1->base = L1->ci->base = L1->top;
74+ L1->ci->top = L1->top + LUA_MINSTACK;
75+ L1->size_ci = BASIC_CI_SIZE;
76+ L1->end_ci = L1->base_ci + L1->size_ci;
77+}
78+
79+
80+static void freestack (lua_State *L, lua_State *L1) {
81+ luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
82+ luaM_freearray(L, L1->stack, L1->stacksize, TObject);
83+}
84+
85+
4186 /*
4287 ** open parts that may cause memory-allocation errors
4388 */
4489 static void f_luaopen (lua_State *L, void *ud) {
45− int stacksize = *(int *)ud;
46− if (stacksize == 0)
47− stacksize = DEFAULT_STACK_SIZE;
48− else
49− stacksize += LUA_MINSTACK;
50− L->gt = luaH_new(L, 10); /* table of globals */
51− luaD_init(L, stacksize);
52− luaS_init(L);
53− luaX_init(L);
90+ /* create a new global state */
91+ global_State *g = luaM_new(NULL, global_State);
92+ UNUSED(ud);
93+ if (g == NULL) luaD_throw(L, LUA_ERRMEM);
94+ L->l_G = g;
95+ g->mainthread = L;
96+ g->GCthreshold = 0; /* mark it as unfinished state */
97+ g->strt.size = 0;
98+ g->strt.nuse = 0;
99+ g->strt.hash = NULL;
100+ setnilvalue(defaultmeta(L));
101+ setnilvalue(registry(L));
102+ luaZ_initbuffer(L, &g->buff);
103+ g->panic = default_panic;
104+ g->rootgc = NULL;
105+ g->rootudata = NULL;
106+ g->tmudata = NULL;
107+ setnilvalue(gkey(g->dummynode));
108+ setnilvalue(gval(g->dummynode));
109+ g->dummynode->next = NULL;
110+ g->nblocks = sizeof(lua_State) + sizeof(global_State);
111+ stack_init(L, L); /* init stack */
112+ /* create default meta table with a dummy table, and then close the loop */
113+ defaultmeta(L)->tt = LUA_TTABLE;
114+ sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
115+ hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
116+ sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
117+ sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
118+ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
54119 luaT_init(L);
55− lua_newtable(L);
56− lua_ref(L, 1); /* create registry */
57− lua_register(L, LUA_ERRORMESSAGE, errormessage);
58−#ifdef LUA_DEBUG
59− luaB_opentests(L);
60− if (lua_state == NULL) lua_state = L; /* keep first state to be opened */
61−#endif
62− LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
120+ luaX_init(L);
121+ luaS_fix(luaS_newliteral(L, MEMERRMSG));
122+ g->GCthreshold = 4*G(L)->nblocks;
63123 }
64124
65125
66−LUA_API lua_State *lua_open (int stacksize) {
67− lua_State *L = luaM_new(NULL, lua_State);
68− if (L == NULL) return NULL; /* memory allocation error */
126+static void preinit_state (lua_State *L) {
69127 L->stack = NULL;
70− L->strt.size = L->udt.size = 0;
71− L->strt.nuse = L->udt.nuse = 0;
72− L->strt.hash = NULL;
73− L->udt.hash = NULL;
74− L->Mbuffer = NULL;
75− L->Mbuffsize = 0;
76− L->rootproto = NULL;
77− L->rootcl = NULL;
78− L->roottable = NULL;
79− L->TMtable = NULL;
80− L->last_tag = -1;
81− L->refArray = NULL;
82− L->refSize = 0;
83− L->refFree = NONEXT;
84− L->nblocks = sizeof(lua_State);
85− L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */
86− L->callhook = NULL;
87− L->linehook = NULL;
88− L->allowhooks = 1;
128+ L->stacksize = 0;
89129 L->errorJmp = NULL;
90− if (luaD_runprotected(L, f_luaopen, &stacksize) != 0) {
91− /* memory allocation error: free partial state */
92− lua_close(L);
93− return NULL;
130+ L->hook = NULL;
131+ L->hookmask = L->hookinit = 0;
132+ L->basehookcount = 0;
133+ L->allowhook = 1;
134+ resethookcount(L);
135+ L->openupval = NULL;
136+ L->size_ci = 0;
137+ L->nCcalls = 0;
138+ L->base_ci = L->ci = NULL;
139+ L->errfunc = 0;
140+ setnilvalue(gt(L));
141+}
142+
143+
144+static void close_state (lua_State *L) {
145+ luaF_close(L, L->stack); /* close all upvalues for this thread */
146+ if (G(L)) { /* close global state */
147+ luaC_sweep(L, 1); /* collect all elements */
148+ lua_assert(G(L)->rootgc == NULL);
149+ lua_assert(G(L)->rootudata == NULL);
150+ luaS_freeall(L);
151+ luaZ_freebuffer(L, &G(L)->buff);
152+ }
153+ freestack(L, L);
154+ if (G(L)) {
155+ lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State));
156+ luaM_freelem(NULL, G(L));
157+ }
158+ freestate(NULL, L);
159+}
160+
161+
162+lua_State *luaE_newthread (lua_State *L) {
163+ lua_State *L1 = mallocstate(L);
164+ luaC_link(L, valtogco(L1), LUA_TTHREAD);
165+ preinit_state(L1);
166+ L1->l_G = L->l_G;
167+ stack_init(L1, L); /* init stack */
168+ setobj2n(gt(L1), gt(L)); /* share table of globals */
169+ return L1;
170+}
171+
172+
173+void luaE_freethread (lua_State *L, lua_State *L1) {
174+ luaF_close(L1, L1->stack); /* close all upvalues for this thread */
175+ lua_assert(L1->openupval == NULL);
176+ freestack(L, L1);
177+ freestate(L, L1);
178+}
179+
180+
181+LUA_API lua_State *lua_open (void) {
182+ lua_State *L = mallocstate(NULL);
183+ if (L) { /* allocation OK? */
184+ L->tt = LUA_TTHREAD;
185+ L->marked = 0;
186+ L->next = L->gclist = NULL;
187+ preinit_state(L);
188+ L->l_G = NULL;
189+ if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
190+ /* memory allocation error: free partial state */
191+ close_state(L);
192+ L = NULL;
193+ }
94194 }
95− L->GCthreshold = 2*L->nblocks;
195+ lua_userstateopen(L);
96196 return L;
97197 }
98198
99199
200+static void callallgcTM (lua_State *L, void *ud) {
201+ UNUSED(ud);
202+ luaC_callGCTM(L); /* call GC metamethods for all udata */
203+}
204+
205+
100206 LUA_API void lua_close (lua_State *L) {
101− LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack");
102− luaC_collect(L, 1); /* collect all elements */
103− LUA_ASSERT(L->rootproto == NULL, "list should be empty");
104− LUA_ASSERT(L->rootcl == NULL, "list should be empty");
105− LUA_ASSERT(L->roottable == NULL, "list should be empty");
106− luaS_freeall(L);
107− if (L->stack)
108− L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject);
109− luaM_free(L, L->stack);
110− L->nblocks -= (L->last_tag+1)*sizeof(struct TM);
111− luaM_free(L, L->TMtable);
112− L->nblocks -= (L->refSize)*sizeof(struct Ref);
113− luaM_free(L, L->refArray);
114− L->nblocks -= (L->Mbuffsize)*sizeof(char);
115− luaM_free(L, L->Mbuffer);
116− LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
117− luaM_free(L, L);
118− LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
119− LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
207+ lua_lock(L);
208+ L = G(L)->mainthread; /* only the main thread can be closed */
209+ luaF_close(L, L->stack); /* close all upvalues for this thread */
210+ luaC_separateudata(L); /* separate udata that have GC metamethods */
211+ L->errfunc = 0; /* no error function during GC metamethods */
212+ do { /* repeat until no more errors */
213+ L->ci = L->base_ci;
214+ L->base = L->top = L->ci->base;
215+ L->nCcalls = 0;
216+ } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
217+ lua_assert(G(L)->tmudata == NULL);
218+ close_state(L);
120219 }
121220
src/lstate.h+158−40
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstate.h,v 1.41 2000/10/05 13:00:17 roberto Exp $
2+** $Id: lstate.h,v 1.109 2003/02/27 11:52:30 roberto Exp $
33 ** Global State
44 ** See Copyright Notice in lua.h
55 */
@@ -7,71 +7,189 @@ · 1 unmodified line
77 #ifndef lstate_h
88 #define lstate_h
99
10−#include "lobject.h"
1110 #include "lua.h"
12−#include "luadebug.h"
13−
1411
15−
16−typedef TObject *StkId; /* index to stack elements */
12+#include "lobject.h"
13+#include "ltm.h"
14+#include "lzio.h"
1715
1816
1917 /*
20−** marks for Reference array
18+** macros for thread synchronization inside Lua core machine:
19+** all accesses to the global state and to global objects are synchronized.
20+** Because threads can read the stack of other threads
21+** (when running garbage collection),
22+** a thread must also synchronize any write-access to its own stack.
23+** Unsynchronized accesses are allowed only when reading its own stack,
24+** or when reading immutable fields from global objects
25+** (such as string values and udata values).
2126 */
22−#define NONEXT -1 /* to end the free list */
23−#define HOLD -2
24−#define COLLECTED -3
25−#define LOCK -4
27+#ifndef lua_lock
28+#define lua_lock(L) ((void) 0)
29+#endif
2630
31+#ifndef lua_unlock
32+#define lua_unlock(L) ((void) 0)
33+#endif
34+
35+
36+#ifndef lua_userstateopen
37+#define lua_userstateopen(l)
38+#endif
2739
28−struct Ref {
29− TObject o;
30− int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
31−};
3240
3341
3442 struct lua_longjmp; /* defined in ldo.c */
35−struct TM; /* defined in ltm.h */
43+
44+
45+/* default meta table (both for tables and udata) */
46+#define defaultmeta(L) (&G(L)->_defaultmeta)
47+
48+/* table of globals */
49+#define gt(L) (&L->_gt)
50+
51+/* registry */
52+#define registry(L) (&G(L)->_registry)
53+
54+
55+/* extra stack space to handle TM calls and some other extras */
56+#define EXTRA_STACK 5
57+
58+
59+#define BASIC_CI_SIZE 8
60+
61+#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
62+
3663
3764
3865 typedef struct stringtable {
66+ GCObject **hash;
67+ ls_nstr nuse; /* number of elements */
3968 int size;
40− lint32 nuse; /* number of elements */
41− TString **hash;
4269 } stringtable;
4370
4471
72+/*
73+** informations about a call
74+*/
75+typedef struct CallInfo {
76+ StkId base; /* base for called function */
77+ StkId top; /* top for this function */
78+ int state; /* bit fields; see below */
79+ union {
80+ struct { /* for Lua functions */
81+ const Instruction *savedpc;
82+ const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
83+ int tailcalls; /* number of tail calls lost under this entry */
84+ } l;
85+ struct { /* for C functions */
86+ int dummy; /* just to avoid an empty struct */
87+ } c;
88+ } u;
89+} CallInfo;
90+
91+
92+/*
93+** bit fields for `CallInfo.state'
94+*/
95+#define CI_C (1<<0) /* 1 if function is a C function */
96+/* 1 if (Lua) function has an active `luaV_execute' running it */
97+#define CI_HASFRAME (1<<1)
98+/* 1 if Lua function is calling another Lua function (and therefore its
99+ `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */
100+#define CI_CALLING (1<<2)
101+#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */
102+#define CI_YIELD (1<<4) /* 1 if thread is suspended */
103+
104+
105+#define ci_func(ci) (clvalue((ci)->base - 1))
106+
45107
108+/*
109+** `global state', shared by all threads of this state
110+*/
111+typedef struct global_State {
112+ stringtable strt; /* hash table for strings */
113+ GCObject *rootgc; /* list of (almost) all collectable objects */
114+ GCObject *rootudata; /* (separated) list of all userdata */
115+ GCObject *tmudata; /* list of userdata to be GC */
116+ Mbuffer buff; /* temporary buffer for string concatentation */
117+ lu_mem GCthreshold;
118+ lu_mem nblocks; /* number of `bytes' currently allocated */
119+ lua_CFunction panic; /* to be called in unprotected errors */
120+ TObject _registry;
121+ TObject _defaultmeta;
122+ struct lua_State *mainthread;
123+ Node dummynode[1]; /* common node array for all empty tables */
124+ TString *tmname[TM_N]; /* array with tag-method names */
125+} global_State;
126+
127+
128+/*
129+** `per thread' state
130+*/
46131 struct lua_State {
47− /* thread-specific state */
132+ CommonHeader;
48133 StkId top; /* first free slot in the stack */
49− StkId stack; /* stack base */
134+ StkId base; /* base of current function */
135+ global_State *l_G;
136+ CallInfo *ci; /* call info for current function */
50137 StkId stack_last; /* last free slot in the stack */
138+ StkId stack; /* stack base */
51139 int stacksize;
52− StkId Cbase; /* base for current C function */
140+ CallInfo *end_ci; /* points after end of ci array*/
141+ CallInfo *base_ci; /* array of CallInfo's */
142+ unsigned short size_ci; /* size of array `base_ci' */
143+ unsigned short nCcalls; /* number of nested C calls */
144+ lu_byte hookmask;
145+ lu_byte allowhook;
146+ lu_byte hookinit;
147+ int basehookcount;
148+ int hookcount;
149+ lua_Hook hook;
150+ TObject _gt; /* table of globals */
151+ GCObject *openupval; /* list of open upvalues in this stack */
152+ GCObject *gclist;
53153 struct lua_longjmp *errorJmp; /* current error recover point */
54− char *Mbuffer; /* global buffer */
55− size_t Mbuffsize; /* size of Mbuffer */
56− /* global state */
57− Proto *rootproto; /* list of all prototypes */
58− Closure *rootcl; /* list of all closures */
59− Hash *roottable; /* list of all tables */
60− stringtable strt; /* hash table for strings */
61− stringtable udt; /* hash table for udata */
62− Hash *gt; /* table for globals */
63− struct TM *TMtable; /* table for tag methods */
64− int last_tag; /* last used tag in TMtable */
65− struct Ref *refArray; /* locked objects */
66− int refSize; /* size of refArray */
67− int refFree; /* list of free positions in refArray */
68− unsigned long GCthreshold;
69− unsigned long nblocks; /* number of `bytes' currently allocated */
70− lua_Hook callhook;
71− lua_Hook linehook;
72− int allowhooks;
154+ ptrdiff_t errfunc; /* current error handling function (stack index) */
155+};
156+
157+
158+#define G(L) (L->l_G)
159+
160+
161+/*
162+** Union of all collectable objects
163+*/
164+union GCObject {
165+ GCheader gch;
166+ union TString ts;
167+ union Udata u;
168+ union Closure cl;
169+ struct Table h;
170+ struct Proto p;
171+ struct UpVal uv;
172+ struct lua_State th; /* thread */
73173 };
74174
75175
176+/* macros to convert a GCObject into a specific value */
177+#define gcotots(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
178+#define gcotou(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
179+#define gcotocl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
180+#define gcotoh(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
181+#define gcotop(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
182+#define gcotouv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
183+#define ngcotouv(o) \
184+ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
185+#define gcototh(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
186+
187+/* macro to convert any value into a GCObject */
188+#define valtogco(v) (cast(GCObject *, (v)))
189+
190+
191+lua_State *luaE_newthread (lua_State *L);
192+void luaE_freethread (lua_State *L, lua_State *L1);
193+
76194 #endif
77195
src/lstring.c+55−108
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstring.c,v 1.45a 2000/10/30 17:49:19 roberto Exp $
2+** $Id: lstring.c,v 1.78 2002/12/04 17:38:31 roberto Exp $
33 ** String table (keeps all strings handled by Lua)
44 ** See Copyright Notice in lua.h
55 */
@@ -7,6 +7,8 @@ · 1 unmodified line
77
88 #include <string.h>
99
10+#define lstring_c
11+
1012 #include "lua.h"
1113
1214 #include "lmem.h"
@@ -15,141 +17,86 @@ · 2 unmodified lines
1517 #include "lstring.h"
1618
1719
18−/*
19−** type equivalent to TString, but with maximum alignment requirements
20−*/
21−union L_UTString {
22− TString ts;
23− union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
24−};
25−
26−
27−
28−void luaS_init (lua_State *L) {
29− L->strt.hash = luaM_newvector(L, 1, TString *);
30− L->udt.hash = luaM_newvector(L, 1, TString *);
31− L->nblocks += 2*sizeof(TString *);
32− L->strt.size = L->udt.size = 1;
33− L->strt.nuse = L->udt.nuse = 0;
34− L->strt.hash[0] = L->udt.hash[0] = NULL;
35−}
36−
3720
3821 void luaS_freeall (lua_State *L) {
39− LUA_ASSERT(L->strt.nuse==0, "non-empty string table");
40− L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *);
41− luaM_free(L, L->strt.hash);
42− LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
43− luaM_free(L, L->udt.hash);
44−}
45−
46−
47−static unsigned long hash_s (const char *s, size_t l) {
48− unsigned long h = l; /* seed */
49− size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
50− for (; l>=step; l-=step)
51− h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
52− return h;
22+ lua_assert(G(L)->strt.nuse==0);
23+ luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
5324 }
5425
5526
56−void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
57− TString **newhash = luaM_newvector(L, newsize, TString *);
27+void luaS_resize (lua_State *L, int newsize) {
28+ GCObject **newhash = luaM_newvector(L, newsize, GCObject *);
29+ stringtable *tb = &G(L)->strt;
5830 int i;
5931 for (i=0; i<newsize; i++) newhash[i] = NULL;
6032 /* rehash */
6133 for (i=0; i<tb->size; i++) {
62− TString *p = tb->hash[i];
34+ GCObject *p = tb->hash[i];
6335 while (p) { /* for each node in the list */
64− TString *next = p->nexthash; /* save next */
65− unsigned long h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value);
66− int h1 = h&(newsize-1); /* new position */
67− LUA_ASSERT(h%newsize == (h&(newsize-1)),
68− "a&(x-1) == a%x, for x power of 2");
69− p->nexthash = newhash[h1]; /* chain it in new position */
36+ GCObject *next = p->gch.next; /* save next */
37+ lu_hash h = gcotots(p)->tsv.hash;
38+ int h1 = lmod(h, newsize); /* new position */
39+ lua_assert(cast(int, h%newsize) == lmod(h, newsize));
40+ p->gch.next = newhash[h1]; /* chain it */
7041 newhash[h1] = p;
7142 p = next;
7243 }
7344 }
74− luaM_free(L, tb->hash);
75− L->nblocks += (newsize - tb->size)*sizeof(TString *);
45+ luaM_freearray(L, tb->hash, tb->size, TString *);
7646 tb->size = newsize;
7747 tb->hash = newhash;
7848 }
7949
8050
81−static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) {
82− ts->nexthash = tb->hash[h]; /* chain new entry */
83− tb->hash[h] = ts;
51+static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) {
52+ TString *ts = cast(TString *, luaM_malloc(L, sizestring(l)));
53+ stringtable *tb;
54+ ts->tsv.len = l;
55+ ts->tsv.hash = h;
56+ ts->tsv.marked = 0;
57+ ts->tsv.tt = LUA_TSTRING;
58+ ts->tsv.reserved = 0;
59+ memcpy(ts+1, str, l*sizeof(char));
60+ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
61+ tb = &G(L)->strt;
62+ h = lmod(h, tb->size);
63+ ts->tsv.next = tb->hash[h]; /* chain new entry */
64+ tb->hash[h] = valtogco(ts);
8465 tb->nuse++;
85− if (tb->nuse > (lint32)tb->size && tb->size < MAX_INT/2) /* too crowded? */
86− luaS_resize(L, tb, tb->size*2);
87−}
88−
89−
90−
91−TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
92− unsigned long h = hash_s(str, l);
93− int h1 = h & (L->strt.size-1);
94− TString *ts;
95− for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) {
96− if (ts->len == l && (memcmp(str, ts->str, l) == 0))
97− return ts;
98− }
99− /* not found */
100− ts = (TString *)luaM_malloc(L, sizestring(l));
101− ts->marked = 0;
102− ts->nexthash = NULL;
103− ts->len = l;
104− ts->u.s.hash = h;
105− ts->u.s.constindex = 0;
106− memcpy(ts->str, str, l);
107− ts->str[l] = 0; /* ending 0 */
108− L->nblocks += sizestring(l);
109− newentry(L, &L->strt, ts, h1); /* insert it on table */
110− return ts;
111−}
112−
113−
114−TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
115− union L_UTString *uts = (union L_UTString *)luaM_malloc(L,
116− (lint32)sizeof(union L_UTString)+s);
117− TString *ts = &uts->ts;
118− ts->marked = 0;
119− ts->nexthash = NULL;
120− ts->len = s;
121− ts->u.d.tag = 0;
122− ts->u.d.value = (s > 0) ? uts+1 : udata;
123− L->nblocks += sizestring(s);
124− /* insert it on table */
125− newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1));
66+ if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2)
67+ luaS_resize(L, tb->size*2); /* too crowded */
12668 return ts;
12769 }
12870
12971
130−TString *luaS_createudata (lua_State *L, void *udata, int tag) {
131− int h1 = IntPoint(udata) & (L->udt.size-1);
132− TString *ts;
133− for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) {
134− if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
72+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
73+ GCObject *o;
74+ lu_hash h = (lu_hash)l; /* seed */
75+ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
76+ size_t l1;
77+ for (l1=l; l1>=step; l1-=step) /* compute hash */
78+ h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1]));
79+ for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
80+ o != NULL;
81+ o = o->gch.next) {
82+ TString *ts = gcotots(o);
83+ if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
13584 return ts;
13685 }
137− /* not found */
138− ts = luaS_newudata(L, 0, udata);
139− if (tag != LUA_ANYTAG)
140− ts->u.d.tag = tag;
141− return ts;
86+ return newlstr(L, str, l, h); /* not found */
14287 }
14388
14489
145−TString *luaS_new (lua_State *L, const char *str) {
146− return luaS_newlstr(L, str, strlen(str));
147−}
148−
149−
150−TString *luaS_newfixed (lua_State *L, const char *str) {
151− TString *ts = luaS_new(L, str);
152− if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */
153− return ts;
90+Udata *luaS_newudata (lua_State *L, size_t s) {
91+ Udata *u;
92+ u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
93+ u->uv.marked = (1<<1); /* is not finalized */
94+ u->uv.tt = LUA_TUSERDATA;
95+ u->uv.len = s;
96+ u->uv.metatable = hvalue(defaultmeta(L));
97+ /* chain it on udata list */
98+ u->uv.next = G(L)->rootudata;
99+ G(L)->rootudata = valtogco(u);
100+ return u;
154101 }
155102
src/lstring.h+11−15
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstring.h,v 1.24 2000/10/30 17:49:19 roberto Exp $
2+** $Id: lstring.h,v 1.37 2002/08/16 14:45:55 roberto Exp $
33 ** String table (keep all strings handled by Lua)
44 ** See Copyright Notice in lua.h
55 */
@@ -12,26 +12,22 @@ · 6 unmodified lines
1212 #include "lstate.h"
1313
1414
15−/*
16−** any TString with mark>=FIXMARK is never collected.
17−** Marks>=RESERVEDMARK are used to identify reserved words.
18−*/
19−#define FIXMARK 2
20−#define RESERVEDMARK 3
2115
16+#define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \
17+ (cast(lu_mem, l)+1)*sizeof(char))
18+
19+#define sizeudata(l) (cast(lu_mem, sizeof(union Udata))+(l))
2220
23−#define sizestring(l) ((long)sizeof(TString) + \
24− ((long)(l+1)-TSPACK)*(long)sizeof(char))
21+#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
22+#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
23+ (sizeof(s)/sizeof(char))-1))
2524
25+#define luaS_fix(s) ((s)->tsv.marked |= (1<<4))
2626
27−void luaS_init (lua_State *L);
28−void luaS_resize (lua_State *L, stringtable *tb, int newsize);
29−TString *luaS_newudata (lua_State *L, size_t s, void *udata);
30−TString *luaS_createudata (lua_State *L, void *udata, int tag);
27+void luaS_resize (lua_State *L, int newsize);
28+Udata *luaS_newudata (lua_State *L, size_t s);
3129 void luaS_freeall (lua_State *L);
3230 TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
33−TString *luaS_new (lua_State *L, const char *str);
34−TString *luaS_newfixed (lua_State *L, const char *str);
3531
3632
3733 #endif
src/ltable.c+393−187
@@ -1,13 +1,17 @@
11 /*
2−** $Id: ltable.c,v 1.58 2000/10/26 12:47:05 roberto Exp $
2+** $Id: ltable.c,v 1.132 2003/04/03 13:35:34 roberto Exp $
33 ** Lua tables (hash)
44 ** See Copyright Notice in lua.h
55 */
66
77
88 /*
9−** Implementation of tables (aka arrays, objects, or hash tables);
10−** uses a mix of chained scatter table with Brent's variation.
9+** Implementation of tables (aka arrays, objects, or hash tables).
10+** Tables keep its elements in two parts: an array part and a hash part.
11+** Non-negative integer keys are all candidates to be kept in the array
12+** part. The actual size of the array is the largest `n' such that at
13+** least half the slots between 0 and n are in use.
14+** Hash uses a mix of chained scatter table with Brent's variation.
1115 ** A main invariant of these tables is that, if an element is not
1216 ** in its main position (i.e. the `original' position that its hash gives
1317 ** to it), then the colliding element is in its own main position.
@@ -17,21 +21,74 @@ · 3 unmodified lines
1721 ** performance penalties.
1822 */
1923
24+#include <string.h>
25+
26+#define ltable_c
2027
2128 #include "lua.h"
2229
30+#include "ldebug.h"
31+#include "ldo.h"
32+#include "lgc.h"
2333 #include "lmem.h"
2434 #include "lobject.h"
2535 #include "lstate.h"
26−#include "lstring.h"
2736 #include "ltable.h"
2837
2938
30−#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node))
39+/*
40+** max size of array part is 2^MAXBITS
41+*/
42+#if BITS_INT > 26
43+#define MAXBITS 24
44+#else
45+#define MAXBITS (BITS_INT-2)
46+#endif
47+
48+/* check whether `x' < 2^MAXBITS */
49+#define toobig(x) ((((x)-1) >> MAXBITS) != 0)
3150
3251
52+/* function to convert a lua_Number to int (with any rounding method) */
53+#ifndef lua_number2int
54+#define lua_number2int(i,n) ((i)=(int)(n))
55+#endif
3356
34−#define TagDefault LUA_TTABLE
57+
58+#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
59+
60+#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
61+#define hashboolean(t,p) hashpow2(t, p)
62+
63+
64+/*
65+** for some types, it is better to avoid modulus by power of 2, as
66+** they tend to have many 2 factors.
67+*/
68+#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
69+
70+
71+#define hashpointer(t,p) hashmod(t, IntPoint(p))
72+
73+
74+/*
75+** number of ints inside a lua_Number
76+*/
77+#define numints cast(int, sizeof(lua_Number)/sizeof(int))
78+
79+
80+/*
81+** hash for lua_Numbers
82+*/
83+static Node *hashnum (const Table *t, lua_Number n) {
84+ unsigned int a[numints];
85+ int i;
86+ n += 1; /* normalize number (avoid -0) */
87+ lua_assert(sizeof(a) <= sizeof(n));
88+ memcpy(a, &n, sizeof(a));
89+ for (i = 1; i < numints; i++) a[0] += a[i];
90+ return hashmod(t, cast(lu_hash, a[0]));
91+}
3592
3693
3794
@@ -39,226 +96,299 @@ · 1 unmodified line
3996 ** returns the `main' position of an element in a table (that is, the index
4097 ** of its hash value)
4198 */
42−Node *luaH_mainposition (const Hash *t, const TObject *key) {
43− unsigned long h;
99+Node *luaH_mainposition (const Table *t, const TObject *key) {
44100 switch (ttype(key)) {
45101 case LUA_TNUMBER:
46− h = (unsigned long)(long)nvalue(key);
47− break;
102+ return hashnum(t, nvalue(key));
48103 case LUA_TSTRING:
49− h = tsvalue(key)->u.s.hash;
50− break;
51− case LUA_TUSERDATA:
52− h = IntPoint(tsvalue(key));
53− break;
54− case LUA_TTABLE:
55− h = IntPoint(hvalue(key));
56− break;
57− case LUA_TFUNCTION:
58− h = IntPoint(clvalue(key));
59− break;
104+ return hashstr(t, tsvalue(key));
105+ case LUA_TBOOLEAN:
106+ return hashboolean(t, bvalue(key));
107+ case LUA_TLIGHTUSERDATA:
108+ return hashpointer(t, pvalue(key));
60109 default:
61− return NULL; /* invalid key */
110+ return hashpointer(t, gcvalue(key));
62111 }
63− LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)),
64− "a&(x-1) == a%x, for x power of 2");
65− return &t->node[h&(t->size-1)];
66112 }
67113
68114
69−static const TObject *luaH_getany (lua_State *L, const Hash *t,
70− const TObject *key) {
71− Node *n = luaH_mainposition(t, key);
72− if (!n)
73− lua_error(L, "table index is nil");
74− else do {
75− if (luaO_equalObj(key, &n->key))
76− return &n->val;
77− n = n->next;
78− } while (n);
79− return &luaO_nilobject; /* key not found */
115+/*
116+** returns the index for `key' if `key' is an appropriate key to live in
117+** the array part of the table, -1 otherwise.
118+*/
119+static int arrayindex (const TObject *key) {
120+ if (ttisnumber(key)) {
121+ int k;
122+ lua_number2int(k, (nvalue(key)));
123+ if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k))
124+ return k;
125+ }
126+ return -1; /* `key' did not match some condition */
80127 }
81128
82129
83−/* specialized version for numbers */
84−const TObject *luaH_getnum (const Hash *t, Number key) {
85− Node *n = &t->node[(unsigned long)(long)key&(t->size-1)];
86− do {
87− if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key)
88− return &n->val;
89− n = n->next;
90− } while (n);
91− return &luaO_nilobject; /* key not found */
130+/*
131+** returns the index of a `key' for table traversals. First goes all
132+** elements in the array part, then elements in the hash part. The
133+** beginning and end of a traversal are signalled by -1.
134+*/
135+static int luaH_index (lua_State *L, Table *t, StkId key) {
136+ int i;
137+ if (ttisnil(key)) return -1; /* first iteration */
138+ i = arrayindex(key);
139+ if (0 <= i && i <= t->sizearray) { /* is `key' inside array part? */
140+ return i-1; /* yes; that's the index (corrected to C) */
141+ }
142+ else {
143+ const TObject *v = luaH_get(t, key);
144+ if (v == &luaO_nilobject)
145+ luaG_runerror(L, "invalid key for `next'");
146+ i = cast(int, (cast(const lu_byte *, v) -
147+ cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node));
148+ return i + t->sizearray; /* hash elements are numbered after array ones */
149+ }
92150 }
93151
94152
95−/* specialized version for strings */
96−const TObject *luaH_getstr (const Hash *t, TString *key) {
97− Node *n = &t->node[key->u.s.hash&(t->size-1)];
98− do {
99− if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key)
100− return &n->val;
101− n = n->next;
102− } while (n);
103− return &luaO_nilobject; /* key not found */
153+int luaH_next (lua_State *L, Table *t, StkId key) {
154+ int i = luaH_index(L, t, key); /* find original element */
155+ for (i++; i < t->sizearray; i++) { /* try first array part */
156+ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
157+ setnvalue(key, cast(lua_Number, i+1));
158+ setobj2s(key+1, &t->array[i]);
159+ return 1;
160+ }
161+ }
162+ for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
163+ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
164+ setobj2s(key, gkey(gnode(t, i)));
165+ setobj2s(key+1, gval(gnode(t, i)));
166+ return 1;
167+ }
168+ }
169+ return 0; /* no more elements */
104170 }
105171
106172
107−const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
108− switch (ttype(key)) {
109− case LUA_TNUMBER: return luaH_getnum(t, nvalue(key));
110− case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
111− default: return luaH_getany(L, t, key);
173+/*
174+** {=============================================================
175+** Rehash
176+** ==============================================================
177+*/
178+
179+
180+static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
181+ int i;
182+ int a = nums[0]; /* number of elements smaller than 2^i */
183+ int na = a; /* number of elements to go to array part */
184+ int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */
185+ for (i = 1; a < *narray && *narray >= twoto(i-1); i++) {
186+ if (nums[i] > 0) {
187+ a += nums[i];
188+ if (a >= twoto(i-1)) { /* more than half elements in use? */
189+ n = i;
190+ na = a;
191+ }
192+ }
112193 }
194+ lua_assert(na <= *narray && *narray <= ntotal);
195+ *nhash = ntotal - na;
196+ *narray = (n == -1) ? 0 : twoto(n);
197+ lua_assert(na <= *narray && na >= *narray/2);
113198 }
114199
115200
116−Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
117− int i;
118− if (ttype(key) == LUA_TNIL)
119− i = 0; /* first iteration */
120− else {
121− const TObject *v = luaH_get(L, t, key);
122− if (v == &luaO_nilobject)
123− lua_error(L, "invalid key for `next'");
124− i = (int)(((const char *)v -
125− (const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
201+static void numuse (const Table *t, int *narray, int *nhash) {
202+ int nums[MAXBITS+1];
203+ int i, lg;
204+ int totaluse = 0;
205+ /* count elements in array part */
206+ for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */
207+ int ttlg = twoto(lg); /* 2^lg */
208+ if (ttlg > t->sizearray) {
209+ ttlg = t->sizearray;
210+ if (i >= ttlg) break;
211+ }
212+ nums[lg] = 0;
213+ for (; i<ttlg; i++) {
214+ if (!ttisnil(&t->array[i])) {
215+ nums[lg]++;
216+ totaluse++;
217+ }
218+ }
126219 }
127− for (; i<t->size; i++) {
128− Node *n = node(t, i);
129− if (ttype(val(n)) != LUA_TNIL)
130− return n;
220+ for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */
221+ *narray = totaluse; /* all previous uses were in array part */
222+ /* count elements in hash part */
223+ i = sizenode(t);
224+ while (i--) {
225+ Node *n = &t->node[i];
226+ if (!ttisnil(gval(n))) {
227+ int k = arrayindex(gkey(n));
228+ if (k >= 0) { /* is `key' an appropriate array index? */
229+ nums[luaO_log2(k-1)+1]++; /* count as such */
230+ (*narray)++;
231+ }
232+ totaluse++;
233+ }
131234 }
132− return NULL; /* no more elements */
235+ computesizes(nums, totaluse, narray, nhash);
133236 }
134237
135238
136−/*
137−** try to remove a key without value from a table. To avoid problems with
138−** hash, change `key' for a number with the same hash.
139−*/
140−void luaH_remove (Hash *t, TObject *key) {
141− if (ttype(key) == LUA_TNUMBER ||
142− (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30))
143− return; /* do not remove numbers nor small strings */
239+static void setarrayvector (lua_State *L, Table *t, int size) {
240+ int i;
241+ luaM_reallocvector(L, t->array, t->sizearray, size, TObject);
242+ for (i=t->sizearray; i<size; i++)
243+ setnilvalue(&t->array[i]);
244+ t->sizearray = size;
245+}
246+
247+
248+static void setnodevector (lua_State *L, Table *t, int lsize) {
249+ int i;
250+ int size = twoto(lsize);
251+ if (lsize > MAXBITS)
252+ luaG_runerror(L, "table overflow");
253+ if (lsize == 0) { /* no elements to hash part? */
254+ t->node = G(L)->dummynode; /* use common `dummynode' */
255+ lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */
256+ lua_assert(ttisnil(gval(t->node)));
257+ lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */
258+ }
144259 else {
145− /* try to find a number `n' with the same hash as `key' */
146− Node *mp = luaH_mainposition(t, key);
147− int n = mp - &t->node[0];
148− /* make sure `n' is not in `t' */
149− while (luaH_getnum(t, n) != &luaO_nilobject) {
150− if (n >= MAX_INT - t->size)
151− return; /* give up; (to avoid overflow) */
152− n += t->size;
260+ t->node = luaM_newvector(L, size, Node);
261+ for (i=0; i<size; i++) {
262+ t->node[i].next = NULL;
263+ setnilvalue(gkey(gnode(t, i)));
264+ setnilvalue(gval(gnode(t, i)));
153265 }
154− ttype(key) = LUA_TNUMBER;
155− nvalue(key) = n;
156− LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash");
157266 }
267+ t->lsizenode = cast(lu_byte, lsize);
268+ t->firstfree = gnode(t, size-1); /* first free position to be used */
158269 }
159270
160271
161−static void setnodevector (lua_State *L, Hash *t, lint32 size) {
272+static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
162273 int i;
163− if (size > MAX_INT)
164− lua_error(L, "table overflow");
165− t->node = luaM_newvector(L, size, Node);
166− for (i=0; i<(int)size; i++) {
167− ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL;
168− t->node[i].next = NULL;
274+ int oldasize = t->sizearray;
275+ int oldhsize = t->lsizenode;
276+ Node *nold;
277+ Node temp[1];
278+ if (oldhsize)
279+ nold = t->node; /* save old hash ... */
280+ else { /* old hash is `dummynode' */
281+ lua_assert(t->node == G(L)->dummynode);
282+ temp[0] = t->node[0]; /* copy it to `temp' */
283+ nold = temp;
284+ setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */
285+ setnilvalue(gval(G(L)->dummynode));
286+ lua_assert(G(L)->dummynode->next == NULL);
287+ }
288+ if (nasize > oldasize) /* array part must grow? */
289+ setarrayvector(L, t, nasize);
290+ /* create new hash part with appropriate size */
291+ setnodevector(L, t, nhsize);
292+ /* re-insert elements */
293+ if (nasize < oldasize) { /* array part must shrink? */
294+ t->sizearray = nasize;
295+ /* re-insert elements from vanishing slice */
296+ for (i=nasize; i<oldasize; i++) {
297+ if (!ttisnil(&t->array[i]))
298+ setobjt2t(luaH_setnum(L, t, i+1), &t->array[i]);
299+ }
300+ /* shrink array */
301+ luaM_reallocvector(L, t->array, oldasize, nasize, TObject);
169302 }
170− L->nblocks += gcsize(L, size) - gcsize(L, t->size);
171− t->size = size;
172− t->firstfree = &t->node[size-1]; /* first free position to be used */
303+ /* re-insert elements in hash part */
304+ for (i = twoto(oldhsize) - 1; i >= 0; i--) {
305+ Node *old = nold+i;
306+ if (!ttisnil(gval(old)))
307+ setobjt2t(luaH_set(L, t, gkey(old)), gval(old));
308+ }
309+ if (oldhsize)
310+ luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
173311 }
174312
175313
176−Hash *luaH_new (lua_State *L, int size) {
177− Hash *t = luaM_new(L, Hash);
178− t->htag = TagDefault;
179− t->next = L->roottable;
180− L->roottable = t;
181− t->mark = t;
182− t->size = 0;
183− L->nblocks += gcsize(L, 0);
184− t->node = NULL;
185− setnodevector(L, t, luaO_power2(size));
186− return t;
314+static void rehash (lua_State *L, Table *t) {
315+ int nasize, nhsize;
316+ numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */
317+ resize(L, t, nasize, luaO_log2(nhsize)+1);
187318 }
188319
189320
190−void luaH_free (lua_State *L, Hash *t) {
191− L->nblocks -= gcsize(L, t->size);
192− luaM_free(L, t->node);
193− luaM_free(L, t);
321+
322+/*
323+** }=============================================================
324+*/
325+
326+
327+Table *luaH_new (lua_State *L, int narray, int lnhash) {
328+ Table *t = luaM_new(L, Table);
329+ luaC_link(L, valtogco(t), LUA_TTABLE);
330+ t->metatable = hvalue(defaultmeta(L));
331+ t->flags = cast(lu_byte, ~0);
332+ /* temporary values (kept only if some malloc fails) */
333+ t->array = NULL;
334+ t->sizearray = 0;
335+ t->lsizenode = 0;
336+ t->node = NULL;
337+ setarrayvector(L, t, narray);
338+ setnodevector(L, t, lnhash);
339+ return t;
194340 }
195341
196342
197−static int numuse (const Hash *t) {
198− Node *v = t->node;
199− int size = t->size;
200− int realuse = 0;
201− int i;
202− for (i=0; i<size; i++) {
203− if (ttype(&v[i].val) != LUA_TNIL)
204− realuse++;
205− }
206− return realuse;
343+void luaH_free (lua_State *L, Table *t) {
344+ if (t->lsizenode)
345+ luaM_freearray(L, t->node, sizenode(t), Node);
346+ luaM_freearray(L, t->array, t->sizearray, TObject);
347+ luaM_freelem(L, t);
207348 }
208349
209350
210−static void rehash (lua_State *L, Hash *t) {
211− int oldsize = t->size;
212− Node *nold = t->node;
213− int nelems = numuse(t);
214− int i;
215− LUA_ASSERT(nelems<=oldsize, "wrong count");
216− if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
217− setnodevector(L, t, (lint32)oldsize*2);
218− else if (nelems <= oldsize/4 && /* less than 1/4? */
219− oldsize > MINPOWER2)
220− setnodevector(L, t, oldsize/2);
221− else
222− setnodevector(L, t, oldsize);
223− for (i=0; i<oldsize; i++) {
224− Node *old = nold+i;
225− if (ttype(&old->val) != LUA_TNIL)
226− *luaH_set(L, t, &old->key) = old->val;
351+#if 0
352+/*
353+** try to remove an element from a hash table; cannot move any element
354+** (because gc can call `remove' during a table traversal)
355+*/
356+void luaH_remove (Table *t, Node *e) {
357+ Node *mp = luaH_mainposition(t, gkey(e));
358+ if (e != mp) { /* element not in its main position? */
359+ while (mp->next != e) mp = mp->next; /* find previous */
360+ mp->next = e->next; /* remove `e' from its list */
361+ }
362+ else {
363+ if (e->next != NULL) ??
227364 }
228− luaM_free(L, nold); /* free old array */
365+ lua_assert(ttisnil(gval(node)));
366+ setnilvalue(gkey(e)); /* clear node `e' */
367+ e->next = NULL;
229368 }
369+#endif
230370
231371
232372 /*
233−** inserts a key into a hash table; first, check whether key is
234−** already present; if not, check whether key's main position is free;
235−** if not, check whether colliding node is in its main position or not;
236−** if it is not, move colliding node to an empty place and put new key
237−** in its main position; otherwise (colliding node is in its main position),
238−** new key goes to an empty position.
373+** inserts a new key into a hash table; first, check whether key's main
374+** position is free. If not, check whether colliding node is in its main
375+** position or not: if it is not, move colliding node to an empty place and
376+** put new key in its main position; otherwise (colliding node is in its main
377+** position), new key goes to an empty position.
239378 */
240−TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
379+static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
380+ TObject *val;
241381 Node *mp = luaH_mainposition(t, key);
242− Node *n = mp;
243− if (!mp)
244− lua_error(L, "table index is nil");
245− do { /* check whether `key' is somewhere in the chain */
246− if (luaO_equalObj(key, &n->key))
247− return &n->val; /* that's all */
248− else n = n->next;
249− } while (n);
250− /* `key' not found; must insert it */
251− if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */
252− Node *othern; /* main position of colliding node */
253− n = t->firstfree; /* get a free place */
254− /* is colliding node out of its main position? (can only happens if
255− its position is after "firstfree") */
256− if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) {
382+ if (!ttisnil(gval(mp))) { /* main position is not free? */
383+ Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */
384+ Node *n = t->firstfree; /* get a free place */
385+ if (othern != mp) { /* is colliding node out of its main position? */
257386 /* yes; move colliding node into free position */
258387 while (othern->next != mp) othern = othern->next; /* find previous */
259388 othern->next = n; /* redo the chain with `n' in place of `mp' */
260389 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
261390 mp->next = NULL; /* now `mp' is free */
391+ setnilvalue(gval(mp));
262392 }
263393 else { /* colliding node is in its own main position */
264394 /* new node will go into free position */
@@ -267,37 +397,113 @@ TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { · 2 unmodified lines
267397 mp = n;
268398 }
269399 }
270− mp->key = *key;
400+ setobj2t(gkey(mp), key); /* write barrier */
401+ lua_assert(ttisnil(gval(mp)));
271402 for (;;) { /* correct `firstfree' */
272− if (ttype(&t->firstfree->key) == LUA_TNIL)
273− return &mp->val; /* OK; table still has a free place */
403+ if (ttisnil(gkey(t->firstfree)))
404+ return gval(mp); /* OK; table still has a free place */
274405 else if (t->firstfree == t->node) break; /* cannot decrement from here */
275406 else (t->firstfree)--;
276407 }
277− rehash(L, t); /* no more free places */
278− return luaH_set(L, t, key); /* `rehash' invalidates this insertion */
408+ /* no more free places; must create one */
409+ setbvalue(gval(mp), 0); /* avoid new key being removed */
410+ rehash(L, t); /* grow table */
411+ val = cast(TObject *, luaH_get(t, key)); /* get new position */
412+ lua_assert(ttisboolean(val));
413+ setnilvalue(val);
414+ return val;
415+}
416+
417+
418+/*
419+** generic search function
420+*/
421+static const TObject *luaH_getany (Table *t, const TObject *key) {
422+ if (ttisnil(key)) return &luaO_nilobject;
423+ else {
424+ Node *n = luaH_mainposition(t, key);
425+ do { /* check whether `key' is somewhere in the chain */
426+ if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
427+ else n = n->next;
428+ } while (n);
429+ return &luaO_nilobject;
430+ }
279431 }
280432
281433
282−TObject *luaH_setint (lua_State *L, Hash *t, int key) {
283− TObject index;
284− ttype(&index) = LUA_TNUMBER;
285− nvalue(&index) = key;
286− return luaH_set(L, t, &index);
434+/*
435+** search function for integers
436+*/
437+const TObject *luaH_getnum (Table *t, int key) {
438+ if (1 <= key && key <= t->sizearray)
439+ return &t->array[key-1];
440+ else {
441+ lua_Number nk = cast(lua_Number, key);
442+ Node *n = hashnum(t, nk);
443+ do { /* check whether `key' is somewhere in the chain */
444+ if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk)
445+ return gval(n); /* that's it */
446+ else n = n->next;
447+ } while (n);
448+ return &luaO_nilobject;
449+ }
287450 }
288451
289452
290−void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val) {
291− TObject *value, index;
292− ttype(&index) = LUA_TSTRING;
293− tsvalue(&index) = key;
294− value = luaH_set(L, t, &index);
295− ttype(value) = LUA_TNUMBER;
296− nvalue(value) = val;
453+/*
454+** search function for strings
455+*/
456+const TObject *luaH_getstr (Table *t, TString *key) {
457+ Node *n = hashstr(t, key);
458+ do { /* check whether `key' is somewhere in the chain */
459+ if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key)
460+ return gval(n); /* that's it */
461+ else n = n->next;
462+ } while (n);
463+ return &luaO_nilobject;
297464 }
298465
299466
300−const TObject *luaH_getglobal (lua_State *L, const char *name) {
301− return luaH_getstr(L->gt, luaS_new(L, name));
467+/*
468+** main search function
469+*/
470+const TObject *luaH_get (Table *t, const TObject *key) {
471+ switch (ttype(key)) {
472+ case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
473+ case LUA_TNUMBER: {
474+ int k;
475+ lua_number2int(k, (nvalue(key)));
476+ if (cast(lua_Number, k) == nvalue(key)) /* is an integer index? */
477+ return luaH_getnum(t, k); /* use specialized version */
478+ /* else go through */
479+ }
480+ default: return luaH_getany(t, key);
481+ }
482+}
483+
484+
485+TObject *luaH_set (lua_State *L, Table *t, const TObject *key) {
486+ const TObject *p = luaH_get(t, key);
487+ t->flags = 0;
488+ if (p != &luaO_nilobject)
489+ return cast(TObject *, p);
490+ else {
491+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
492+ else if (ttisnumber(key) && nvalue(key) != nvalue(key))
493+ luaG_runerror(L, "table index is NaN");
494+ return newkey(L, t, key);
495+ }
496+}
497+
498+
499+TObject *luaH_setnum (lua_State *L, Table *t, int key) {
500+ const TObject *p = luaH_getnum(t, key);
501+ if (p != &luaO_nilobject)
502+ return cast(TObject *, p);
503+ else {
504+ TObject k;
505+ setnvalue(&k, cast(lua_Number, key));
506+ return newkey(L, t, &k);
507+ }
302508 }
303509
src/ltable.h+14−17
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ltable.h,v 1.24 2000/08/31 14:08:27 roberto Exp $
2+** $Id: ltable.h,v 1.44 2003/03/18 12:50:04 roberto Exp $
33 ** Lua tables (hash)
44 ** See Copyright Notice in lua.h
55 */
@@ -10,25 +10,22 @@ · 4 unmodified lines
1010 #include "lobject.h"
1111
1212
13−#define node(t,i) (&(t)->node[i])
14−#define key(n) (&(n)->key)
15−#define val(n) (&(n)->val)
13+#define gnode(t,i) (&(t)->node[i])
14+#define gkey(n) (&(n)->i_key)
15+#define gval(n) (&(n)->i_val)
1616
17−Hash *luaH_new (lua_State *L, int nhash);
18−void luaH_free (lua_State *L, Hash *t);
19−const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
20−const TObject *luaH_getnum (const Hash *t, Number key);
21−const TObject *luaH_getstr (const Hash *t, TString *key);
22−void luaH_remove (Hash *t, TObject *key);
23−TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
24−Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
25−TObject *luaH_setint (lua_State *L, Hash *t, int key);
26−void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val);
27−unsigned long luaH_hash (lua_State *L, const TObject *key);
28−const TObject *luaH_getglobal (lua_State *L, const char *name);
17+
18+const TObject *luaH_getnum (Table *t, int key);
19+TObject *luaH_setnum (lua_State *L, Table *t, int key);
20+const TObject *luaH_getstr (Table *t, TString *key);
21+const TObject *luaH_get (Table *t, const TObject *key);
22+TObject *luaH_set (lua_State *L, Table *t, const TObject *key);
23+Table *luaH_new (lua_State *L, int narray, int lnhash);
24+void luaH_free (lua_State *L, Table *t);
25+int luaH_next (lua_State *L, Table *t, StkId key);
2926
3027 /* exported only for debugging */
31−Node *luaH_mainposition (const Hash *t, const TObject *key);
28+Node *luaH_mainposition (const Table *t, const TObject *key);
3229
3330
3431 #endif
src/ltests.c+500−191
@@ -1,15 +1,17 @@
11 /*
2−** $Id: ltests.c,v 1.54 2000/10/31 13:10:24 roberto Exp $
2+** $Id: ltests.c,v 1.158 2003/04/07 14:35:00 roberto Exp $
33 ** Internal Module for Debugging of the Lua Implementation
44 ** See Copyright Notice in lua.h
55 */
66
77
88 #include <ctype.h>
9+#include <limits.h>
910 #include <stdio.h>
1011 #include <stdlib.h>
1112 #include <string.h>
1213
14+#define ltests_c
1315
1416 #include "lua.h"
1517
@@ -24,12 +26,9 @@ · 8 unmodified lines
2426 #include "lstate.h"
2527 #include "lstring.h"
2628 #include "ltable.h"
27−#include "luadebug.h"
2829 #include "lualib.h"
2930
3031
31−void luaB_opentests (lua_State *L);
32−
3332
3433 /*
3534 ** The whole module only makes sense with LUA_DEBUG on
@@ -37,14 +36,117 @@ void luaB_opentests (lua_State *L); · 1 unmodified line
3736 #ifdef LUA_DEBUG
3837
3938
39+#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
40+
41+
42+static lua_State *lua_state = NULL;
43+
44+int islocked = 0;
45+
46+
47+#define func_at(L,k) (L->ci->base+(k) - 1)
48+
4049
4150 static void setnameval (lua_State *L, const char *name, int val) {
4251 lua_pushstring(L, name);
43− lua_pushnumber(L, val);
52+ lua_pushintegral(L, val);
4453 lua_settable(L, -3);
4554 }
4655
4756
57+/*
58+** {======================================================================
59+** Controlled version for realloc.
60+** =======================================================================
61+*/
62+
63+#define MARK 0x55 /* 01010101 (a nice pattern) */
64+
65+#ifndef EXTERNMEMCHECK
66+/* full memory check */
67+#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
68+#define MARKSIZE 16 /* size of marks after each block */
69+#define blockhead(b) (cast(char *, b) - HEADER)
70+#define setsize(newblock, size) (*cast(size_t *, newblock) = size)
71+#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
72+#define fillmem(mem,size) memset(mem, -MARK, size)
73+#else
74+/* external memory check: don't do it twice */
75+#define HEADER 0
76+#define MARKSIZE 0
77+#define blockhead(b) (b)
78+#define setsize(newblock, size) /* empty */
79+#define checkblocksize(b,size) (1)
80+#define fillmem(mem,size) /* empty */
81+#endif
82+
83+unsigned long memdebug_numblocks = 0;
84+unsigned long memdebug_total = 0;
85+unsigned long memdebug_maxmem = 0;
86+unsigned long memdebug_memlimit = ULONG_MAX;
87+
88+
89+static void *checkblock (void *block, size_t size) {
90+ void *b = blockhead(block);
91+ int i;
92+ for (i=0;i<MARKSIZE;i++)
93+ lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
94+ return b;
95+}
96+
97+
98+static void freeblock (void *block, size_t size) {
99+ if (block) {
100+ lua_assert(checkblocksize(block, size));
101+ block = checkblock(block, size);
102+ fillmem(block, size+HEADER+MARKSIZE); /* erase block */
103+ free(block); /* free original block */
104+ memdebug_numblocks--;
105+ memdebug_total -= size;
106+ }
107+}
108+
109+
110+void *debug_realloc (void *block, size_t oldsize, size_t size) {
111+ lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
112+ /* ISO does not specify what realloc(NULL, 0) does */
113+ lua_assert(block != NULL || size > 0);
114+ if (size == 0) {
115+ freeblock(block, oldsize);
116+ return NULL;
117+ }
118+ else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
119+ return NULL; /* to test memory allocation errors */
120+ else {
121+ void *newblock;
122+ int i;
123+ size_t realsize = HEADER+size+MARKSIZE;
124+ size_t commonsize = (oldsize < size) ? oldsize : size;
125+ if (realsize < size) return NULL; /* overflow! */
126+ newblock = malloc(realsize); /* alloc a new block */
127+ if (newblock == NULL) return NULL;
128+ if (block) {
129+ memcpy(cast(char *, newblock)+HEADER, block, commonsize);
130+ freeblock(block, oldsize); /* erase (and check) old copy */
131+ }
132+ /* initialize new part of the block with something `weird' */
133+ fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
134+ memdebug_total += size;
135+ if (memdebug_total > memdebug_maxmem)
136+ memdebug_maxmem = memdebug_total;
137+ memdebug_numblocks++;
138+ setsize(newblock, size);
139+ for (i=0;i<MARKSIZE;i++)
140+ *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
141+ return cast(char *, newblock)+HEADER;
142+ }
143+}
144+
145+
146+/* }====================================================================== */
147+
148+
149+
48150 /*
49151 ** {======================================================
50152 ** Disassembler
@@ -52,73 +154,69 @@ static void setnameval (lua_State *L, const char *name, int val) { · 1 unmodified line
52154 */
53155
54156
55−static const char *const instrname[NUM_OPCODES] = {
56− "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT",
57− "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL",
58− "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF",
59− "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP",
60− "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT",
61− "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF",
62− "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP",
63− "LFORLOOP", "CLOSURE"
64−};
65−
66−
67−static int pushop (lua_State *L, Proto *p, int pc) {
68− char buff[100];
157+static char *buildop (Proto *p, int pc, char *buff) {
69158 Instruction i = p->code[pc];
70159 OpCode o = GET_OPCODE(i);
71− const char *name = instrname[o];
72− sprintf(buff, "%5d - ", luaG_getline(p->lineinfo, pc, 1, NULL));
73− switch ((enum Mode)luaK_opproperties[o].mode) {
74− case iO:
75− sprintf(buff+8, "%-12s", name);
76− break;
77− case iU:
78− sprintf(buff+8, "%-12s%4u", name, GETARG_U(i));
160+ const char *name = luaP_opnames[o];
161+ int line = getline(p, pc);
162+ sprintf(buff, "(%4d) %4d - ", line, pc);
163+ switch (getOpMode(o)) {
164+ case iABC:
165+ sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
166+ GETARG_A(i), GETARG_B(i), GETARG_C(i));
79167 break;
80− case iS:
81− sprintf(buff+8, "%-12s%4d", name, GETARG_S(i));
168+ case iABx:
169+ sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
82170 break;
83− case iAB:
84− sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
171+ case iAsBx:
172+ sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
85173 break;
86174 }
87− lua_pushstring(L, buff);
88− return (o != OP_END);
175+ return buff;
89176 }
90177
91178
179+#if 0
180+void luaI_printcode (Proto *pt, int size) {
181+ int pc;
182+ for (pc=0; pc<size; pc++) {
183+ char buff[100];
184+ printf("%s\n", buildop(pt, pc, buff));
185+ }
186+ printf("-------\n");
187+}
188+#endif
189+
190+
92191 static int listcode (lua_State *L) {
93192 int pc;
94193 Proto *p;
95− int res;
96− luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
194+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
97195 1, "Lua function expected");
98− p = clvalue(luaA_index(L, 1))->f.l;
196+ p = clvalue(func_at(L, 1))->l.p;
99197 lua_newtable(L);
100198 setnameval(L, "maxstack", p->maxstacksize);
101199 setnameval(L, "numparams", p->numparams);
102− pc = 0;
103− do {
104− lua_pushnumber(L, pc+1);
105− res = pushop(L, p, pc++);
200+ for (pc=0; pc<p->sizecode; pc++) {
201+ char buff[100];
202+ lua_pushintegral(L, pc+1);
203+ lua_pushstring(L, buildop(p, pc, buff));
106204 lua_settable(L, -3);
107− } while (res);
205+ }
108206 return 1;
109207 }
110208
111209
112−static int liststrings (lua_State *L) {
210+static int listk (lua_State *L) {
113211 Proto *p;
114212 int i;
115− luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
213+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
116214 1, "Lua function expected");
117− p = clvalue(luaA_index(L, 1))->f.l;
215+ p = clvalue(func_at(L, 1))->l.p;
118216 lua_newtable(L);
119− for (i=0; i<p->nkstr; i++) {
120− lua_pushnumber(L, i+1);
121− lua_pushstring(L, p->kstr[i]->str);
217+ for (i=0; i<p->sizek; i++) {
218+ lua_pushintegral(L, i+1);
219+ luaA_pushobject(L, p->k+i);
122220 lua_settable(L, -3);
123221 }
124222 return 1;
@@ -127,12 +225,12 @@ static int liststrings (lua_State *L) { · 2 unmodified lines
127225
128226 static int listlocals (lua_State *L) {
129227 Proto *p;
130− int pc = luaL_check_int(L, 2) - 1;
228+ int pc = luaL_checkint(L, 2) - 1;
131229 int i = 0;
132230 const char *name;
133− luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
231+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
134232 1, "Lua function expected");
135− p = clvalue(luaA_index(L, 1))->f.l;
233+ p = clvalue(func_at(L, 1))->l.p;
136234 while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
137235 lua_pushstring(L, name);
138236 return i-1;
@@ -142,96 +240,107 @@ static int listlocals (lua_State *L) { · 3 unmodified lines
142240
143241
144242
243+
145244 static int get_limits (lua_State *L) {
146245 lua_newtable(L);
147246 setnameval(L, "BITS_INT", BITS_INT);
148247 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
149− setnameval(L, "MAXARG_A", MAXARG_A);
150− setnameval(L, "MAXARG_B", MAXARG_B);
151− setnameval(L, "MAXARG_S", MAXARG_S);
152− setnameval(L, "MAXARG_U", MAXARG_U);
153− setnameval(L, "MAXLOCALS", MAXLOCALS);
248+ setnameval(L, "MAXVARS", MAXVARS);
154249 setnameval(L, "MAXPARAMS", MAXPARAMS);
155250 setnameval(L, "MAXSTACK", MAXSTACK);
156251 setnameval(L, "MAXUPVALUES", MAXUPVALUES);
157− setnameval(L, "MAXVARSLH", MAXVARSLH);
158− setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
159− setnameval(L, "SIZE_A", SIZE_A);
160− setnameval(L, "SIZE_B", SIZE_B);
161− setnameval(L, "SIZE_OP", SIZE_OP);
162− setnameval(L, "SIZE_U", SIZE_U);
163252 return 1;
164253 }
165254
166255
167256 static int mem_query (lua_State *L) {
168− if (lua_isnull(L, 1)) {
169− lua_pushnumber(L, memdebug_total);
170− lua_pushnumber(L, memdebug_numblocks);
171− lua_pushnumber(L, memdebug_maxmem);
257+ if (lua_isnone(L, 1)) {
258+ lua_pushintegral(L, memdebug_total);
259+ lua_pushintegral(L, memdebug_numblocks);
260+ lua_pushintegral(L, memdebug_maxmem);
172261 return 3;
173262 }
174263 else {
175− memdebug_memlimit = luaL_check_int(L, 1);
264+ memdebug_memlimit = luaL_checkint(L, 1);
176265 return 0;
177266 }
178267 }
179268
180269
181270 static int hash_query (lua_State *L) {
182− if (lua_isnull(L, 2)) {
183− luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected");
184− lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
271+ if (lua_isnone(L, 2)) {
272+ luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
273+ lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
185274 }
186275 else {
187− Hash *t;
276+ TObject *o = func_at(L, 1);
277+ Table *t;
188278 luaL_checktype(L, 2, LUA_TTABLE);
189− t = hvalue(luaA_index(L, 2));
190− lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
279+ t = hvalue(func_at(L, 2));
280+ lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
191281 }
192282 return 1;
193283 }
194284
195285
286+static int stacklevel (lua_State *L) {
287+ unsigned long a = 0;
288+ lua_pushintegral(L, (int)(L->top - L->stack));
289+ lua_pushintegral(L, (int)(L->stack_last - L->stack));
290+ lua_pushintegral(L, (int)(L->ci - L->base_ci));
291+ lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
292+ lua_pushintegral(L, (unsigned long)&a);
293+ return 5;
294+}
295+
296+
196297 static int table_query (lua_State *L) {
197− const Hash *t;
198− int i = luaL_opt_int(L, 2, -1);
298+ const Table *t;
299+ int i = luaL_optint(L, 2, -1);
199300 luaL_checktype(L, 1, LUA_TTABLE);
200− t = hvalue(luaA_index(L, 1));
301+ t = hvalue(func_at(L, 1));
201302 if (i == -1) {
202− lua_pushnumber(L, t->size);
203− lua_pushnumber(L, t->firstfree - t->node);
204− return 2;
303+ lua_pushintegral(L, t->sizearray);
304+ lua_pushintegral(L, sizenode(t));
305+ lua_pushintegral(L, t->firstfree - t->node);
205306 }
206− else if (i < t->size) {
207− luaA_pushobject(L, &t->node[i].key);
208− luaA_pushobject(L, &t->node[i].val);
209− if (t->node[i].next) {
210− lua_pushnumber(L, t->node[i].next - t->node);
211− return 3;
307+ else if (i < t->sizearray) {
308+ lua_pushintegral(L, i);
309+ luaA_pushobject(L, &t->array[i]);
310+ lua_pushnil(L);
311+ }
312+ else if ((i -= t->sizearray) < sizenode(t)) {
313+ if (!ttisnil(gval(gnode(t, i))) ||
314+ ttisnil(gkey(gnode(t, i))) ||
315+ ttisnumber(gkey(gnode(t, i)))) {
316+ luaA_pushobject(L, gkey(gnode(t, i)));
212317 }
213318 else
214− return 2;
319+ lua_pushstring(L, "<undef>");
320+ luaA_pushobject(L, gval(gnode(t, i)));
321+ if (t->node[i].next)
322+ lua_pushintegral(L, t->node[i].next - t->node);
323+ else
324+ lua_pushnil(L);
215325 }
216− return 0;
326+ return 3;
217327 }
218328
219329
220330 static int string_query (lua_State *L) {
221− stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
222− int s = luaL_opt_int(L, 2, 0) - 1;
331+ stringtable *tb = &G(L)->strt;
332+ int s = luaL_optint(L, 2, 0) - 1;
223333 if (s==-1) {
224− lua_pushnumber(L ,tb->nuse);
225− lua_pushnumber(L ,tb->size);
334+ lua_pushintegral(L ,tb->nuse);
335+ lua_pushintegral(L ,tb->size);
226336 return 2;
227337 }
228338 else if (s < tb->size) {
229− TString *ts;
339+ GCObject *ts;
230340 int n = 0;
231− for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
232− ttype(L->top) = LUA_TSTRING;
233− tsvalue(L->top) = ts;
234− incr_top;
341+ for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
342+ setsvalue2s(L->top, gcotots(ts));
343+ incr_top(L);
235344 n++;
236345 }
237346 return n;
@@ -241,111 +350,193 @@ static int string_query (lua_State *L) { · 3 unmodified lines
241350
242351
243352 static int tref (lua_State *L) {
353+ int level = lua_gettop(L);
354+ int lock = luaL_optint(L, 2, 1);
244355 luaL_checkany(L, 1);
245356 lua_pushvalue(L, 1);
246− lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
357+ lua_pushintegral(L, lua_ref(L, lock));
358+ assert(lua_gettop(L) == level+1); /* +1 for result */
247359 return 1;
248360 }
249361
250362 static int getref (lua_State *L) {
251− if (lua_getref(L, luaL_check_int(L, 1)))
252− return 1;
253− else
254− return 0;
363+ int level = lua_gettop(L);
364+ lua_getref(L, luaL_checkint(L, 1));
365+ assert(lua_gettop(L) == level+1);
366+ return 1;
255367 }
256368
257369 static int unref (lua_State *L) {
258− lua_unref(L, luaL_check_int(L, 1));
370+ int level = lua_gettop(L);
371+ lua_unref(L, luaL_checkint(L, 1));
372+ assert(lua_gettop(L) == level);
259373 return 0;
260374 }
261375
376+static int metatable (lua_State *L) {
377+ luaL_checkany(L, 1);
378+ if (lua_isnone(L, 2)) {
379+ if (lua_getmetatable(L, 1) == 0)
380+ lua_pushnil(L);
381+ }
382+ else {
383+ lua_settop(L, 2);
384+ luaL_checktype(L, 2, LUA_TTABLE);
385+ lua_setmetatable(L, 1);
386+ }
387+ return 1;
388+}
389+
390+
391+static int upvalue (lua_State *L) {
392+ int n = luaL_checkint(L, 2);
393+ luaL_checktype(L, 1, LUA_TFUNCTION);
394+ if (lua_isnone(L, 3)) {
395+ const char *name = lua_getupvalue(L, 1, n);
396+ if (name == NULL) return 0;
397+ lua_pushstring(L, name);
398+ return 2;
399+ }
400+ else {
401+ const char *name = lua_setupvalue(L, 1, n);
402+ lua_pushstring(L, name);
403+ return 1;
404+ }
405+}
406+
407+
262408 static int newuserdata (lua_State *L) {
263− if (lua_isnumber(L, 2))
264− lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2));
265− else
266− lua_newuserdata(L, luaL_check_int(L, 1));
409+ size_t size = luaL_checkint(L, 1);
410+ char *p = cast(char *, lua_newuserdata(L, size));
411+ while (size--) *p++ = '\0';
412+ return 1;
413+}
414+
415+
416+static int pushuserdata (lua_State *L) {
417+ lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
267418 return 1;
268419 }
269420
421+
270422 static int udataval (lua_State *L) {
271− luaL_checktype(L, 1, LUA_TUSERDATA);
272− lua_pushnumber(L, (int)lua_touserdata(L, 1));
423+ lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
424+ return 1;
425+}
426+
427+
428+static int doonnewstack (lua_State *L) {
429+ lua_State *L1 = lua_newthread(L);
430+ size_t l;
431+ const char *s = luaL_checklstring(L, 1, &l);
432+ int status = luaL_loadbuffer(L1, s, l, s);
433+ if (status == 0)
434+ status = lua_pcall(L1, 0, 0, 0);
435+ lua_pushintegral(L, status);
436+ return 1;
437+}
438+
439+
440+static int s2d (lua_State *L) {
441+ lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
442+ return 1;
443+}
444+
445+static int d2s (lua_State *L) {
446+ double d = luaL_checknumber(L, 1);
447+ lua_pushlstring(L, cast(char *, &d), sizeof(d));
273448 return 1;
274449 }
275450
451+
276452 static int newstate (lua_State *L) {
277− lua_State *L1 = lua_open(luaL_check_int(L, 1));
278− if (L1)
279− lua_pushuserdata(L, L1);
453+ lua_State *L1 = lua_open();
454+ if (L1) {
455+ lua_userstateopen(L1); /* init lock */
456+ lua_pushintegral(L, (unsigned long)L1);
457+ }
280458 else
281459 lua_pushnil(L);
282460 return 1;
283461 }
284462
463+
285464 static int loadlib (lua_State *L) {
286− lua_State *L1 = (lua_State *)lua_touserdata(L, 1);
287− switch (*luaL_check_string(L, 2)) {
288− case 'm': lua_mathlibopen(L1); break;
289− case 's': lua_strlibopen(L1); break;
290− case 'i': lua_iolibopen(L1); break;
291− case 'd': lua_dblibopen(L1); break;
292− case 'b': lua_baselibopen(L1); break;
293− default: luaL_argerror(L, 2, "invalid option");
294− }
465+ static const luaL_reg libs[] = {
466+ {"mathlibopen", luaopen_math},
467+ {"strlibopen", luaopen_string},
468+ {"iolibopen", luaopen_io},
469+ {"tablibopen", luaopen_table},
470+ {"dblibopen", luaopen_debug},
471+ {"baselibopen", luaopen_base},
472+ {NULL, NULL}
473+ };
474+ lua_State *L1 = cast(lua_State *,
475+ cast(unsigned long, luaL_checknumber(L, 1)));
476+ lua_pushvalue(L1, LUA_GLOBALSINDEX);
477+ luaL_openlib(L1, NULL, libs, 0);
295478 return 0;
296479 }
297480
298481 static int closestate (lua_State *L) {
299− luaL_checktype(L, 1, LUA_TUSERDATA);
300− lua_close((lua_State *)lua_touserdata(L, 1));
482+ lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
483+ lua_close(L1);
484+ lua_unlock(L); /* close cannot unlock that */
301485 return 0;
302486 }
303487
304488 static int doremote (lua_State *L) {
305− lua_State *L1;
306− const char *code = luaL_check_string(L, 2);
489+ lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
490+ size_t lcode;
491+ const char *code = luaL_checklstring(L, 2, &lcode);
307492 int status;
308− luaL_checktype(L, 1, LUA_TUSERDATA);
309− L1 = (lua_State *)lua_touserdata(L, 1);
310− status = lua_dostring(L1, code);
493+ lua_settop(L1, 0);
494+ status = luaL_loadbuffer(L1, code, lcode, code);
495+ if (status == 0)
496+ status = lua_pcall(L1, 0, LUA_MULTRET, 0);
311497 if (status != 0) {
312498 lua_pushnil(L);
313− lua_pushnumber(L, status);
314− return 2;
499+ lua_pushintegral(L, status);
500+ lua_pushstring(L, lua_tostring(L1, -1));
501+ return 3;
315502 }
316503 else {
317504 int i = 0;
318− while (!lua_isnull(L1, ++i))
505+ while (!lua_isnone(L1, ++i))
319506 lua_pushstring(L, lua_tostring(L1, i));
507+ lua_pop(L1, i-1);
320508 return i-1;
321509 }
322510 }
323511
324−static int settagmethod (lua_State *L) {
325− int tag = luaL_check_int(L, 1);
326− const char *event = luaL_check_string(L, 2);
327− luaL_checkany(L, 3);
328− lua_gettagmethod(L, tag, event);
329− lua_pushvalue(L, 3);
330− lua_settagmethod(L, tag, event);
512+
513+static int log2_aux (lua_State *L) {
514+ lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
331515 return 1;
332516 }
333517
334−static int pushbool (lua_State *L, int b) {
335− if (b) lua_pushnumber(L, 1);
336− else lua_pushnil(L);
337− return 1;
518+static int int2fb_aux (lua_State *L) {
519+ int b = luaO_int2fb(luaL_checkint(L, 1));
520+ lua_pushintegral(L, b);
521+ lua_pushintegral(L, fb2int(b));
522+ return 2;
338523 }
339524
340−static int equal (lua_State *L) {
341− return pushbool(L, lua_equal(L, 1, 2));
525+
526+static int test_do (lua_State *L) {
527+ const char *p = luaL_checkstring(L, 1);
528+ if (*p == '@')
529+ lua_dofile(L, p+1);
530+ else
531+ lua_dostring(L, p);
532+ return lua_gettop(L);
342533 }
343534
344−
535+
345536
346537 /*
347538 ** {======================================================
348−** function to test the API with C. It interprets a kind of "assembler"
539+** function to test the API with C. It interprets a kind of assembler
349540 ** language with calls to the API, so the test can be driven by Lua code
350541 ** =======================================================
351542 */
@@ -356,12 +547,12 @@ static void skip (const char **pc) { · 4 unmodified lines
356547 while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
357548 }
358549
359−static int getnum (lua_State *L, const char **pc) {
550+static int getnum_aux (lua_State *L, const char **pc) {
360551 int res = 0;
361552 int sig = 1;
362553 skip(pc);
363554 if (**pc == '.') {
364− res = (int)lua_tonumber(L, -1);
555+ res = cast(int, lua_tonumber(L, -1));
365556 lua_pop(L, 1);
366557 (*pc)++;
367558 return res;
@@ -370,11 +561,11 @@ static int getnum (lua_State *L, const char **pc) { · 2 unmodified lines
370561 sig = -1;
371562 (*pc)++;
372563 }
373− while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
564+ while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0';
374565 return sig*res;
375566 }
376567
377−static const char *getname (char *buff, const char **pc) {
568+static const char *getname_aux (char *buff, const char **pc) {
378569 int i = 0;
379570 skip(pc);
380571 while (**pc != '\0' && !strchr(delimits, **pc))
@@ -386,51 +577,52 @@ static const char *getname (char *buff, const char **pc) { · 5 unmodified lines
386577
387578 #define EQ(s1) (strcmp(s1, inst) == 0)
388579
389−#define getnum ((getnum)(L, &pc))
390−#define getname ((getname)(buff, &pc))
580+#define getnum (getnum_aux(L, &pc))
581+#define getname (getname_aux(buff, &pc))
391582
392583
393584 static int testC (lua_State *L) {
394585 char buff[30];
395− const char *pc = luaL_check_string(L, 1);
586+ const char *pc = luaL_checkstring(L, 1);
396587 for (;;) {
397588 const char *inst = getname;
398589 if EQ("") return 0;
399590 else if EQ("isnumber") {
400− lua_pushnumber(L, lua_isnumber(L, getnum));
591+ lua_pushintegral(L, lua_isnumber(L, getnum));
401592 }
402593 else if EQ("isstring") {
403− lua_pushnumber(L, lua_isstring(L, getnum));
594+ lua_pushintegral(L, lua_isstring(L, getnum));
404595 }
405596 else if EQ("istable") {
406− lua_pushnumber(L, lua_istable(L, getnum));
597+ lua_pushintegral(L, lua_istable(L, getnum));
407598 }
408599 else if EQ("iscfunction") {
409− lua_pushnumber(L, lua_iscfunction(L, getnum));
600+ lua_pushintegral(L, lua_iscfunction(L, getnum));
410601 }
411602 else if EQ("isfunction") {
412− lua_pushnumber(L, lua_isfunction(L, getnum));
603+ lua_pushintegral(L, lua_isfunction(L, getnum));
413604 }
414605 else if EQ("isuserdata") {
415− lua_pushnumber(L, lua_isuserdata(L, getnum));
606+ lua_pushintegral(L, lua_isuserdata(L, getnum));
607+ }
608+ else if EQ("isudataval") {
609+ lua_pushintegral(L, lua_islightuserdata(L, getnum));
416610 }
417611 else if EQ("isnil") {
418− lua_pushnumber(L, lua_isnil(L, getnum));
612+ lua_pushintegral(L, lua_isnil(L, getnum));
419613 }
420614 else if EQ("isnull") {
421− lua_pushnumber(L, lua_isnull(L, getnum));
615+ lua_pushintegral(L, lua_isnone(L, getnum));
422616 }
423617 else if EQ("tonumber") {
424618 lua_pushnumber(L, lua_tonumber(L, getnum));
425619 }
426620 else if EQ("tostring") {
427− lua_pushstring(L, lua_tostring(L, getnum));
428− }
429− else if EQ("tonumber") {
430− lua_pushnumber(L, lua_tonumber(L, getnum));
621+ const char *s = lua_tostring(L, getnum);
622+ lua_pushstring(L, s);
431623 }
432624 else if EQ("strlen") {
433− lua_pushnumber(L, lua_strlen(L, getnum));
625+ lua_pushintegral(L, lua_strlen(L, getnum));
434626 }
435627 else if EQ("tocfunction") {
436628 lua_pushcfunction(L, lua_tocfunction(L, getnum));
@@ -439,7 +631,7 @@ static int testC (lua_State *L) { · 2 unmodified lines
439631 return getnum;
440632 }
441633 else if EQ("gettop") {
442− lua_pushnumber(L, lua_gettop(L));
634+ lua_pushintegral(L, lua_gettop(L));
443635 }
444636 else if EQ("settop") {
445637 lua_settop(L, getnum);
@@ -448,17 +640,35 @@ static int testC (lua_State *L) { · 2 unmodified lines
448640 lua_pop(L, getnum);
449641 }
450642 else if EQ("pushnum") {
451− lua_pushnumber(L, getnum);
643+ lua_pushintegral(L, getnum);
644+ }
645+ else if EQ("pushnil") {
646+ lua_pushnil(L);
647+ }
648+ else if EQ("pushbool") {
649+ lua_pushboolean(L, getnum);
650+ }
651+ else if EQ("tobool") {
652+ lua_pushintegral(L, lua_toboolean(L, getnum));
452653 }
453654 else if EQ("pushvalue") {
454655 lua_pushvalue(L, getnum);
455656 }
657+ else if EQ("pushcclosure") {
658+ lua_pushcclosure(L, testC, getnum);
659+ }
660+ else if EQ("pushupvalues") {
661+ lua_pushupvalues(L);
662+ }
456663 else if EQ("remove") {
457664 lua_remove(L, getnum);
458665 }
459666 else if EQ("insert") {
460667 lua_insert(L, getnum);
461668 }
669+ else if EQ("replace") {
670+ lua_replace(L, getnum);
671+ }
462672 else if EQ("gettable") {
463673 lua_gettable(L, getnum);
464674 }
@@ -471,33 +681,53 @@ static int testC (lua_State *L) { · 6 unmodified lines
471681 else if EQ("concat") {
472682 lua_concat(L, getnum);
473683 }
684+ else if EQ("lessthan") {
685+ int a = getnum;
686+ lua_pushboolean(L, lua_lessthan(L, a, getnum));
687+ }
688+ else if EQ("equal") {
689+ int a = getnum;
690+ lua_pushboolean(L, lua_equal(L, a, getnum));
691+ }
474692 else if EQ("rawcall") {
475693 int narg = getnum;
476694 int nres = getnum;
477− lua_rawcall(L, narg, nres);
695+ lua_call(L, narg, nres);
478696 }
479697 else if EQ("call") {
480698 int narg = getnum;
481699 int nres = getnum;
482− lua_call(L, narg, nres);
700+ lua_pcall(L, narg, nres, 0);
701+ }
702+ else if EQ("loadstring") {
703+ size_t sl;
704+ const char *s = luaL_checklstring(L, getnum, &sl);
705+ luaL_loadbuffer(L, s, sl, s);
483706 }
484− else if EQ("dostring") {
485− lua_dostring(L, luaL_check_string(L, getnum));
707+ else if EQ("loadfile") {
708+ luaL_loadfile(L, luaL_checkstring(L, getnum));
486709 }
487− else if EQ("settagmethod") {
488− int tag = getnum;
489− const char *event = getname;
490− lua_settagmethod(L, tag, event);
710+ else if EQ("setmetatable") {
711+ lua_setmetatable(L, getnum);
491712 }
492− else if EQ("gettagmethod") {
493− int tag = getnum;
494− const char *event = getname;
495− lua_gettagmethod(L, tag, event);
713+ else if EQ("getmetatable") {
714+ if (lua_getmetatable(L, getnum) == 0)
715+ lua_pushnil(L);
496716 }
497717 else if EQ("type") {
498718 lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
499719 }
500− else luaL_verror(L, "unknown instruction %.30s", buff);
720+ else if EQ("getn") {
721+ int i = getnum;
722+ lua_pushintegral(L, luaL_getn(L, i));
723+ }
724+ else if EQ("setn") {
725+ int i = getnum;
726+ int n = cast(int, lua_tonumber(L, -1));
727+ luaL_setn(L, i, n);
728+ lua_pop(L, 1);
729+ }
730+ else luaL_error(L, "unknown instruction %s", buff);
501731 }
502732 return 0;
503733 }
@@ -505,39 +735,118 @@ static int testC (lua_State *L) { · 1 unmodified line
505735 /* }====================================================== */
506736
507737
738+/*
739+** {======================================================
740+** tests for yield inside hooks
741+** =======================================================
742+*/
743+
744+static void yieldf (lua_State *L, lua_Debug *ar) {
745+ lua_yield(L, 0);
746+}
747+
748+static int setyhook (lua_State *L) {
749+ if (lua_isnoneornil(L, 1))
750+ lua_sethook(L, NULL, 0, 0); /* turn off hooks */
751+ else {
752+ const char *smask = luaL_checkstring(L, 1);
753+ int count = luaL_optint(L, 2, 0);
754+ int mask = 0;
755+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
756+ if (count > 0) mask |= LUA_MASKCOUNT;
757+ lua_sethook(L, yieldf, mask, count);
758+ }
759+ return 0;
760+}
761+
762+
763+static int coresume (lua_State *L) {
764+ int status;
765+ lua_State *co = lua_tothread(L, 1);
766+ luaL_argcheck(L, co, 1, "coroutine expected");
767+ status = lua_resume(co, 0);
768+ if (status != 0) {
769+ lua_pushboolean(L, 0);
770+ lua_insert(L, -2);
771+ return 2; /* return false + error message */
772+ }
773+ else {
774+ lua_pushboolean(L, 1);
775+ return 1;
776+ }
777+}
778+
779+/* }====================================================== */
780+
781+
508782
509783 static const struct luaL_reg tests_funcs[] = {
510784 {"hash", hash_query},
511785 {"limits", get_limits},
512786 {"listcode", listcode},
513− {"liststrings", liststrings},
787+ {"listk", listk},
514788 {"listlocals", listlocals},
515789 {"loadlib", loadlib},
790+ {"stacklevel", stacklevel},
516791 {"querystr", string_query},
517792 {"querytab", table_query},
793+ {"doit", test_do},
518794 {"testC", testC},
519795 {"ref", tref},
520796 {"getref", getref},
521797 {"unref", unref},
798+ {"d2s", d2s},
799+ {"s2d", s2d},
800+ {"metatable", metatable},
801+ {"upvalue", upvalue},
522802 {"newuserdata", newuserdata},
803+ {"pushuserdata", pushuserdata},
523804 {"udataval", udataval},
805+ {"doonnewstack", doonnewstack},
524806 {"newstate", newstate},
525807 {"closestate", closestate},
526808 {"doremote", doremote},
527− {"settagmethod", settagmethod},
528− {"equal", equal},
529− {"totalmem", mem_query}
809+ {"log2", log2_aux},
810+ {"int2fb", int2fb_aux},
811+ {"totalmem", mem_query},
812+ {"resume", coresume},
813+ {"setyhook", setyhook},
814+ {NULL, NULL}
530815 };
531816
532817
533−void luaB_opentests (lua_State *L) {
534− lua_newtable(L);
535− lua_getglobals(L);
536− lua_pushvalue(L, -2);
537− lua_setglobals(L);
538− luaL_openl(L, tests_funcs); /* open functions inside new table */
539− lua_setglobals(L); /* restore old table of globals */
540− lua_setglobal(L, "T"); /* set new table as global T */
818+static void fim (void) {
819+ if (!islocked)
820+ lua_close(lua_state);
821+ lua_assert(memdebug_numblocks == 0);
822+ lua_assert(memdebug_total == 0);
823+}
824+
825+
826+static int l_panic (lua_State *L) {
827+ UNUSED(L);
828+ fprintf(stderr, "unable to recover; exiting\n");
829+ return 0;
830+}
831+
832+
833+int luaB_opentests (lua_State *L) {
834+ lua_atpanic(L, l_panic);
835+ lua_userstateopen(L); /* init lock */
836+ lua_state = L; /* keep first state to be opened */
837+ luaL_openlib(L, "T", tests_funcs, 0);
838+ atexit(fim);
839+ return 0;
840+}
841+
842+
843+#undef main
844+int main (int argc, char *argv[]) {
845+ char *limit = getenv("MEMLIMIT");
846+ if (limit)
847+ memdebug_memlimit = strtoul(limit, NULL, 10);
848+ l_main(argc, argv);
849+ return 0;
541850 }
542851
543852 #endif
src/ltm.c+38−131
@@ -1,163 +1,70 @@
11 /*
2−** $Id: ltm.c,v 1.56 2000/10/31 13:10:24 roberto Exp $
2+** $Id: ltm.c,v 1.106 2003/04/03 13:35:34 roberto Exp $
33 ** Tag methods
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <stdio.h>
98 #include <string.h>
109
10+#define ltm_c
11+
1112 #include "lua.h"
1213
13−#include "ldo.h"
14−#include "lmem.h"
1514 #include "lobject.h"
1615 #include "lstate.h"
16+#include "lstring.h"
17+#include "ltable.h"
1718 #include "ltm.h"
1819
1920
20−const char *const luaT_eventname[] = { /* ORDER TM */
21− "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub",
22− "mul", "div", "pow", "unm", "lt", "concat", "gc", "function",
23− "le", "gt", "ge", /* deprecated options!! */
24− NULL
25−};
26−
27−
28−static int findevent (const char *name) {
29− int i;
30− for (i=0; luaT_eventname[i]; i++)
31− if (strcmp(luaT_eventname[i], name) == 0)
32− return i;
33− return -1; /* name not found */
34−}
35−
36−
37−static int luaI_checkevent (lua_State *L, const char *name, int t) {
38− int e = findevent(name);
39− if (e >= TM_N)
40− luaO_verror(L, "event `%.50s' is deprecated", name);
41− if (e == TM_GC && t == LUA_TTABLE)
42− luaO_verror(L, "event `gc' for tables is deprecated");
43− if (e < 0)
44− luaO_verror(L, "`%.50s' is not a valid event name", name);
45− return e;
46−}
47−
48−
4921
50−/* events in LUA_TNIL are all allowed, since this is used as a
51−* 'placeholder' for "default" fallbacks
52−*/
53−/* ORDER LUA_T, ORDER TM */
54−static const char luaT_validevents[NUM_TAGS][TM_N] = {
55− {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
56− {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
57− {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
58− {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
59− {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
60− {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
22+const char *const luaT_typenames[] = {
23+ "nil", "boolean", "userdata", "number",
24+ "string", "table", "function", "userdata", "thread"
6125 };
6226
63−int luaT_validevent (int t, int e) { /* ORDER LUA_T */
64− return (t >= NUM_TAGS) ? 1 : luaT_validevents[t][e];
65−}
66−
67−
68−static void init_entry (lua_State *L, int tag) {
69− int i;
70− for (i=0; i<TM_N; i++)
71− luaT_gettm(L, tag, i) = NULL;
72− L->TMtable[tag].collected = NULL;
73−}
74−
7527
7628 void luaT_init (lua_State *L) {
77− int t;
78− luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT);
79− L->nblocks += NUM_TAGS*sizeof(struct TM);
80− L->last_tag = NUM_TAGS-1;
81− for (t=0; t<=L->last_tag; t++)
82− init_entry(L, t);
83−}
84−
85−
86−LUA_API int lua_newtag (lua_State *L) {
87− luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM,
88− "tag table overflow", MAX_INT);
89− L->nblocks += sizeof(struct TM);
90− L->last_tag++;
91− init_entry(L, L->last_tag);
92− return L->last_tag;
93−}
94−
95−
96−static void checktag (lua_State *L, int tag) {
97− if (!(0 <= tag && tag <= L->last_tag))
98− luaO_verror(L, "%d is not a valid tag", tag);
99−}
100−
101−void luaT_realtag (lua_State *L, int tag) {
102− if (!validtag(tag))
103− luaO_verror(L, "tag %d was not created by `newtag'", tag);
104−}
105−
106−
107−LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
108− int e;
109− checktag(L, tagto);
110− checktag(L, tagfrom);
111− for (e=0; e<TM_N; e++) {
112− if (luaT_validevent(tagto, e))
113− luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e);
114− }
115− return tagto;
116−}
117−
118−
119−int luaT_tag (const TObject *o) {
120− int t = ttype(o);
121− switch (t) {
122− case LUA_TUSERDATA: return tsvalue(o)->u.d.tag;
123− case LUA_TTABLE: return hvalue(o)->htag;
124− default: return t;
29+ static const char *const luaT_eventname[] = { /* ORDER TM */
30+ "__index", "__newindex",
31+ "__gc", "__mode", "__eq",
32+ "__add", "__sub", "__mul", "__div",
33+ "__pow", "__unm", "__lt", "__le",
34+ "__concat", "__call"
35+ };
36+ int i;
37+ for (i=0; i<TM_N; i++) {
38+ G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
39+ luaS_fix(G(L)->tmname[i]); /* never collect these names */
12540 }
12641 }
12742
12843
129−LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
130− int e;
131− e = luaI_checkevent(L, event, t);
132− checktag(L, t);
133− if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) {
134− clvalue(L->top) = luaT_gettm(L, t, e);
135− ttype(L->top) = LUA_TFUNCTION;
44+/*
45+** function to be used with macro "fasttm": optimized for absence of
46+** tag methods
47+*/
48+const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
49+ const TObject *tm = luaH_getstr(events, ename);
50+ lua_assert(event <= TM_EQ);
51+ if (ttisnil(tm)) { /* no tag method? */
52+ events->flags |= cast(lu_byte, 1u<<event); /* cache this fact */
53+ return NULL;
13654 }
137− else
138− ttype(L->top) = LUA_TNIL;
139− incr_top;
55+ else return tm;
14056 }
14157
14258
143−LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
144− int e = luaI_checkevent(L, event, t);
145− checktag(L, t);
146− if (!luaT_validevent(t, e))
147− luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
148− luaT_eventname[e], luaO_typenames[t],
149− (t == LUA_TTABLE || t == LUA_TUSERDATA) ?
150− " with default tag" : "");
151− switch (ttype(L->top - 1)) {
152− case LUA_TNIL:
153− luaT_gettm(L, t, e) = NULL;
154− break;
155− case LUA_TFUNCTION:
156− luaT_gettm(L, t, e) = clvalue(L->top - 1);
157− break;
59+const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
60+ TString *ename = G(L)->tmname[event];
61+ switch (ttype(o)) {
62+ case LUA_TTABLE:
63+ return luaH_getstr(hvalue(o)->metatable, ename);
64+ case LUA_TUSERDATA:
65+ return luaH_getstr(uvalue(o)->uv.metatable, ename);
15866 default:
159− lua_error(L, "tag method must be a function (or nil)");
67+ return &luaO_nilobject;
16068 }
161− L->top--;
16269 }
16370
src/ltm.h+14−22
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ltm.h,v 1.18 2000/10/05 13:00:17 roberto Exp $
2+** $Id: ltm.h,v 1.41 2002/11/14 11:51:50 roberto Exp $
33 ** Tag methods
44 ** See Copyright Notice in lua.h
55 */
@@ -9,18 +9,18 @@ · 3 unmodified lines
99
1010
1111 #include "lobject.h"
12−#include "lstate.h"
12+
1313
1414 /*
1515 * WARNING: if you change the order of this enumeration,
1616 * grep "ORDER TM"
1717 */
1818 typedef enum {
19− TM_GETTABLE = 0,
20− TM_SETTABLE,
2119 TM_INDEX,
22− TM_GETGLOBAL,
23− TM_SETGLOBAL,
20+ TM_NEWINDEX,
21+ TM_GC,
22+ TM_MODE,
23+ TM_EQ, /* last tag method with `fast' access */
2424 TM_ADD,
2525 TM_SUB,
2626 TM_MUL,
@@ -28,32 +28,24 @@ typedef enum { · 1 unmodified line
2828 TM_POW,
2929 TM_UNM,
3030 TM_LT,
31+ TM_LE,
3132 TM_CONCAT,
32− TM_GC,
33− TM_FUNCTION,
33+ TM_CALL,
3434 TM_N /* number of elements in the enum */
3535 } TMS;
3636
3737
38−struct TM {
39− Closure *method[TM_N];
40− TString *collected; /* list of garbage-collected udata with this tag */
41−};
42−
43−
44−#define luaT_gettm(L,tag,event) (L->TMtable[tag].method[event])
45−#define luaT_gettmbyObj(L,o,e) (luaT_gettm((L),luaT_tag(o),(e)))
46−
4738
48−#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag)
39+#define gfasttm(g,et,e) \
40+ (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
4941
50−extern const char *const luaT_eventname[];
42+#define fasttm(l,et,e) gfasttm(G(l), et, e)
5143
5244
45+const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
46+const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event);
5347 void luaT_init (lua_State *L);
54−void luaT_realtag (lua_State *L, int tag);
55−int luaT_tag (const TObject *o);
56−int luaT_validevent (int t, int e); /* used by compatibility module */
5748
49+extern const char *const luaT_typenames[];
5850
5951 #endif
src/lua/Makefile+4−5
@@ -4,17 +4,16 @@ LUA= ../.. · 3 unmodified lines
44
55 include $(LUA)/config
66
7−EXTRA_DEFS= $(POSIX)
8−
7+EXTRA_DEFS= $(USERCONF)
98 OBJS= lua.o
109 SRCS= lua.c
1110
1211 T= $(BIN)/lua
1312
14−all: $T
13+all: $T
1514
16−$T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
17− $(CC) -o $@ $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS)
15+$T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
16+ $(CC) -o $@ $(MYLDFLAGS) $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS) $(DLLIB)
1817
1918 $(LIB)/liblua.a:
2019 cd ..; $(MAKE)
src/lua/README+21−29
@@ -2,39 +2,31 @@ This is lua, a sample Lua interpreter. · 1 unmodified line
22 It can be used as a batch interpreter and also interactively.
33 There are man pages for it in both nroff and html in ../../doc.
44
5−Here are the options that it understands:
5+Usage: ./lua [options] [script [args]]. Available options are:
66 - execute stdin as a file
7− -c close Lua when exiting
87 -e stat execute string `stat'
9− -f name execute file `name' with remaining arguments in table `arg'
10− -i enter interactive mode with prompt
11− -q enter interactive mode without prompt
12− -sNUM set stack size to NUM (must be the first option)
13− -v print version information
14− a=b set global `a' to string `b'
15− name execute file `name'
8+ -i enter interactive mode after executing `script'
9+ -l name load and run library `name'
10+ -v show version information
11+ -- stop handling options
1612
17−If no options are given, then it reads lines from stdin and executes them
18−as they are read -- so, each line must contain a complete statement.
19−To span a statement across several lines, end each line with a backslash '\'.
13+This interpreter is suitable for using Lua as a standalone language; it loads
14+all standard libraries. For a minimal interpreter, see ../../etc/min.c.
2015
21−To change the prompt, set the global variable _PROMPT to whatever you want.
22−You can do this after calling the interpreter or on the command line with
23− lua _PROMPT="lua: " -i
24−for example. Note that you need "-i" in this case.
16+If your application simply exports new functions to Lua (which is common),
17+then you can use this interpreter (almost) unmodified, as follows:
2518
26−You must be careful when using quotes on the command line because they are
27−usually handled by the shell.
19+* First, define a function
20+ void myinit (lua_State *L)
21+ in your own code. In this function, you should do whatever initializations
22+ are needed by your application, typically exporting your functions to Lua.
23+ (Of course, you can use any name instead of "myinit".)
2824
29−This interpreter is good for using Lua as a standalone language.
30−For a minimal interpreter, see ../../etc/min.c.
25+* Then, #define lua_userinit(L) to be "openstdlibs(L)+myinit(L)".
26+ Here, openstdlibs is a function in lua.c that opens all standard libraries.
27+ If you don't need them, just don't call openstdlibs and open any standard
28+ libraries that you do need in myinit.
3129
32−If your application simply exports new functions to Lua (which is common),
33−then you can use this interpreter (almost) unmodified, as follows:
34−First, define a function
35− void myinit (lua_State *L)
36−in your own code. In this function, you should do whatever initializations
37−are needed by your application, typically exporting your functions to Lua.
38−Then, add a call "myinit(L)" in lua.c after the place marked
39− "add your libraries here"
40−Of course, you can use any name instead of "myinit".
30+* Finally, remember to link your C code when building lua.
31+
32+For other customizations, see ../../etc/config.c.
src/lua/lua.c+332−216
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lua.c,v 1.55 2000/10/20 16:36:32 roberto Exp $
2+** $Id: lua.c,v 1.122 2003/04/03 13:34:42 roberto Exp $
33 ** Lua stand-alone interpreter
44 ** See Copyright Notice in lua.h
55 */
@@ -10,313 +10,429 @@ · 4 unmodified lines
1010 #include <stdlib.h>
1111 #include <string.h>
1212
13+#define lua_c
14+
1315 #include "lua.h"
1416
15−#include "luadebug.h"
17+#include "lauxlib.h"
1618 #include "lualib.h"
1719
1820
19−static lua_State *L = NULL;
21+/*
22+** generic extra include file
23+*/
24+#ifdef LUA_USERCONFIG
25+#include LUA_USERCONFIG
26+#endif
27+
28+
29+/*
30+** definition of `isatty'
31+*/
32+#ifdef _POSIX_C_SOURCE
33+#include <unistd.h>
34+#define stdin_is_tty() isatty(0)
35+#else
36+#define stdin_is_tty() 1 /* assume stdin is a tty */
37+#endif
38+
2039
2140
2241 #ifndef PROMPT
2342 #define PROMPT "> "
2443 #endif
2544
26−#ifdef _POSIX_SOURCE
27−#include <unistd.h>
28−#else
29−static int isatty (int x) { return x==0; } /* assume stdin is a tty */
45+
46+#ifndef PROMPT2
47+#define PROMPT2 ">> "
3048 #endif
3149
50+#ifndef PROGNAME
51+#define PROGNAME "lua"
52+#endif
3253
33−/*
34−** global options
35−*/
36−struct Options {
37− int toclose;
38− int stacksize;
39−};
54+#ifndef lua_userinit
55+#define lua_userinit(L) openstdlibs(L)
56+#endif
4057
4158
42−typedef void (*handler)(int); /* type for signal actions */
59+#ifndef LUA_EXTRALIBS
60+#define LUA_EXTRALIBS /* empty */
61+#endif
4362
44−static void laction (int i);
4563
64+static lua_State *L = NULL;
4665
47−static lua_Hook old_linehook = NULL;
48−static lua_Hook old_callhook = NULL;
66+static const char *progname = PROGNAME;
4967
5068
51−static void userinit (void) {
52− lua_baselibopen(L);
53− lua_iolibopen(L);
54− lua_strlibopen(L);
55− lua_mathlibopen(L);
56− lua_dblibopen(L);
69+
70+static const luaL_reg lualibs[] = {
71+ {"base", luaopen_base},
72+ {"table", luaopen_table},
73+ {"io", luaopen_io},
74+ {"string", luaopen_string},
75+ {"math", luaopen_math},
76+ {"debug", luaopen_debug},
77+ {"loadlib", luaopen_loadlib},
5778 /* add your libraries here */
58−}
79+ LUA_EXTRALIBS
80+ {NULL, NULL}
81+};
5982
6083
61−static handler lreset (void) {
62− return signal(SIGINT, laction);
63−}
6484
65−
66−static void lstop (void) {
67− lua_setlinehook(L, old_linehook);
68− lua_setcallhook(L, old_callhook);
69− lreset();
70− lua_error(L, "interrupted!");
85+static void lstop (lua_State *l, lua_Debug *ar) {
86+ (void)ar; /* unused arg. */
87+ lua_sethook(l, NULL, 0, 0);
88+ luaL_error(l, "interrupted!");
7189 }
7290
7391
7492 static void laction (int i) {
75− (void)i; /* to avoid warnings */
76− signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
93+ signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
7794 terminate process (default action) */
78− old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
79− old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
80−}
81−
82−
83−static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
84− int res;
85− handler h = lreset();
86− int top = lua_gettop(L);
87− res = f(L, name); /* dostring | dofile */
88− lua_settop(L, top); /* remove eventual results */
89− signal(SIGINT, h); /* restore old action */
90− /* Lua gives no message in such cases, so lua.c provides one */
91− if (res == LUA_ERRMEM) {
92− fprintf(stderr, "lua: memory allocation error\n");
93− }
94− else if (res == LUA_ERRERR)
95− fprintf(stderr, "lua: error in error message\n");
96− return res;
95+ lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
9796 }
9897
9998
100−static void print_message (void) {
99+static void print_usage (void) {
101100 fprintf(stderr,
102− "usage: lua [options]. Available options are:\n"
101+ "usage: %s [options] [script [args]].\n"
102+ "Available options are:\n"
103103 " - execute stdin as a file\n"
104− " -c close Lua when exiting\n"
105104 " -e stat execute string `stat'\n"
106− " -f name execute file `name' with remaining arguments in table `arg'\n"
107− " -i enter interactive mode with prompt\n"
108− " -q enter interactive mode without prompt\n"
109− " -sNUM set stack size to NUM (must be the first option)\n"
110− " -v print version information\n"
111− " a=b set global `a' to string `b'\n"
112− " name execute file `name'\n"
113−);
105+ " -i enter interactive mode after executing `script'\n"
106+ " -l name load and run library `name'\n"
107+ " -v show version information\n"
108+ " -- stop handling options\n" ,
109+ progname);
114110 }
115111
116112
117−static void print_version (void) {
118− printf("%.80s %.80s\n", LUA_VERSION, LUA_COPYRIGHT);
113+static void l_message (const char *pname, const char *msg) {
114+ if (pname) fprintf(stderr, "%s: ", pname);
115+ fprintf(stderr, "%s\n", msg);
119116 }
120117
121118
122−static void assign (char *arg) {
123− char *eq = strchr(arg, '=');
124− *eq = '\0'; /* spilt `arg' in two strings (name & value) */
125− lua_pushstring(L, eq+1);
126− lua_setglobal(L, arg);
119+static int report (int status) {
120+ const char *msg;
121+ if (status) {
122+ msg = lua_tostring(L, -1);
123+ if (msg == NULL) msg = "(error with no message)";
124+ l_message(progname, msg);
125+ lua_pop(L, 1);
126+ }
127+ return status;
127128 }
128129
129130
130−static void getargs (char *argv[]) {
131+static int lcall (int narg, int clear) {
132+ int status;
133+ int base = lua_gettop(L) - narg; /* function index */
134+ lua_pushliteral(L, "_TRACEBACK");
135+ lua_rawget(L, LUA_GLOBALSINDEX); /* get traceback function */
136+ lua_insert(L, base); /* put it under chunk and args */
137+ signal(SIGINT, laction);
138+ status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
139+ signal(SIGINT, SIG_DFL);
140+ lua_remove(L, base); /* remove traceback function */
141+ return status;
142+}
143+
144+
145+static void print_version (void) {
146+ l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
147+}
148+
149+
150+static void getargs (char *argv[], int n) {
131151 int i;
132152 lua_newtable(L);
133153 for (i=0; argv[i]; i++) {
134− /* arg[i] = argv[i] */
135− lua_pushnumber(L, i);
154+ lua_pushnumber(L, i - n);
136155 lua_pushstring(L, argv[i]);
137− lua_settable(L, -3);
156+ lua_rawset(L, -3);
138157 }
139158 /* arg.n = maximum index in table `arg' */
140− lua_pushstring(L, "n");
141− lua_pushnumber(L, i-1);
142− lua_settable(L, -3);
159+ lua_pushliteral(L, "n");
160+ lua_pushnumber(L, i-n-1);
161+ lua_rawset(L, -3);
143162 }
144163
145164
146−static int l_getargs (lua_State *l) {
147− char **argv = (char **)lua_touserdata(l, -1);
148− getargs(argv);
149− return 1;
165+static int docall (int status) {
166+ if (status == 0) status = lcall(0, 1);
167+ return report(status);
150168 }
151169
152170
153−static int file_input (const char *argv) {
154− int result = ldo(lua_dofile, argv);
155− if (result) {
156− if (result == LUA_ERRFILE) {
157− fprintf(stderr, "lua: cannot execute file ");
158− perror(argv);
159− }
160− return EXIT_FAILURE;
171+static int file_input (const char *name) {
172+ return docall(luaL_loadfile(L, name));
173+}
174+
175+
176+static int dostring (const char *s, const char *name) {
177+ return docall(luaL_loadbuffer(L, s, strlen(s), name));
178+}
179+
180+
181+static int load_file (const char *name) {
182+ lua_pushliteral(L, "require");
183+ lua_rawget(L, LUA_GLOBALSINDEX);
184+ if (!lua_isfunction(L, -1)) { /* no `require' defined? */
185+ lua_pop(L, 1);
186+ return file_input(name);
187+ }
188+ else {
189+ lua_pushstring(L, name);
190+ return report(lcall(1, 1));
161191 }
162− else
163− return EXIT_SUCCESS;
164192 }
165193
166194
167−/* maximum length of an input string */
195+/*
196+** this macro can be used by some `history' system to save lines
197+** read in manual input
198+*/
199+#ifndef lua_saveline
200+#define lua_saveline(L,line) /* empty */
201+#endif
202+
203+
204+/*
205+** this macro defines a function to show the prompt and reads the
206+** next line for manual input
207+*/
208+#ifndef lua_readline
209+#define lua_readline(L,prompt) readline(L,prompt)
210+
211+/* maximum length of an input line */
168212 #ifndef MAXINPUT
169−#define MAXINPUT BUFSIZ
213+#define MAXINPUT 512
170214 #endif
171215
172−static void manual_input (int version, int prompt) {
173− int cont = 1;
174− if (version) print_version();
175− while (cont) {
176− char buffer[MAXINPUT];
177− int i = 0;
178− if (prompt) {
179− const char *s;
180− lua_getglobal(L, "_PROMPT");
181− s = lua_tostring(L, -1);
182− if (!s) s = PROMPT;
183− fputs(s, stdout);
184− lua_pop(L, 1); /* remove global */
185− }
186− for(;;) {
187− int c = getchar();
188− if (c == EOF) {
189− cont = 0;
190− break;
191− }
192− else if (c == '\n') {
193− if (i>0 && buffer[i-1] == '\\')
194− buffer[i-1] = '\n';
195− else break;
196− }
197− else if (i >= MAXINPUT-1) {
198− fprintf(stderr, "lua: input line too long\n");
199− break;
200− }
201− else buffer[i++] = (char)c;
216+
217+static int readline (lua_State *l, const char *prompt) {
218+ static char buffer[MAXINPUT];
219+ if (prompt) {
220+ fputs(prompt, stdout);
221+ fflush(stdout);
222+ }
223+ if (fgets(buffer, sizeof(buffer), stdin) == NULL)
224+ return 0; /* read fails */
225+ else {
226+ lua_pushstring(l, buffer);
227+ return 1;
228+ }
229+}
230+
231+#endif
232+
233+
234+static const char *get_prompt (int firstline) {
235+ const char *p = NULL;
236+ lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2");
237+ lua_rawget(L, LUA_GLOBALSINDEX);
238+ p = lua_tostring(L, -1);
239+ if (p == NULL) p = (firstline ? PROMPT : PROMPT2);
240+ lua_pop(L, 1); /* remove global */
241+ return p;
242+}
243+
244+
245+static int incomplete (int status) {
246+ if (status == LUA_ERRSYNTAX &&
247+ strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
248+ lua_pop(L, 1);
249+ return 1;
250+ }
251+ else
252+ return 0;
253+}
254+
255+
256+static int load_string (void) {
257+ int status;
258+ lua_settop(L, 0);
259+ if (lua_readline(L, get_prompt(1)) == 0) /* no input? */
260+ return -1;
261+ if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */
262+ lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */
263+ lua_remove(L, -2); /* remove original line */
264+ }
265+ for (;;) { /* repeat until gets a complete line */
266+ status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
267+ if (!incomplete(status)) break; /* cannot try to add lines? */
268+ if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */
269+ return -1;
270+ lua_concat(L, lua_gettop(L)); /* join lines */
271+ }
272+ lua_saveline(L, lua_tostring(L, 1));
273+ lua_remove(L, 1); /* remove line */
274+ return status;
275+}
276+
277+
278+static void manual_input (void) {
279+ int status;
280+ const char *oldprogname = progname;
281+ progname = NULL;
282+ while ((status = load_string()) != -1) {
283+ if (status == 0) status = lcall(0, 0);
284+ report(status);
285+ if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
286+ lua_getglobal(L, "print");
287+ lua_insert(L, 1);
288+ if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
289+ l_message(progname, lua_pushfstring(L, "error calling `print' (%s)",
290+ lua_tostring(L, -1)));
202291 }
203− buffer[i] = '\0';
204− ldo(lua_dostring, buffer);
205− lua_settop(L, 0); /* remove eventual results */
206292 }
207− printf("\n");
293+ lua_settop(L, 0); /* clear stack */
294+ fputs("\n", stdout);
295+ progname = oldprogname;
208296 }
209297
210298
211−static int handle_argv (char *argv[], struct Options *opt) {
212− if (opt->stacksize > 0) argv++; /* skip option `-s' (if present) */
213− if (*argv == NULL) { /* no more arguments? */
214− if (isatty(0)) {
215− manual_input(1, 1);
299+static int handle_argv (char *argv[], int *interactive) {
300+ if (argv[1] == NULL) { /* no more arguments? */
301+ if (stdin_is_tty()) {
302+ print_version();
303+ manual_input();
216304 }
217305 else
218− ldo(lua_dofile, NULL); /* executes stdin as a file */
306+ file_input(NULL); /* executes stdin as a file */
219307 }
220308 else { /* other arguments; loop over them */
221309 int i;
222− for (i = 0; argv[i] != NULL; i++) {
223− if (argv[i][0] != '-') { /* not an option? */
224− if (strchr(argv[i], '='))
225− assign(argv[i]);
226− else
227− if (file_input(argv[i]) != EXIT_SUCCESS)
228− return EXIT_FAILURE; /* stop if file fails */
229− }
230− else switch (argv[i][1]) { /* option */
231− case 0: {
232− ldo(lua_dofile, NULL); /* executes stdin as a file */
233− break;
234− }
235− case 'i': {
236− manual_input(0, 1);
237− break;
238− }
239− case 'q': {
240− manual_input(0, 0);
241− break;
242− }
243− case 'c': {
244− opt->toclose = 1;
245− break;
310+ for (i = 1; argv[i] != NULL; i++) {
311+ if (argv[i][0] != '-') break; /* not an option? */
312+ switch (argv[i][1]) { /* option */
313+ case '-': { /* `--' */
314+ if (argv[i][2] != '\0') {
315+ print_usage();
316+ return 1;
246317 }
247− case 'v': {
248− print_version();
249− break;
250− }
251− case 'e': {
252− i++;
253− if (argv[i] == NULL) {
254− print_message();
255− return EXIT_FAILURE;
256− }
257− if (ldo(lua_dostring, argv[i]) != 0) {
258− fprintf(stderr, "lua: error running argument `%.99s'\n", argv[i]);
259− return EXIT_FAILURE;
260− }
261− break;
262− }
263− case 'f': {
264− i++;
265− if (argv[i] == NULL) {
266− print_message();
267− return EXIT_FAILURE;
268− }
269− getargs(argv+i); /* collect remaining arguments */
270− lua_setglobal(L, "arg");
271− return file_input(argv[i]); /* stop scanning arguments */
272− }
273− case 's': {
274− fprintf(stderr, "lua: stack size (`-s') must be the first option\n");
275− return EXIT_FAILURE;
318+ i++; /* skip this argument */
319+ goto endloop; /* stop handling arguments */
320+ }
321+ case '\0': {
322+ file_input(NULL); /* executes stdin as a file */
323+ break;
324+ }
325+ case 'i': {
326+ *interactive = 1;
327+ break;
328+ }
329+ case 'v': {
330+ print_version();
331+ break;
332+ }
333+ case 'e': {
334+ const char *chunk = argv[i] + 2;
335+ if (*chunk == '\0') chunk = argv[++i];
336+ if (chunk == NULL) {
337+ print_usage();
338+ return 1;
276339 }
277− default: {
278− print_message();
279− return EXIT_FAILURE;
340+ if (dostring(chunk, "=<command line>") != 0)
341+ return 1;
342+ break;
343+ }
344+ case 'l': {
345+ const char *filename = argv[i] + 2;
346+ if (*filename == '\0') filename = argv[++i];
347+ if (filename == NULL) {
348+ print_usage();
349+ return 1;
280350 }
351+ if (load_file(filename))
352+ return 1; /* stop if file fails */
353+ break;
354+ }
355+ case 'c': {
356+ l_message(progname, "option `-c' is deprecated");
357+ break;
358+ }
359+ case 's': {
360+ l_message(progname, "option `-s' is deprecated");
361+ break;
362+ }
363+ default: {
364+ print_usage();
365+ return 1;
281366 }
367+ }
368+ } endloop:
369+ if (argv[i] != NULL) {
370+ const char *filename = argv[i];
371+ getargs(argv, i); /* collect arguments */
372+ lua_setglobal(L, "arg");
373+ return file_input(filename); /* stop scanning arguments */
282374 }
283375 }
284− return EXIT_SUCCESS;
376+ return 0;
285377 }
286378
287379
288−static void getstacksize (int argc, char *argv[], struct Options *opt) {
289− if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 's') {
290− int stacksize = atoi(&argv[1][2]);
291− if (stacksize <= 0) {
292− fprintf(stderr, "lua: invalid stack size ('%.20s')\n", &argv[1][2]);
293− exit(EXIT_FAILURE);
294− }
295− opt->stacksize = stacksize;
380+static void openstdlibs (lua_State *l) {
381+ const luaL_reg *lib = lualibs;
382+ for (; lib->func; lib++) {
383+ lib->func(l); /* open library */
384+ lua_settop(l, 0); /* discard any results */
296385 }
386+}
387+
388+
389+static int handle_luainit (void) {
390+ const char *init = getenv("LUA_INIT");
391+ if (init == NULL) return 0; /* status OK */
392+ else if (init[0] == '@')
393+ return file_input(init+1);
297394 else
298− opt->stacksize = 0; /* no stack size */
395+ return dostring(init, "=LUA_INIT");
299396 }
300397
301398
302−static void register_getargs (char *argv[]) {
303− lua_pushuserdata(L, argv);
304− lua_pushcclosure(L, l_getargs, 1);
305− lua_setglobal(L, "getargs");
399+struct Smain {
400+ int argc;
401+ char **argv;
402+ int status;
403+};
404+
405+
406+static int pmain (lua_State *l) {
407+ struct Smain *s = (struct Smain *)lua_touserdata(l, 1);
408+ int status;
409+ int interactive = 0;
410+ if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
411+ L = l;
412+ lua_userinit(l); /* open libraries */
413+ status = handle_luainit();
414+ if (status == 0) {
415+ status = handle_argv(s->argv, &interactive);
416+ if (status == 0 && interactive) manual_input();
417+ }
418+ s->status = status;
419+ return 0;
306420 }
307421
308422
309423 int main (int argc, char *argv[]) {
310− struct Options opt;
311424 int status;
312− opt.toclose = 0;
313− getstacksize(argc, argv, &opt); /* handle option `-s' */
314− L = lua_open(opt.stacksize); /* create state */
315− userinit(); /* open libraries */
316− register_getargs(argv); /* create `getargs' function */
317− status = handle_argv(argv+1, &opt);
318− if (opt.toclose)
319− lua_close(L);
320− return status;
425+ struct Smain s;
426+ lua_State *l = lua_open(); /* create state */
427+ if (l == NULL) {
428+ l_message(argv[0], "cannot create state: not enough memory");
429+ return EXIT_FAILURE;
430+ }
431+ s.argc = argc;
432+ s.argv = argv;
433+ status = lua_cpcall(l, &pmain, &s);
434+ report(status);
435+ lua_close(l);
436+ return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
321437 }
322438
src/luac/Makefile+13−6
@@ -4,20 +4,27 @@ LUA= ../.. · 3 unmodified lines
44
55 include $(LUA)/config
66
7−INCS= -I$(INC) $(EXTRA_INCS) -I..
8−OBJS= dump.o luac.o opt.o print.o stubs.o
9−SRCS= dump.c luac.c opt.c print.c stubs.c luac.h print.h
7+INCS= -I$(INC) -I.. $(EXTRA_INCS)
8+OBJS= luac.o print.o lopcodes.o
9+SRCS= luac.c print.c
1010
1111 T= $(BIN)/luac
1212
13−all: $T
13+all: $T
1414
15−$T: $(OBJS) $(LIB)/liblua.a
16− $(CC) -o $@ $(OBJS) -L$(LIB) -llua
15+$T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
16+ $(CC) -o $@ $(MYLDFLAGS) $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS)
17+
18+# print.c needs opcode names from lopcodes.c
19+lopcodes.o: ../lopcodes.c ../lopcodes.h
20+ $(CC) -o $@ -c $(CFLAGS) -DLUA_OPNAMES ../lopcodes.c
1721
1822 $(LIB)/liblua.a:
1923 cd ..; $(MAKE)
2024
25+$(LIB)/liblualib.a:
26+ cd ../lib; $(MAKE)
27+
2128 clean:
2229 rm -f $(OBJS) $T
2330
src/luac/README+4−8
@@ -1,22 +1,18 @@
11 This is luac, the Lua compiler.
22 There are man pages for it in both nroff and html in ../../doc.
33
4−luac translates Lua programs into binary files that can be loaded and executed
5−with lua_dofile in C or with dofile in Lua.
4+luac translates Lua programs into binary files that can be loaded latter.
65 The main advantages of pre-compiling chunks are: faster loading, protecting
76 source code from user changes, and off-line syntax error detection.
87 luac can also be used to learn about the Lua virtual machine.
98
10−Here are the options that luac understands:
11−
9+Usage: /l/luac/luac [options] [filenames]. Available options are:
1210 - process stdin
1311 -l list
14− -o file output file (default is "luac.out")
12+ -o name output to file `name' (default is "luac.out")
1513 -p parse only
1614 -s strip debug information
17− -t test code integrity
1815 -v show version information
16+ -- stop handling options
1917
2018 luac is also an example of how to use the internals of Lua (politely).
21−Finally, luac does not need the runtime code, and stubs.c makes sure it is not
22−linked into luac. This file also shows how to avoid linking the parser.
src/luac/dump.c+0−121
@@ -1,121 +0,0 @@
1−/*
2−** $Id: dump.c,v 1.30 2000/10/31 16:57:23 lhf Exp $
3−** save bytecodes to file
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include <stdio.h>
8−#include <stdlib.h>
9−#include <string.h>
10−
11−#include "luac.h"
12−
13−#define DumpVector(b,n,size,D) fwrite(b,size,n,D)
14−#define DumpBlock(b,size,D) fwrite(b,size,1,D)
15−#define DumpByte fputc
16−
17−static void DumpInt(int x, FILE* D)
18−{
19− DumpBlock(&x,sizeof(x),D);
20−}
21−
22−static void DumpSize(size_t x, FILE* D)
23−{
24− DumpBlock(&x,sizeof(x),D);
25−}
26−
27−static void DumpNumber(Number x, FILE* D)
28−{
29− DumpBlock(&x,sizeof(x),D);
30−}
31−
32−static void DumpString(const TString* s, FILE* D)
33−{
34− if (s==NULL || s->str==NULL)
35− DumpSize(0,D);
36− else
37− {
38− size_t size=s->len+1; /* include trailing '\0' */
39− DumpSize(size,D);
40− DumpBlock(s->str,size,D);
41− }
42−}
43−
44−static void DumpCode(const Proto* tf, FILE* D)
45−{
46− DumpInt(tf->ncode,D);
47− DumpVector(tf->code,tf->ncode,sizeof(*tf->code),D);
48−}
49−
50−static void DumpLocals(const Proto* tf, FILE* D)
51−{
52− int i,n=tf->nlocvars;
53− DumpInt(n,D);
54− for (i=0; i<n; i++)
55− {
56− DumpString(tf->locvars[i].varname,D);
57− DumpInt(tf->locvars[i].startpc,D);
58− DumpInt(tf->locvars[i].endpc,D);
59− }
60−}
61−
62−static void DumpLines(const Proto* tf, FILE* D)
63−{
64− DumpInt(tf->nlineinfo,D);
65− DumpVector(tf->lineinfo,tf->nlineinfo,sizeof(*tf->lineinfo),D);
66−}
67−
68−static void DumpFunction(const Proto* tf, FILE* D);
69−
70−static void DumpConstants(const Proto* tf, FILE* D)
71−{
72− int i,n;
73− DumpInt(n=tf->nkstr,D);
74− for (i=0; i<n; i++)
75− DumpString(tf->kstr[i],D);
76− DumpInt(tf->nknum,D);
77− DumpVector(tf->knum,tf->nknum,sizeof(*tf->knum),D);
78− DumpInt(n=tf->nkproto,D);
79− for (i=0; i<n; i++)
80− DumpFunction(tf->kproto[i],D);
81−}
82−
83−static void DumpFunction(const Proto* tf, FILE* D)
84−{
85− DumpString(tf->source,D);
86− DumpInt(tf->lineDefined,D);
87− DumpInt(tf->numparams,D);
88− DumpByte(tf->is_vararg,D);
89− DumpInt(tf->maxstacksize,D);
90− DumpLocals(tf,D);
91− DumpLines(tf,D);
92− DumpConstants(tf,D);
93− DumpCode(tf,D);
94− if (ferror(D))
95− {
96− perror("luac: write error");
97− exit(1);
98− }
99−}
100−
101−static void DumpHeader(FILE* D)
102−{
103− DumpByte(ID_CHUNK,D);
104− fputs(SIGNATURE,D);
105− DumpByte(VERSION,D);
106− DumpByte(luaU_endianess(),D);
107− DumpByte(sizeof(int),D);
108− DumpByte(sizeof(size_t),D);
109− DumpByte(sizeof(Instruction),D);
110− DumpByte(SIZE_INSTRUCTION,D);
111− DumpByte(SIZE_OP,D);
112− DumpByte(SIZE_B,D);
113− DumpByte(sizeof(Number),D);
114− DumpNumber(TEST_NUMBER,D);
115−}
116−
117−void luaU_dumpchunk(const Proto* Main, FILE* D)
118−{
119− DumpHeader(D);
120− DumpFunction(Main,D);
121−}
src/luac/luac.c+106−118
@@ -1,6 +1,6 @@
11 /*
2−** $Id: luac.c,v 1.28 2000/11/06 20:06:27 lhf Exp $
3−** lua compiler (saves bytecodes to files; also list binary files)
2+** $Id: luac.c,v 1.44 2003/04/07 20:34:20 lhf Exp $
3+** Lua compiler (saves bytecodes to files; also list bytecodes)
44 ** See Copyright Notice in lua.h
55 */
66
@@ -8,78 +8,80 @@ · 1 unmodified line
88 #include <stdlib.h>
99 #include <string.h>
1010
11−#include "lparser.h"
12−#include "lstate.h"
13−#include "lzio.h"
14−#include "luac.h"
11+#include "lua.h"
12+#include "lauxlib.h"
1513
16−#define OUTPUT "luac.out" /* default output file */
14+#include "lfunc.h"
15+#include "lmem.h"
16+#include "lobject.h"
17+#include "lopcodes.h"
18+#include "lstring.h"
19+#include "lundump.h"
1720
18−static void usage(const char* message, const char* arg);
19−static int doargs(int argc, const char* argv[]);
20−static Proto* load(const char* filename);
21−static FILE* efopen(const char* name, const char* mode);
22−static void strip(Proto* tf);
23−static Proto* combine(Proto** P, int n);
21+#ifndef LUA_DEBUG
22+#define luaB_opentests(L)
23+#endif
2424
25−lua_State* lua_state=NULL; /* lazy! */
25+#ifndef PROGNAME
26+#define PROGNAME "luac" /* program name */
27+#endif
28+
29+#define OUTPUT "luac.out" /* default output file */
2630
2731 static int listing=0; /* list bytecodes? */
2832 static int dumping=1; /* dump bytecodes? */
2933 static int stripping=0; /* strip debug information? */
30−static int testing=0; /* test integrity? */
31−static const char* output=OUTPUT; /* output file name */
34+static char Output[]={ OUTPUT }; /* default output file name */
35+static const char* output=Output; /* output file name */
36+static const char* progname=PROGNAME; /* actual program name */
3237
33−#define IS(s) (strcmp(argv[i],s)==0)
38+static void fatal(const char* message)
39+{
40+ fprintf(stderr,"%s: %s\n",progname,message);
41+ exit(EXIT_FAILURE);
42+}
3443
35−int main(int argc, const char* argv[])
44+static void cannot(const char* name, const char* what, const char* mode)
3645 {
37− Proto** P,*tf;
38− int i=doargs(argc,argv);
39− argc-=i; argv+=i;
40− if (argc<=0) usage("no input files given",NULL);
41− L=lua_open(0);
42− P=luaM_newvector(L,argc,Proto*);
43− for (i=0; i<argc; i++)
44− P[i]=load(IS("-")? NULL : argv[i]);
45− tf=combine(P,argc);
46− if (dumping) luaU_optchunk(tf);
47− if (listing) luaU_printchunk(tf);
48− if (testing) luaU_testchunk(tf);
49− if (dumping)
50− {
51− if (stripping) strip(tf);
52− luaU_dumpchunk(tf,efopen(output,"wb"));
53− }
54− return 0;
46+ fprintf(stderr,"%s: cannot %s %sput file ",progname,what,mode);
47+ perror(name);
48+ exit(EXIT_FAILURE);
5549 }
5650
5751 static void usage(const char* message, const char* arg)
5852 {
5953 if (message!=NULL)
6054 {
61− fprintf(stderr,"luac: "); fprintf(stderr,message,arg); fprintf(stderr,"\n");
55+ fprintf(stderr,"%s: ",progname); fprintf(stderr,message,arg); fprintf(stderr,"\n");
6256 }
6357 fprintf(stderr,
64− "usage: luac [options] [filenames]. Available options are:\n"
58+ "usage: %s [options] [filenames]. Available options are:\n"
6559 " - process stdin\n"
6660 " -l list\n"
67− " -o file output file (default is \"" OUTPUT "\")\n"
61+ " -o name output to file `name' (default is \"" OUTPUT "\")\n"
6862 " -p parse only\n"
6963 " -s strip debug information\n"
70− " -t test code integrity\n"
7164 " -v show version information\n"
72− );
73− exit(1);
65+ " -- stop handling options\n",
66+ progname);
67+ exit(EXIT_FAILURE);
7468 }
7569
76−static int doargs(int argc, const char* argv[])
70+#define IS(s) (strcmp(argv[i],s)==0)
71+
72+static int doargs(int argc, char* argv[])
7773 {
7874 int i;
75+ if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
7976 for (i=1; i<argc; i++)
8077 {
81− if (*argv[i]!='-') /* end of options */
78+ if (*argv[i]!='-') /* end of options; keep it */
79+ break;
80+ else if (IS("--")) /* end of options; skip it */
81+ {
82+ ++i;
8283 break;
84+ }
8385 else if (IS("-")) /* end of options; use stdin */
8486 return i;
8587 else if (IS("-l")) /* list */
@@ -87,117 +89,103 @@ static int doargs(int argc, const char* argv[]) · 1 unmodified line
8789 else if (IS("-o")) /* output file */
8890 {
8991 output=argv[++i];
90− if (output==NULL) usage(NULL,NULL);
92+ if (output==NULL || *output==0) usage("`-o' needs argument",NULL);
9193 }
9294 else if (IS("-p")) /* parse only */
9395 dumping=0;
9496 else if (IS("-s")) /* strip debug information */
9597 stripping=1;
96− else if (IS("-t")) /* test */
97− {
98− testing=1;
99− dumping=0;
100− }
10198 else if (IS("-v")) /* show version */
10299 {
103100 printf("%s %s\n",LUA_VERSION,LUA_COPYRIGHT);
104− if (argc==2) exit(0);
101+ if (argc==2) exit(EXIT_SUCCESS);
105102 }
106103 else /* unknown option */
107104 usage("unrecognized option `%s'",argv[i]);
108105 }
109− if (i==argc && (listing || testing))
106+ if (i==argc && (listing || !dumping))
110107 {
111108 dumping=0;
112− argv[--i]=OUTPUT;
109+ argv[--i]=Output;
113110 }
114111 return i;
115112 }
116113
117−static Proto* load(const char* filename)
114+static Proto* toproto(lua_State* L, int i)
118115 {
119− Proto* tf;
120− ZIO z;
121− char source[512];
122− FILE* f;
123− int c,undump;
124− if (filename==NULL)
125− {
126− f=stdin;
127− filename="(stdin)";
128− }
129− else
130− f=efopen(filename,"r");
131− c=ungetc(fgetc(f),f);
132− if (ferror(f))
133− {
134− fprintf(stderr,"luac: cannot read from ");
135− perror(filename);
136− exit(1);
137− }
138− undump=(c==ID_CHUNK);
139− if (undump && f!=stdin)
140− {
141− fclose(f);
142− f=efopen(filename,"rb");
143− }
144− sprintf(source,"@%.*s",Sizeof(source)-2,filename);
145− luaZ_Fopen(&z,f,source);
146− tf = undump ? luaU_undump(L,&z) : luaY_parser(L,&z);
147− if (f!=stdin) fclose(f);
148− return tf;
116+ const Closure* c=(const Closure*)lua_topointer(L,i);
117+ return c->l.p;
149118 }
150119
151−static Proto* combine(Proto** P, int n)
120+static Proto* combine(lua_State* L, int n)
152121 {
153122 if (n==1)
154− return P[0];
123+ return toproto(L,-1);
155124 else
156125 {
157126 int i,pc=0;
158− Proto* tf=luaF_newproto(L);
159− tf->source=luaS_new(L,"=(luac)");
160− tf->maxstacksize=1;
161− tf->kproto=P;
162− tf->nkproto=n;
163− tf->ncode=2*n+1;
164− tf->code=luaM_newvector(L,tf->ncode,Instruction);
127+ Proto* f=luaF_newproto(L);
128+ f->source=luaS_newliteral(L,"=(" PROGNAME ")");
129+ f->maxstacksize=1;
130+ f->p=luaM_newvector(L,n,Proto*);
131+ f->sizep=n;
132+ f->sizecode=2*n+1;
133+ f->code=luaM_newvector(L,f->sizecode,Instruction);
165134 for (i=0; i<n; i++)
166135 {
167− tf->code[pc++]=CREATE_AB(OP_CLOSURE,i,0);
168− tf->code[pc++]=CREATE_AB(OP_CALL,0,0);
136+ f->p[i]=toproto(L,i-n);
137+ f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
138+ f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
169139 }
170− tf->code[pc++]=OP_END;
171− return tf;
140+ f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0);
141+ return f;
172142 }
173143 }
174144
175−static void strip(Proto* tf)
145+static void strip(lua_State* L, Proto* f)
176146 {
177− int i,n=tf->nkproto;
178− tf->lineinfo=NULL;
179− tf->nlineinfo=0;
180− tf->source=luaS_new(L,"=(none)");
181− tf->locvars=NULL;
182− tf->nlocvars=0;
183− for (i=0; i<n; i++) strip(tf->kproto[i]);
147+ int i,n=f->sizep;
148+ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
149+ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
150+ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
151+ f->lineinfo=NULL; f->sizelineinfo=0;
152+ f->locvars=NULL; f->sizelocvars=0;
153+ f->upvalues=NULL; f->sizeupvalues=0;
154+ f->source=luaS_newliteral(L,"=(none)");
155+ for (i=0; i<n; i++) strip(L,f->p[i]);
184156 }
185157
186−static FILE* efopen(const char* name, const char* mode)
158+static int writer(lua_State* L, const void* p, size_t size, void* u)
187159 {
188− FILE* f=fopen(name,mode);
189− if (f==NULL)
190− {
191− fprintf(stderr,"luac: cannot open %sput file ",*mode=='r' ? "in" : "out");
192− perror(name);
193− exit(1);
194− }
195− return f;
160+ UNUSED(L);
161+ return fwrite(p,size,1,(FILE*)u)==1;
196162 }
197163
198−void luaU_testchunk(const Proto* Main)
164+int main(int argc, char* argv[])
199165 {
200− UNUSED(Main);
201− fprintf(stderr,"luac: -t not operational in this version\n");
202− exit(1);
166+ lua_State* L;
167+ Proto* f;
168+ int i=doargs(argc,argv);
169+ argc-=i; argv+=i;
170+ if (argc<=0) usage("no input files given",NULL);
171+ L=lua_open();
172+ luaB_opentests(L);
173+ for (i=0; i<argc; i++)
174+ {
175+ const char* filename=IS("-") ? NULL : argv[i];
176+ if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
177+ }
178+ f=combine(L,argc);
179+ if (listing) luaU_print(f);
180+ if (dumping)
181+ {
182+ FILE* D=fopen(output,"wb");
183+ if (D==NULL) cannot(output,"open","out");
184+ if (stripping) strip(L,f);
185+ luaU_dump(L,f,writer,D);
186+ if (ferror(D)) cannot(output,"write","out");
187+ fclose(D);
188+ }
189+ lua_close(L);
190+ return 0;
203191 }
src/luac/luac.h+0−31
@@ -1,31 +0,0 @@
1−/*
2−** $Id: luac.h,v 1.18 2000/10/31 16:57:23 lhf Exp $
3−** definitions for luac
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include "ldebug.h"
8−#include "lfunc.h"
9−#include "lmem.h"
10−#include "lobject.h"
11−#include "lopcodes.h"
12−#include "lstring.h"
13−#include "ltable.h"
14−#include "lundump.h"
15−
16−extern lua_State *lua_state;
17−#define L lua_state /* lazy! */
18−
19−/* from dump.c */
20−void luaU_dumpchunk(const Proto* Main, FILE* D);
21−
22−/* from opt.c */
23−void luaU_optchunk(Proto* Main);
24−
25−/* from print.c */
26−void luaU_printchunk(const Proto* Main);
27−
28−/* from test.c */
29−void luaU_testchunk(const Proto* Main);
30−
31−#define Sizeof(x) ((int)sizeof(x))
src/luac/opt.c+0−127
@@ -1,127 +0,0 @@
1−/*
2−** $Id: opt.c,v 1.22 2000/10/31 16:57:23 lhf Exp $
3−** optimize bytecodes
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include <stdio.h>
8−#include <stdlib.h>
9−#include <string.h>
10−
11−#include "luac.h"
12−
13−static int MapConstant(Hash* t, int j, const TObject* key)
14−{
15− const TObject* o=luaH_get(L,t,key);
16− if (ttype(o)==LUA_TNUMBER)
17− return (int) nvalue(o);
18− else
19− {
20− TObject val;
21− ttype(&val)=LUA_TNUMBER;
22− nvalue(&val)=j;
23− *luaH_set(L,t,key)=val;
24− LUA_ASSERT(j>=0,"MapConstant returns negative!");
25− return j;
26− }
27−}
28−
29−static int MapConstants(Proto* tf, Hash* map)
30−{
31− int i,j,k,n,m=0;
32− TObject o;
33− j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
34− for (i=0; i<n; i++)
35− {
36− nvalue(&o)=tf->knum[i];
37− k=MapConstant(map,j,&o);
38− if (k==j) j++;
39− }
40− m=j;
41− j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
42− for (i=0; i<n; i++)
43− {
44− tsvalue(&o)=tf->kstr[i];
45− k=MapConstant(map,j,&o);
46− if (k==j) j++;
47− }
48− return m+j;
49−}
50−
51−static void PackConstants(Proto* tf, Hash* map)
52−{
53− int i,j,k,n;
54− TObject o;
55−#ifdef DEBUG
56− printf("%p before pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
57−#endif
58− j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
59− for (i=0; i<n; i++)
60− {
61− nvalue(&o)=tf->knum[i];
62− k=MapConstant(map,-1,&o);
63− if (k==j) tf->knum[j++]=tf->knum[i];
64− }
65− tf->nknum=j;
66− j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
67− for (i=0; i<n; i++)
68− {
69− tsvalue(&o)=tf->kstr[i];
70− k=MapConstant(map,-1,&o);
71− if (k==j) tf->kstr[j++]=tf->kstr[i];
72− }
73− tf->nkstr=j;
74−#ifdef DEBUG
75− printf("%p after pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
76−#endif
77−}
78−
79−static void OptConstants(Proto* tf)
80−{
81− Instruction* p;
82− int n=tf->nknum+tf->nkstr;
83− Hash* map=luaH_new(L,n);
84− int m=MapConstants(tf,map);
85−#ifdef DEBUG
86− printf("%p n=%d m=%d %s\n",tf,n,m,(m==n)?"nothing to optimize":"yes!");
87−#endif
88− if (m==n) return;
89− for (p=tf->code;; p++)
90− {
91− Instruction i=*p;
92− int op=GET_OPCODE(i);
93− switch (op)
94− {
95− TObject o;
96− int j,k;
97− case OP_PUSHNUM: case OP_PUSHNEGNUM:
98− j=GETARG_U(i);
99− ttype(&o)=LUA_TNUMBER; nvalue(&o)=tf->knum[j];
100− k=MapConstant(map,-1,&o);
101− if (k!=j) *p=CREATE_U(op,k);
102− break;
103− case OP_PUSHSTRING: case OP_GETGLOBAL: case OP_GETDOTTED:
104− case OP_PUSHSELF: case OP_SETGLOBAL:
105− j=GETARG_U(i);
106− ttype(&o)=LUA_TSTRING; tsvalue(&o)=tf->kstr[j];
107− k=MapConstant(map,-1,&o);
108− if (k!=j) *p=CREATE_U(op,k);
109− break;
110− case OP_END:
111− PackConstants(tf,map);
112− luaH_free(L,map);
113− return;
114− default:
115− break;
116− }
117− }
118−}
119−
120−#define OptFunction luaU_optchunk
121−
122−void OptFunction(Proto* tf)
123−{
124− int i,n=tf->nkproto;
125− OptConstants(tf);
126− for (i=0; i<n; i++) OptFunction(tf->kproto[i]);
127−}
src/luac/print.c+171−53
@@ -1,31 +1,30 @@
11 /*
2−** $Id: print.c,v 1.32 2000/11/06 20:04:36 lhf Exp $
2+** $Id: print.c,v 1.44 2003/04/07 20:34:20 lhf Exp $
33 ** print bytecodes
44 ** See Copyright Notice in lua.h
55 */
66
77 #include <stdio.h>
8−#include <stdlib.h>
9−
10−#include "luac.h"
11−
12−/* macros used in print.h, included in PrintCode */
13−#define P_OP(x) printf("%-11s\t",x)
14−#define P_NONE
15−#define P_AB printf("%d %d",GETARG_A(i),GETARG_B(i))
16−#define P_F printf("%d %d\t; %p",GETARG_A(i),GETARG_B(i),tf->kproto[GETARG_A(i)])
17−#define P_J printf("%d\t; to %d",GETARG_S(i),GETARG_S(i)+at+1)
18−#define P_Q PrintString(tf,GETARG_U(i))
19−#define P_K printf("%d\t; %s",GETARG_U(i),tf->kstr[GETARG_U(i)]->str)
20−#define P_L PrintLocal(tf,GETARG_U(i),at-1)
21−#define P_N printf("%d\t; " NUMBER_FMT,GETARG_U(i),tf->knum[GETARG_U(i)])
22−#define P_S printf("%d",GETARG_S(i))
23−#define P_U printf("%u",GETARG_U(i))
24−
25−static void PrintString(const Proto* tf, int n)
8+
9+#if 0
10+#define DEBUG_PRINT
11+#endif
12+
13+#ifndef LUA_OPNAMES
14+#define LUA_OPNAMES
15+#endif
16+
17+#include "ldebug.h"
18+#include "lobject.h"
19+#include "lopcodes.h"
20+#include "lundump.h"
21+
22+#define Sizeof(x) ((int)sizeof(x))
23+#define VOID(p) ((const void*)(p))
24+
25+static void PrintString(const Proto* f, int n)
2626 {
27− const char* s=tf->kstr[n]->str;
28− printf("%d\t; ",n);
27+ const char* s=svalue(&f->k[n]);
2928 putchar('"');
3029 for (; *s; s++)
3130 {
@@ -45,55 +44,174 @@ static void PrintString(const Proto* tf, int n) · 13 unmodified lines
4544 putchar('"');
4645 }
4746
48−static void PrintLocal(const Proto* tf, int n, int pc)
47+static void PrintConstant(const Proto* f, int i)
4948 {
50− const char* s=luaF_getlocalname(tf,n+1,pc);
51− printf("%u",n);
52− if (s!=NULL) printf("\t; %s",s);
49+ const TObject* o=&f->k[i];
50+ switch (ttype(o))
51+ {
52+ case LUA_TNUMBER:
53+ printf(LUA_NUMBER_FMT,nvalue(o));
54+ break;
55+ case LUA_TSTRING:
56+ PrintString(f,i);
57+ break;
58+ case LUA_TNIL:
59+ printf("nil");
60+ break;
61+ default: /* cannot happen */
62+ printf("? type=%d",ttype(o));
63+ break;
64+ }
5365 }
5466
55−static void PrintCode(const Proto* tf)
67+static void PrintCode(const Proto* f)
5668 {
57− const Instruction* code=tf->code;
58− const Instruction* p=code;
59− for (;;)
69+ const Instruction* code=f->code;
70+ int pc,n=f->sizecode;
71+ for (pc=0; pc<n; pc++)
6072 {
61− int at=p-code+1;
62− Instruction i=*p;
63− int line=luaG_getline(tf->lineinfo,at-1,1,NULL);
64− printf("%6d\t",at);
65− if (line>=0) printf("[%d]\t",line); else printf("[-]\t");
66− switch (GET_OPCODE(i)) {
67−#include "print.h"
73+ Instruction i=code[pc];
74+ OpCode o=GET_OPCODE(i);
75+ int a=GETARG_A(i);
76+ int b=GETARG_B(i);
77+ int c=GETARG_C(i);
78+ int bc=GETARG_Bx(i);
79+ int sbc=GETARG_sBx(i);
80+ int line=getline(f,pc);
81+#if 0
82+ printf("%0*lX",Sizeof(i)*2,i);
83+#endif
84+ printf("\t%d\t",pc+1);
85+ if (line>0) printf("[%d]\t",line); else printf("[-]\t");
86+ printf("%-9s\t",luaP_opnames[o]);
87+ switch (getOpMode(o))
88+ {
89+ case iABC: printf("%d %d %d",a,b,c); break;
90+ case iABx: printf("%d %d",a,bc); break;
91+ case iAsBx: printf("%d %d",a,sbc); break;
92+ }
93+ switch (o)
94+ {
95+ case OP_LOADK:
96+ printf("\t; "); PrintConstant(f,bc);
97+ break;
98+ case OP_GETUPVAL:
99+ case OP_SETUPVAL:
100+ printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
101+ break;
102+ case OP_GETGLOBAL:
103+ case OP_SETGLOBAL:
104+ printf("\t; %s",svalue(&f->k[bc]));
105+ break;
106+ case OP_GETTABLE:
107+ case OP_SELF:
108+ if (c>=MAXSTACK) { printf("\t; "); PrintConstant(f,c-MAXSTACK); }
109+ break;
110+ case OP_SETTABLE:
111+ case OP_ADD:
112+ case OP_SUB:
113+ case OP_MUL:
114+ case OP_DIV:
115+ case OP_POW:
116+ case OP_EQ:
117+ case OP_LT:
118+ case OP_LE:
119+ if (b>=MAXSTACK || c>=MAXSTACK)
120+ {
121+ printf("\t; ");
122+ if (b>=MAXSTACK) PrintConstant(f,b-MAXSTACK); else printf("-");
123+ printf(" ");
124+ if (c>=MAXSTACK) PrintConstant(f,c-MAXSTACK);
125+ }
126+ break;
127+ case OP_JMP:
128+ case OP_FORLOOP:
129+ case OP_TFORPREP:
130+ printf("\t; to %d",sbc+pc+2);
131+ break;
132+ case OP_CLOSURE:
133+ printf("\t; %p",VOID(f->p[bc]));
134+ break;
135+ default:
136+ break;
68137 }
69138 printf("\n");
70− if (i==OP_END) break;
71− p++;
72139 }
73140 }
74141
75−#define IsMain(tf) (tf->lineDefined==0)
142+static const char* Source(const Proto* f)
143+{
144+ const char* s=getstr(f->source);
145+ if (*s=='@' || *s=='=')
146+ return s+1;
147+ else if (*s==LUA_SIGNATURE[0])
148+ return "(bstring)";
149+ else
150+ return "(string)";
151+}
152+
153+#define IsMain(f) (f->lineDefined==0)
76154
77155 #define SS(x) (x==1)?"":"s"
78156 #define S(x) x,SS(x)
79157
80−static void PrintHeader(const Proto* tf)
158+static void PrintHeader(const Proto* f)
159+{
160+ printf("\n%s <%s:%d> (%d instruction%s, %d bytes at %p)\n",
161+ IsMain(f)?"main":"function",Source(f),f->lineDefined,
162+ S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
163+ printf("%d%s param%s, %d stack%s, %d upvalue%s, ",
164+ f->numparams,f->is_vararg?"+":"",SS(f->numparams),S(f->maxstacksize),
165+ S(f->nups));
166+ printf("%d local%s, %d constant%s, %d function%s\n",
167+ S(f->sizelocvars),S(f->sizek),S(f->sizep));
168+}
169+
170+#ifdef DEBUG_PRINT
171+static void PrintConstants(const Proto* f)
172+{
173+ int i,n=f->sizek;
174+ printf("constants (%d) for %p:\n",n,VOID(f));
175+ for (i=0; i<n; i++)
176+ {
177+ printf("\t%d\t",i);
178+ PrintConstant(f,i);
179+ printf("\n");
180+ }
181+}
182+
183+static void PrintLocals(const Proto* f)
81184 {
82− printf("\n%s " SOURCE_FMT " (%d instruction%s/%d bytes at %p)\n",
83− IsMain(tf)?"main":"function",SOURCE,
84− S(tf->ncode),tf->ncode*Sizeof(Instruction),tf);
85− printf("%d%s param%s, %d stack%s, ",
86− tf->numparams,tf->is_vararg?"+":"",SS(tf->numparams),S(tf->maxstacksize));
87− printf("%d local%s, %d string%s, %d number%s, %d function%s, %d line%s\n",
88− S(tf->nlocvars),S(tf->nkstr),S(tf->nknum),S(tf->nkproto),S(tf->nlineinfo));
185+ int i,n=f->sizelocvars;
186+ printf("locals (%d) for %p:\n",n,VOID(f));
187+ for (i=0; i<n; i++)
188+ {
189+ printf("\t%d\t%s\t%d\t%d\n",
190+ i,getstr(f->locvars[i].varname),f->locvars[i].startpc,f->locvars[i].endpc);
191+ }
89192 }
90193
91−#define PrintFunction luaU_printchunk
194+static void PrintUpvalues(const Proto* f)
195+{
196+ int i,n=f->sizeupvalues;
197+ printf("upvalues (%d) for %p:\n",n,VOID(f));
198+ if (f->upvalues==NULL) return;
199+ for (i=0; i<n; i++)
200+ {
201+ printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
202+ }
203+}
204+#endif
92205
93−void PrintFunction(const Proto* tf)
206+void luaU_print(const Proto* f)
94207 {
95− int i,n=tf->nkproto;
96− PrintHeader(tf);
97− PrintCode(tf);
98− for (i=0; i<n; i++) PrintFunction(tf->kproto[i]);
208+ int i,n=f->sizep;
209+ PrintHeader(f);
210+ PrintCode(f);
211+#ifdef DEBUG_PRINT
212+ PrintConstants(f);
213+ PrintLocals(f);
214+ PrintUpvalues(f);
215+#endif
216+ for (i=0; i<n; i++) luaU_print(f->p[i]);
99217 }
src/luac/print.h+0−55
@@ -1,55 +0,0 @@
1−/*
2−** $Id: print.h,v 1.1 2000/11/06 20:03:12 lhf Exp $
3−** extracted automatically from lopcodes.h by mkprint.lua -- DO NOT EDIT
4−** See Copyright Notice in lua.h
5−*/
6−
7− case OP_END: P_OP("END"); P_NONE; break;
8− case OP_RETURN: P_OP("RETURN"); P_U; break;
9− case OP_CALL: P_OP("CALL"); P_AB; break;
10− case OP_TAILCALL: P_OP("TAILCALL"); P_AB; break;
11− case OP_PUSHNIL: P_OP("PUSHNIL"); P_U; break;
12− case OP_POP: P_OP("POP"); P_U; break;
13− case OP_PUSHINT: P_OP("PUSHINT"); P_S; break;
14− case OP_PUSHSTRING: P_OP("PUSHSTRING"); P_Q; break;
15− case OP_PUSHNUM: P_OP("PUSHNUM"); P_N; break;
16− case OP_PUSHNEGNUM: P_OP("PUSHNEGNUM"); P_N; break;
17− case OP_PUSHUPVALUE: P_OP("PUSHUPVALUE"); P_U; break;
18− case OP_GETLOCAL: P_OP("GETLOCAL"); P_L; break;
19− case OP_GETGLOBAL: P_OP("GETGLOBAL"); P_K; break;
20− case OP_GETTABLE: P_OP("GETTABLE"); P_NONE; break;
21− case OP_GETDOTTED: P_OP("GETDOTTED"); P_K; break;
22− case OP_GETINDEXED: P_OP("GETINDEXED"); P_L; break;
23− case OP_PUSHSELF: P_OP("PUSHSELF"); P_K; break;
24− case OP_CREATETABLE: P_OP("CREATETABLE"); P_U; break;
25− case OP_SETLOCAL: P_OP("SETLOCAL"); P_L; break;
26− case OP_SETGLOBAL: P_OP("SETGLOBAL"); P_K; break;
27− case OP_SETTABLE: P_OP("SETTABLE"); P_AB; break;
28− case OP_SETLIST: P_OP("SETLIST"); P_AB; break;
29− case OP_SETMAP: P_OP("SETMAP"); P_U; break;
30− case OP_ADD: P_OP("ADD"); P_NONE; break;
31− case OP_ADDI: P_OP("ADDI"); P_S; break;
32− case OP_SUB: P_OP("SUB"); P_NONE; break;
33− case OP_MULT: P_OP("MULT"); P_NONE; break;
34− case OP_DIV: P_OP("DIV"); P_NONE; break;
35− case OP_POW: P_OP("POW"); P_NONE; break;
36− case OP_CONCAT: P_OP("CONCAT"); P_U; break;
37− case OP_MINUS: P_OP("MINUS"); P_NONE; break;
38− case OP_NOT: P_OP("NOT"); P_NONE; break;
39− case OP_JMPNE: P_OP("JMPNE"); P_J; break;
40− case OP_JMPEQ: P_OP("JMPEQ"); P_J; break;
41− case OP_JMPLT: P_OP("JMPLT"); P_J; break;
42− case OP_JMPLE: P_OP("JMPLE"); P_J; break;
43− case OP_JMPGT: P_OP("JMPGT"); P_J; break;
44− case OP_JMPGE: P_OP("JMPGE"); P_J; break;
45− case OP_JMPT: P_OP("JMPT"); P_J; break;
46− case OP_JMPF: P_OP("JMPF"); P_J; break;
47− case OP_JMPONT: P_OP("JMPONT"); P_J; break;
48− case OP_JMPONF: P_OP("JMPONF"); P_J; break;
49− case OP_JMP: P_OP("JMP"); P_J; break;
50− case OP_PUSHNILJMP: P_OP("PUSHNILJMP"); P_NONE; break;
51− case OP_FORPREP: P_OP("FORPREP"); P_J; break;
52− case OP_FORLOOP: P_OP("FORLOOP"); P_J; break;
53− case OP_LFORPREP: P_OP("LFORPREP"); P_J; break;
54− case OP_LFORLOOP: P_OP("LFORLOOP"); P_J; break;
55− case OP_CLOSURE: P_OP("CLOSURE"); P_F; break;
src/luac/stubs.c+0−127
@@ -1,127 +0,0 @@
1−/*
2−** $Id: stubs.c,v 1.20 2000/10/31 16:57:23 lhf Exp $
3−** avoid runtime modules in luac
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include <stdio.h>
8−#include <stdlib.h>
9−
10−#include "ldo.h"
11−#include "llex.h"
12−#include "luac.h"
13−#undef L
14−
15−#ifndef NOSTUBS
16−
17−const char luac_ident[] = "$luac: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
18− "$Authors: " LUA_AUTHORS " $";
19−
20−/*
21−* avoid lapi ldebug ldo lgc lstate ltm lvm
22−* use only lcode lfunc llex lmem lobject lparser lstring ltable lzio
23−*/
24−
25−/* simplified from ldo.c */
26−void lua_error (lua_State* L, const char* s) {
27− UNUSED(L);
28− if (s) fprintf(stderr,"luac: %s\n",s);
29− exit(1);
30−}
31−
32−/* simplified from ldo.c */
33−void luaD_breakrun (lua_State *L, int errcode) {
34− UNUSED(errcode);
35− lua_error(L,"memory allocation error");
36−}
37−
38−/* simplified from lstate.c */
39−lua_State *lua_open (int stacksize) {
40− lua_State *L = luaM_new(NULL, lua_State);
41− if (L == NULL) return NULL; /* memory allocation error */
42− L->stack = NULL;
43− L->strt.size = L->udt.size = 0;
44− L->strt.nuse = L->udt.nuse = 0;
45− L->strt.hash = NULL;
46− L->udt.hash = NULL;
47− L->Mbuffer = NULL;
48− L->Mbuffsize = 0;
49− L->rootproto = NULL;
50− L->rootcl = NULL;
51− L->roottable = NULL;
52− L->TMtable = NULL;
53− L->last_tag = -1;
54− L->refArray = NULL;
55− L->refSize = 0;
56− L->refFree = NONEXT;
57− L->nblocks = sizeof(lua_State);
58− L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */
59− L->callhook = NULL;
60− L->linehook = NULL;
61− L->allowhooks = 1;
62− L->errorJmp = NULL;
63− if (stacksize == 0)
64− stacksize = DEFAULT_STACK_SIZE;
65− else
66− stacksize += LUA_MINSTACK;
67− L->gt = luaH_new(L, 10); /* table of globals */
68− luaS_init(L);
69− luaX_init(L);
70− L->GCthreshold = 2*L->nblocks;
71− return L;
72−}
73−
74−/* copied from ldebug.c */
75−int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
76− int refi;
77− if (lineinfo == NULL || pc == -1)
78− return -1; /* no line info or function is not active */
79− refi = prefi ? *prefi : 0;
80− if (lineinfo[refi] < 0)
81− refline += -lineinfo[refi++];
82− LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
83− while (lineinfo[refi] > pc) {
84− refline--;
85− refi--;
86− if (lineinfo[refi] < 0)
87− refline -= -lineinfo[refi--];
88− LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
89− }
90− for (;;) {
91− int nextline = refline + 1;
92− int nextref = refi + 1;
93− if (lineinfo[nextref] < 0)
94− nextline += -lineinfo[nextref++];
95− LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
96− if (lineinfo[nextref] > pc)
97− break;
98− refline = nextline;
99− refi = nextref;
100− }
101− if (prefi) *prefi = refi;
102− return refline;
103−}
104−
105−/*
106−* the code below avoids the lexer and the parser (llex lparser lcode).
107−* it is useful if you only want to load binary files.
108−* this works for interpreters like lua.c too.
109−*/
110−
111−#ifdef NOPARSER
112−
113−#include "llex.h"
114−#include "lparser.h"
115−
116−void luaX_init(lua_State *L) {
117− UNUSED(L);
118−}
119−
120−Proto *luaY_parser(lua_State *L, ZIO *z) {
121− UNUSED(z);
122− lua_error(L,"parser not loaded");
123− return NULL;
124−}
125−
126−#endif
127−#endif
src/lundump.c+176−134
@@ -1,243 +1,285 @@
11 /*
2−** $Id: lundump.c,v 1.33 2000/10/31 16:57:23 lhf Exp $
3−** load bytecodes from files
2+** $Id: lundump.c,v 1.49 2003/04/07 20:34:20 lhf Exp $
3+** load pre-compiled Lua chunks
44 ** See Copyright Notice in lua.h
55 */
66
7−#include <stdio.h>
8−#include <string.h>
7+#define lundump_c
98
9+#include "lua.h"
10+
11+#include "ldebug.h"
1012 #include "lfunc.h"
1113 #include "lmem.h"
1214 #include "lopcodes.h"
1315 #include "lstring.h"
1416 #include "lundump.h"
17+#include "lzio.h"
1518
16−#define LoadByte ezgetc
19+#define LoadByte (lu_byte) ezgetc
1720
18−static const char* ZNAME (ZIO* Z)
19−{
20− const char* s=zname(Z);
21− return (*s=='@') ? s+1 : s;
22−}
21+typedef struct {
22+ lua_State* L;
23+ ZIO* Z;
24+ Mbuffer* b;
25+ int swap;
26+ const char* name;
27+} LoadState;
2328
24−static void unexpectedEOZ (lua_State* L, ZIO* Z)
29+static void unexpectedEOZ (LoadState* S)
2530 {
26− luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z));
31+ luaG_runerror(S->L,"unexpected end of file in %s",S->name);
2732 }
2833
29−static int ezgetc (lua_State* L, ZIO* Z)
34+static int ezgetc (LoadState* S)
3035 {
31− int c=zgetc(Z);
32− if (c==EOZ) unexpectedEOZ(L,Z);
36+ int c=zgetc(S->Z);
37+ if (c==EOZ) unexpectedEOZ(S);
3338 return c;
3439 }
3540
36−static void ezread (lua_State* L, ZIO* Z, void* b, int n)
41+static void ezread (LoadState* S, void* b, int n)
3742 {
38− int r=zread(Z,b,n);
39− if (r!=0) unexpectedEOZ(L,Z);
43+ int r=luaZ_read(S->Z,b,n);
44+ if (r!=0) unexpectedEOZ(S);
4045 }
4146
42−static void LoadBlock (lua_State* L, void* b, size_t size, ZIO* Z, int swap)
47+static void LoadBlock (LoadState* S, void* b, size_t size)
4348 {
44− if (swap)
49+ if (S->swap)
4550 {
46− char *p=(char *) b+size-1;
51+ char* p=(char*) b+size-1;
4752 int n=size;
48− while (n--) *p--=(char)ezgetc(L,Z);
53+ while (n--) *p--=(char)ezgetc(S);
4954 }
5055 else
51− ezread(L,Z,b,size);
56+ ezread(S,b,size);
5257 }
5358
54−static void LoadVector (lua_State* L, void* b, int m, size_t size, ZIO* Z, int swap)
59+static void LoadVector (LoadState* S, void* b, int m, size_t size)
5560 {
56− if (swap)
61+ if (S->swap)
5762 {
58− char *q=(char *) b;
63+ char* q=(char*) b;
5964 while (m--)
6065 {
61− char *p=q+size-1;
66+ char* p=q+size-1;
6267 int n=size;
63− while (n--) *p--=(char)ezgetc(L,Z);
68+ while (n--) *p--=(char)ezgetc(S);
6469 q+=size;
6570 }
6671 }
6772 else
68− ezread(L,Z,b,m*size);
73+ ezread(S,b,m*size);
6974 }
7075
71−static int LoadInt (lua_State* L, ZIO* Z, int swap)
76+static int LoadInt (LoadState* S)
7277 {
7378 int x;
74− LoadBlock(L,&x,sizeof(x),Z,swap);
79+ LoadBlock(S,&x,sizeof(x));
80+ if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name);
7581 return x;
7682 }
7783
78−static size_t LoadSize (lua_State* L, ZIO* Z, int swap)
84+static size_t LoadSize (LoadState* S)
7985 {
8086 size_t x;
81− LoadBlock(L,&x,sizeof(x),Z,swap);
87+ LoadBlock(S,&x,sizeof(x));
8288 return x;
8389 }
8490
85−static Number LoadNumber (lua_State* L, ZIO* Z, int swap)
91+static lua_Number LoadNumber (LoadState* S)
8692 {
87− Number x;
88− LoadBlock(L,&x,sizeof(x),Z,swap);
93+ lua_Number x;
94+ LoadBlock(S,&x,sizeof(x));
8995 return x;
9096 }
9197
92−static TString* LoadString (lua_State* L, ZIO* Z, int swap)
98+static TString* LoadString (LoadState* S)
9399 {
94− size_t size=LoadSize(L,Z,swap);
100+ size_t size=LoadSize(S);
95101 if (size==0)
96102 return NULL;
97103 else
98104 {
99− char* s=luaO_openspace(L,size);
100− LoadBlock(L,s,size,Z,0);
101− return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */
105+ char* s=luaZ_openspace(S->L,S->b,size);
106+ ezread(S,s,size);
107+ return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
102108 }
103109 }
104110
105−static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
111+static void LoadCode (LoadState* S, Proto* f)
106112 {
107− int size=LoadInt(L,Z,swap);
108− tf->code=luaM_newvector(L,size,Instruction);
109− LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap);
110− if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
111− luaF_protook(L,tf,size);
113+ int size=LoadInt(S);
114+ f->code=luaM_newvector(S->L,size,Instruction);
115+ f->sizecode=size;
116+ LoadVector(S,f->code,size,sizeof(*f->code));
112117 }
113118
114−static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
119+static void LoadLocals (LoadState* S, Proto* f)
115120 {
116121 int i,n;
117− tf->nlocvars=n=LoadInt(L,Z,swap);
118− tf->locvars=luaM_newvector(L,n,LocVar);
122+ n=LoadInt(S);
123+ f->locvars=luaM_newvector(S->L,n,LocVar);
124+ f->sizelocvars=n;
119125 for (i=0; i<n; i++)
120126 {
121− tf->locvars[i].varname=LoadString(L,Z,swap);
122− tf->locvars[i].startpc=LoadInt(L,Z,swap);
123− tf->locvars[i].endpc=LoadInt(L,Z,swap);
127+ f->locvars[i].varname=LoadString(S);
128+ f->locvars[i].startpc=LoadInt(S);
129+ f->locvars[i].endpc=LoadInt(S);
124130 }
125131 }
126132
127−static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
133+static void LoadLines (LoadState* S, Proto* f)
128134 {
129− int n;
130− tf->nlineinfo=n=LoadInt(L,Z,swap);
131− tf->lineinfo=luaM_newvector(L,n,int);
132− LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap);
135+ int size=LoadInt(S);
136+ f->lineinfo=luaM_newvector(S->L,size,int);
137+ f->sizelineinfo=size;
138+ LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
133139 }
134140
135−static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);
141+static void LoadUpvalues (LoadState* S, Proto* f)
142+{
143+ int i,n;
144+ n=LoadInt(S);
145+ if (n!=0 && n!=f->nups)
146+ luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
147+ S->name,n,f->nups);
148+ f->upvalues=luaM_newvector(S->L,n,TString*);
149+ f->sizeupvalues=n;
150+ for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
151+}
136152
137−static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
153+static Proto* LoadFunction (LoadState* S, TString* p);
154+
155+static void LoadConstants (LoadState* S, Proto* f)
138156 {
139157 int i,n;
140− tf->nkstr=n=LoadInt(L,Z,swap);
141− tf->kstr=luaM_newvector(L,n,TString*);
142− for (i=0; i<n; i++)
143− tf->kstr[i]=LoadString(L,Z,swap);
144− tf->nknum=n=LoadInt(L,Z,swap);
145− tf->knum=luaM_newvector(L,n,Number);
146− LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap);
147− tf->nkproto=n=LoadInt(L,Z,swap);
148− tf->kproto=luaM_newvector(L,n,Proto*);
158+ n=LoadInt(S);
159+ f->k=luaM_newvector(S->L,n,TObject);
160+ f->sizek=n;
149161 for (i=0; i<n; i++)
150− tf->kproto[i]=LoadFunction(L,Z,swap);
162+ {
163+ TObject* o=&f->k[i];
164+ int t=LoadByte(S);
165+ switch (t)
166+ {
167+ case LUA_TNUMBER:
168+ setnvalue(o,LoadNumber(S));
169+ break;
170+ case LUA_TSTRING:
171+ setsvalue2n(o,LoadString(S));
172+ break;
173+ case LUA_TNIL:
174+ setnilvalue(o);
175+ break;
176+ default:
177+ luaG_runerror(S->L,"bad constant type (%d) in %s",t,S->name);
178+ break;
179+ }
180+ }
181+ n=LoadInt(S);
182+ f->p=luaM_newvector(S->L,n,Proto*);
183+ f->sizep=n;
184+ for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
151185 }
152186
153−static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap)
187+static Proto* LoadFunction (LoadState* S, TString* p)
154188 {
155− Proto* tf=luaF_newproto(L);
156− tf->source=LoadString(L,Z,swap);
157− tf->lineDefined=LoadInt(L,Z,swap);
158− tf->numparams=LoadInt(L,Z,swap);
159− tf->is_vararg=LoadByte(L,Z);
160− tf->maxstacksize=LoadInt(L,Z,swap);
161− LoadLocals(L,tf,Z,swap);
162− LoadLines(L,tf,Z,swap);
163− LoadConstants(L,tf,Z,swap);
164− LoadCode(L,tf,Z,swap);
165− return tf;
189+ Proto* f=luaF_newproto(S->L);
190+ f->source=LoadString(S); if (f->source==NULL) f->source=p;
191+ f->lineDefined=LoadInt(S);
192+ f->nups=LoadByte(S);
193+ f->numparams=LoadByte(S);
194+ f->is_vararg=LoadByte(S);
195+ f->maxstacksize=LoadByte(S);
196+ LoadLines(S,f);
197+ LoadLocals(S,f);
198+ LoadUpvalues(S,f);
199+ LoadConstants(S,f);
200+ LoadCode(S,f);
201+#ifndef TRUST_BINARIES
202+ if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name);
203+#endif
204+ return f;
166205 }
167206
168−static void LoadSignature (lua_State* L, ZIO* Z)
207+static void LoadSignature (LoadState* S)
169208 {
170− const char* s=SIGNATURE;
171− while (*s!=0 && ezgetc(L,Z)==*s)
209+ const char* s=LUA_SIGNATURE;
210+ while (*s!=0 && ezgetc(S)==*s)
172211 ++s;
173− if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z));
212+ if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name);
174213 }
175214
176−static void TestSize (lua_State* L, int s, const char* what, ZIO* Z)
215+static void TestSize (LoadState* S, int s, const char* what)
177216 {
178− int r=ezgetc(L,Z);
217+ int r=LoadByte(S);
179218 if (r!=s)
180− luaO_verror(L,"virtual machine mismatch in `%.99s':\n"
181− " %.20s is %d but read %d",ZNAME(Z),what,s,r);
219+ luaG_runerror(S->L,"virtual machine mismatch in %s: "
220+ "size of %s is %d but read %d",S->name,what,s,r);
182221 }
183222
184−#define TESTSIZE(s) TestSize(L,s,#s,Z)
185−#define V(v) v/16,v%16
223+#define TESTSIZE(s,w) TestSize(S,s,w)
224+#define V(v) v/16,v%16
186225
187−static int LoadHeader (lua_State* L, ZIO* Z)
226+static void LoadHeader (LoadState* S)
188227 {
189− int version,swap;
190− Number f=0,tf=TEST_NUMBER;
191− LoadSignature(L,Z);
192− version=ezgetc(L,Z);
228+ int version;
229+ lua_Number x,tx=TEST_NUMBER;
230+ LoadSignature(S);
231+ version=LoadByte(S);
193232 if (version>VERSION)
194− luaO_verror(L,"`%.99s' too new:\n"
195− " read version %d.%d; expected at most %d.%d",
196− ZNAME(Z),V(version),V(VERSION));
197− if (version<VERSION0) /* check last major change */
198− luaO_verror(L,"`%.99s' too old:\n"
199− " read version %d.%d; expected at least %d.%d",
200− ZNAME(Z),V(version),V(VERSION));
201− swap=(luaU_endianess()!=ezgetc(L,Z)); /* need to swap bytes? */
202− TESTSIZE(sizeof(int));
203− TESTSIZE(sizeof(size_t));
204− TESTSIZE(sizeof(Instruction));
205− TESTSIZE(SIZE_INSTRUCTION);
206− TESTSIZE(SIZE_OP);
207− TESTSIZE(SIZE_B);
208− TESTSIZE(sizeof(Number));
209− f=LoadNumber(L,Z,swap);
210− if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */
211− luaO_verror(L,"unknown number format in `%.99s':\n"
212− " read " NUMBER_FMT "; expected " NUMBER_FMT, ZNAME(Z),f,tf);
213− return swap;
214−}
215−
216−static Proto* LoadChunk (lua_State* L, ZIO* Z)
217−{
218− return LoadFunction(L,Z,LoadHeader(L,Z));
233+ luaG_runerror(S->L,"%s too new: "
234+ "read version %d.%d; expected at most %d.%d",
235+ S->name,V(version),V(VERSION));
236+ if (version<VERSION0) /* check last major change */
237+ luaG_runerror(S->L,"%s too old: "
238+ "read version %d.%d; expected at least %d.%d",
239+ S->name,V(version),V(VERSION0));
240+ S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */
241+ TESTSIZE(sizeof(int),"int");
242+ TESTSIZE(sizeof(size_t), "size_t");
243+ TESTSIZE(sizeof(Instruction), "Instruction");
244+ TESTSIZE(SIZE_OP, "OP");
245+ TESTSIZE(SIZE_A, "A");
246+ TESTSIZE(SIZE_B, "B");
247+ TESTSIZE(SIZE_C, "C");
248+ TESTSIZE(sizeof(lua_Number), "number");
249+ x=LoadNumber(S);
250+ if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */
251+ luaG_runerror(S->L,"unknown number format in %s",S->name);
252+}
253+
254+static Proto* LoadChunk (LoadState* S)
255+{
256+ LoadHeader(S);
257+ return LoadFunction(S,NULL);
219258 }
220259
221260 /*
222−** load one chunk from a file or buffer
223−** return main if ok and NULL at EOF
261+** load precompiled chunk
224262 */
225−Proto* luaU_undump (lua_State* L, ZIO* Z)
263+Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff)
226264 {
227− Proto* tf=NULL;
228− int c=zgetc(Z);
229− if (c==ID_CHUNK)
230− tf=LoadChunk(L,Z);
231− c=zgetc(Z);
232− if (c!=EOZ)
233− luaO_verror(L,"`%.99s' apparently contains more than one chunk",ZNAME(Z));
234− return tf;
265+ LoadState S;
266+ const char* s=zname(Z);
267+ if (*s=='@' || *s=='=')
268+ S.name=s+1;
269+ else if (*s==LUA_SIGNATURE[0])
270+ S.name="binary string";
271+ else
272+ S.name=s;
273+ S.L=L;
274+ S.Z=Z;
275+ S.b=buff;
276+ return LoadChunk(&S);
235277 }
236278
237279 /*
238280 ** find byte order
239281 */
240−int luaU_endianess (void)
282+int luaU_endianness (void)
241283 {
242284 int x=1;
243285 return *(char*)&x;
src/lundump.h+16−17
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lundump.h,v 1.21 2000/10/31 16:57:23 lhf Exp $
2+** $Id: lundump.h,v 1.30 2003/04/07 20:34:20 lhf Exp $
33 ** load pre-compiled Lua chunks
44 ** See Copyright Notice in lua.h
55 */
@@ -10,26 +10,25 @@ · 4 unmodified lines
1010 #include "lobject.h"
1111 #include "lzio.h"
1212
13−/* load one chunk */
14−Proto* luaU_undump (lua_State* L, ZIO* Z);
13+/* load one chunk; from lundump.c */
14+Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff);
1515
16−/* find byte order */
17−int luaU_endianess (void);
16+/* find byte order; from lundump.c */
17+int luaU_endianness (void);
1818
19−/* definitions for headers of binary files */
20−#define VERSION 0x40 /* last format change was in 4.0 */
21−#define VERSION0 0x40 /* last major change was in 4.0 */
22−#define ID_CHUNK 27 /* binary files start with ESC... */
23−#define SIGNATURE "Lua" /* ...followed by this signature */
19+/* dump one chunk; from ldump.c */
20+void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data);
21+
22+/* print one chunk; from print.c */
23+void luaU_print (const Proto* Main);
2424
25−/* formats for error messages */
26−#define SOURCE_FMT "<%d:%.99s>"
27−#define SOURCE tf->lineDefined,tf->source->str
28−#define IN_FMT " in %p " SOURCE_FMT
29−#define IN tf,SOURCE
25+/* definitions for headers of binary files */
26+#define LUA_SIGNATURE "\033Lua" /* binary files start with "<esc>Lua" */
27+#define VERSION 0x50 /* last format change was in 5.0 */
28+#define VERSION0 0x50 /* last major change was in 5.0 */
3029
3130 /* a multiple of PI for testing native format */
32−/* multiplying by 1E8 gives non-trivial integer values */
33−#define TEST_NUMBER 3.14159265358979323846E8
31+/* multiplying by 1E7 gives non-trivial integer values */
32+#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7)
3433
3534 #endif
src/lvm.c+575−505
@@ -1,17 +1,21 @@
11 /*
2−** $Id: lvm.c,v 1.146a 2000/10/26 12:47:05 roberto Exp $
2+** $Id: lvm.c,v 1.284 2003/04/03 13:35:34 roberto Exp $
33 ** Lua virtual machine
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <stdio.h>
8+#include <stdarg.h>
99 #include <stdlib.h>
1010 #include <string.h>
1111
12+/* needed only when `lua_number2str' uses `sprintf' */
13+#include <stdio.h>
14+
15+#define lvm_c
16+
1217 #include "lua.h"
1318
14−#include "lapi.h"
1519 #include "ldebug.h"
1620 #include "ldo.h"
1721 #include "lfunc.h"
@@ -25,243 +29,225 @@ · 7 unmodified lines
2529 #include "lvm.h"
2630
2731
28−#ifdef OLD_ANSI
29−#define strcoll(a,b) strcmp(a,b)
30−#endif
31−
3232
33+/* function to convert a lua_Number to a string */
34+#ifndef lua_number2str
35+#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
36+#endif
3337
34−/*
35−** Extra stack size to run a function:
36−** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
37−*/
38−#define EXTRA_STACK 8
3938
39+/* limit for table tag-method chains (to avoid loops) */
40+#define MAXTAGLOOP 100
4041
4142
42−int luaV_tonumber (TObject *obj) {
43− if (ttype(obj) != LUA_TSTRING)
44− return 1;
45− else {
46− if (!luaO_str2d(svalue(obj), &nvalue(obj)))
47− return 2;
48− ttype(obj) = LUA_TNUMBER;
49− return 0;
43+const TObject *luaV_tonumber (const TObject *obj, TObject *n) {
44+ lua_Number num;
45+ if (ttisnumber(obj)) return obj;
46+ if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
47+ setnvalue(n, num);
48+ return n;
5049 }
50+ else
51+ return NULL;
5152 }
5253
5354
54−int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
55− if (ttype(obj) != LUA_TNUMBER)
56− return 1;
55+int luaV_tostring (lua_State *L, StkId obj) {
56+ if (!ttisnumber(obj))
57+ return 0;
5758 else {
5859 char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */
59− lua_number2str(s, nvalue(obj)); /* convert `s' to number */
60− tsvalue(obj) = luaS_new(L, s);
61− ttype(obj) = LUA_TSTRING;
62− return 0;
60+ lua_number2str(s, nvalue(obj));
61+ setsvalue2s(obj, luaS_new(L, s));
62+ return 1;
6363 }
6464 }
6565
6666
67−static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
68− CallInfo *ci = infovalue(base-1);
69− int *lineinfo = ci->func->f.l->lineinfo;
70− int pc = (*ci->pc - ci->func->f.l->code) - 1;
71− int newline;
72− if (pc == 0) { /* may be first time? */
73− ci->line = 1;
74− ci->refi = 0;
75− ci->lastpc = pc+1; /* make sure it will call linehook */
67+static void traceexec (lua_State *L) {
68+ lu_byte mask = L->hookmask;
69+ if (mask > LUA_MASKLINE) { /* instruction-hook set? */
70+ if (L->hookcount == 0) {
71+ resethookcount(L);
72+ luaD_callhook(L, LUA_HOOKCOUNT, -1);
73+ return;
74+ }
7675 }
77− newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
78− /* calls linehook when enters a new line or jumps back (loop) */
79− if (newline != ci->line || pc <= ci->lastpc) {
80− ci->line = newline;
81− L->top = top;
82− luaD_lineHook(L, base-1, newline, linehook);
76+ if (mask & LUA_MASKLINE) {
77+ CallInfo *ci = L->ci;
78+ Proto *p = ci_func(ci)->l.p;
79+ int newline = getline(p, pcRel(*ci->u.l.pc, p));
80+ if (!L->hookinit) {
81+ luaG_inithooks(L);
82+ return;
83+ }
84+ lua_assert(ci->state & CI_HASFRAME);
85+ if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
86+ ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */
87+ /* calls linehook when enters a new line or jumps back (loop) */
88+ if (*ci->u.l.pc <= ci->u.l.savedpc ||
89+ newline != getline(p, pcRel(ci->u.l.savedpc, p))) {
90+ luaD_callhook(L, LUA_HOOKLINE, newline);
91+ ci = L->ci; /* previous call may reallocate `ci' */
92+ }
93+ ci->u.l.savedpc = *ci->u.l.pc;
8394 }
84− ci->lastpc = pc;
8595 }
8696
8797
88−static Closure *luaV_closure (lua_State *L, int nelems) {
89− Closure *c = luaF_newclosure(L, nelems);
90− L->top -= nelems;
91− while (nelems--)
92− c->upvalue[nelems] = *(L->top+nelems);
93− clvalue(L->top) = c;
94− ttype(L->top) = LUA_TFUNCTION;
95− incr_top;
96− return c;
98+static void callTMres (lua_State *L, const TObject *f,
99+ const TObject *p1, const TObject *p2) {
100+ setobj2s(L->top, f); /* push function */
101+ setobj2s(L->top+1, p1); /* 1st argument */
102+ setobj2s(L->top+2, p2); /* 2nd argument */
103+ luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */
104+ L->top += 3;
105+ luaD_call(L, L->top - 3, 1);
106+ L->top--; /* result will be in L->top */
97107 }
98108
99109
100−void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
101− Closure *cl = luaV_closure(L, nelems);
102− cl->f.c = c;
103− cl->isC = 1;
110+
111+static void callTM (lua_State *L, const TObject *f,
112+ const TObject *p1, const TObject *p2, const TObject *p3) {
113+ setobj2s(L->top, f); /* push function */
114+ setobj2s(L->top+1, p1); /* 1st argument */
115+ setobj2s(L->top+2, p2); /* 2nd argument */
116+ setobj2s(L->top+3, p3); /* 3th argument */
117+ luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */
118+ L->top += 4;
119+ luaD_call(L, L->top - 4, 0);
104120 }
105121
106122
107−void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
108− Closure *cl = luaV_closure(L, nelems);
109− cl->f.l = l;
110− cl->isC = 0;
123+static const TObject *luaV_index (lua_State *L, const TObject *t,
124+ TObject *key, int loop) {
125+ const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
126+ if (tm == NULL) return &luaO_nilobject; /* no TM */
127+ if (ttisfunction(tm)) {
128+ callTMres(L, tm, t, key);
129+ return L->top;
130+ }
131+ else return luaV_gettable(L, tm, key, loop);
132+}
133+
134+static const TObject *luaV_getnotable (lua_State *L, const TObject *t,
135+ TObject *key, int loop) {
136+ const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX);
137+ if (ttisnil(tm))
138+ luaG_typeerror(L, t, "index");
139+ if (ttisfunction(tm)) {
140+ callTMres(L, tm, t, key);
141+ return L->top;
142+ }
143+ else return luaV_gettable(L, tm, key, loop);
111144 }
112145
113146
114147 /*
115148 ** Function to index a table.
116−** Receives the table at `t' and the key at top.
149+** Receives the table at `t' and the key at `key'.
150+** leaves the result at `res'.
117151 */
118−const TObject *luaV_gettable (lua_State *L, StkId t) {
119− Closure *tm;
120− int tg;
121− if (ttype(t) == LUA_TTABLE && /* `t' is a table? */
122− ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
123− luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
124− /* do a primitive get */
125− const TObject *h = luaH_get(L, hvalue(t), L->top-1);
126− /* result is no nil or there is no `index' tag method? */
127− if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
128− return h; /* return result */
129− /* else call `index' tag method */
130− }
131− else { /* try a `gettable' tag method */
132− tm = luaT_gettmbyObj(L, t, TM_GETTABLE);
133− }
134− if (tm != NULL) { /* is there a tag method? */
135− luaD_checkstack(L, 2);
136− *(L->top+1) = *(L->top-1); /* key */
137− *L->top = *t; /* table */
138− clvalue(L->top-1) = tm; /* tag method */
139− ttype(L->top-1) = LUA_TFUNCTION;
140− L->top += 2;
141− luaD_call(L, L->top - 3, 1);
142− return L->top - 1; /* call result */
143− }
144− else { /* no tag method */
145− luaG_typeerror(L, t, "index");
146− return NULL; /* to avoid warnings */
152+const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
153+ int loop) {
154+ if (loop > MAXTAGLOOP)
155+ luaG_runerror(L, "loop in gettable");
156+ if (ttistable(t)) { /* `t' is a table? */
157+ Table *h = hvalue(t);
158+ const TObject *v = luaH_get(h, key); /* do a primitive get */
159+ if (!ttisnil(v)) return v;
160+ else return luaV_index(L, t, key, loop+1);
147161 }
162+ else return luaV_getnotable(L, t, key, loop+1);
148163 }
149164
150165
151166 /*
152−** Receives table at `t', key at `key' and value at top.
167+** Receives table at `t', key at `key' and value at `val'.
153168 */
154−void luaV_settable (lua_State *L, StkId t, StkId key) {
155− int tg;
156− if (ttype(t) == LUA_TTABLE && /* `t' is a table? */
157− ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
158− luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */
159− *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */
160− else { /* try a `settable' tag method */
161− Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE);
162− if (tm != NULL) {
163− luaD_checkstack(L, 3);
164− *(L->top+2) = *(L->top-1);
165− *(L->top+1) = *key;
166− *(L->top) = *t;
167− clvalue(L->top-1) = tm;
168− ttype(L->top-1) = LUA_TFUNCTION;
169− L->top += 3;
170− luaD_call(L, L->top - 4, 0); /* call `settable' tag method */
169+void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) {
170+ const TObject *tm;
171+ int loop = 0;
172+ do {
173+ if (ttistable(t)) { /* `t' is a table? */
174+ Table *h = hvalue(t);
175+ TObject *oldval = luaH_set(L, h, key); /* do a primitive set */
176+ if (!ttisnil(oldval) || /* result is no nil? */
177+ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
178+ setobj2t(oldval, val); /* write barrier */
179+ return;
180+ }
181+ /* else will try the tag method */
171182 }
172− else /* no tag method... */
183+ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
173184 luaG_typeerror(L, t, "index");
174− }
175−}
176−
177−
178−const TObject *luaV_getglobal (lua_State *L, TString *s) {
179− const TObject *value = luaH_getstr(L->gt, s);
180− Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL);
181− if (tm == NULL) /* is there a tag method? */
182− return value; /* default behavior */
183− else { /* tag method */
184− luaD_checkstack(L, 3);
185− clvalue(L->top) = tm;
186− ttype(L->top) = LUA_TFUNCTION;
187− tsvalue(L->top+1) = s; /* global name */
188− ttype(L->top+1) = LUA_TSTRING;
189− *(L->top+2) = *value;
190− L->top += 3;
191− luaD_call(L, L->top - 3, 1);
192− return L->top - 1;
193− }
185+ if (ttisfunction(tm)) {
186+ callTM(L, tm, t, key, val);
187+ return;
188+ }
189+ t = tm; /* else repeat with `tm' */
190+ } while (++loop <= MAXTAGLOOP);
191+ luaG_runerror(L, "loop in settable");
194192 }
195193
196194
197−void luaV_setglobal (lua_State *L, TString *s) {
198− const TObject *oldvalue = luaH_getstr(L->gt, s);
199− Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
200− if (tm == NULL) { /* is there a tag method? */
201− if (oldvalue != &luaO_nilobject) {
202− /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */
203− *(TObject *)oldvalue = *(L->top - 1);
204− }
205− else {
206− TObject key;
207− ttype(&key) = LUA_TSTRING;
208− tsvalue(&key) = s;
209− *luaH_set(L, L->gt, &key) = *(L->top - 1);
210− }
211− }
212− else {
213− luaD_checkstack(L, 3);
214− *(L->top+2) = *(L->top-1); /* new value */
215− *(L->top+1) = *oldvalue;
216− ttype(L->top) = LUA_TSTRING;
217− tsvalue(L->top) = s;
218− clvalue(L->top-1) = tm;
219− ttype(L->top-1) = LUA_TFUNCTION;
220− L->top += 3;
221− luaD_call(L, L->top - 4, 0);
222− }
195+static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
196+ StkId res, TMS event) {
197+ ptrdiff_t result = savestack(L, res);
198+ const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
199+ if (ttisnil(tm))
200+ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
201+ if (!ttisfunction(tm)) return 0;
202+ callTMres(L, tm, p1, p2);
203+ res = restorestack(L, result); /* previous call may change stack */
204+ setobjs2s(res, L->top);
205+ return 1;
223206 }
224207
225208
226−static int call_binTM (lua_State *L, StkId top, TMS event) {
227− /* try first operand */
228− Closure *tm = luaT_gettmbyObj(L, top-2, event);
229− L->top = top;
230− if (tm == NULL) {
231− tm = luaT_gettmbyObj(L, top-1, event); /* try second operand */
232− if (tm == NULL) {

915 more lines aren’t shown here.

src/lvm.h+17−14

This diff is large: its 44 lines aren’t shown here.

src/lzio.c+43−46

This diff is large: its 125 lines aren’t shown here.

src/lzio.h+37−26

This diff is large: its 90 lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t