History

Lua 4.0

Lua Team committed 26 years ago

Commit e22497f1 parent 0125a77117 files · +12837 −10103Browse files

Showing the changes to src (66 of 117 files). Show all

Unified · Split

66 files
  1. src/Makefile +10 −8
  2. src/lapi.c +298 −498
  3. src/lapi.h +3 −8
  4. src/lauxlib.c +0 −133
  5. src/lbuffer.c +0 −75
  6. src/lbuiltin.c +0 −736
  7. src/lbuiltin.h +0 −14
  8. src/lcode.c +701 −0
  9. src/lcode.h +70 −0
  10. src/ldebug.c +466 −0
  11. src/ldebug.h +21 −0
  12. src/ldo.c +271 −273
  13. src/ldo.h +10 −23
  14. src/lfunc.c +66 −55
  15. src/lfunc.h +8 −7
  16. src/lgc.c +260 −182
  17. src/lgc.h +3 −6
  18. src/lib/Makefile +3 −3
  19. src/lib/README +4 −2
  20. src/lib/lauxlib.c +216 −0
  21. src/lib/lbaselib.c +651 −0
  22. src/lib/ldblib.c +124 −153
  23. src/lib/linit.c +0 −17
  24. src/lib/liolib.c +432 −297
  25. src/lib/lmathlib.c +114 −79
  26. src/lib/lstrlib.c +265 −238
  27. src/llex.c +219 −276
  28. src/llex.h +39 −31
  29. src/llimits.h +204 −0
  30. src/lmem.c +94 −84
  31. src/lmem.h +23 −22
  32. src/lobject.c +83 −87
  33. src/lobject.h +125 −125
  34. src/lopcodes.h +120 −90
  35. src/lparser.c +822 −1090
  36. src/lparser.h +45 −5
  37. src/lstate.c +94 −59
  38. src/lstate.h +35 −52
  39. src/lstring.c +96 −239
  40. src/lstring.h +22 −13
  41. src/ltable.c +231 −105
  42. src/ltable.h +19 −15
  43. src/ltests.c +543 −0
  44. src/ltm.c +93 −178
  45. src/ltm.h +34 −37
  46. src/lua/Makefile +2 −2
  47. src/lua/README +26 −24
  48. src/lua/lua.c +224 −90
  49. src/luac/Makefile +3 −3
  50. src/luac/README +14 −20
  51. src/luac/dump.c +70 −103
  52. src/luac/luac.c +134 −118
  53. src/luac/luac.h +10 −27
  54. src/luac/opcode.c +0 −102
  55. src/luac/opcode.h +0 −70
  56. src/luac/opt.c +86 −240
  57. src/luac/print.c +64 −188
  58. src/luac/print.h +55 −0
  59. src/luac/stubs.c +91 −85
  60. src/luac/test.c +0 −253
  61. src/lundump.c +154 −149
  62. src/lundump.h +12 −16
  63. src/lvm.c +549 −474
  64. src/lvm.h +13 −15
  65. src/lzio.c +34 −34
  66. src/lzio.h +15 −12
src/Makefile+10−8
@@ -1,4 +1,4 @@
1−# makefile for lua basic library
1+# makefile for Lua core library
22
33 LUA= ..
44
@@ -6,9 +6,8 @@ include $(LUA)/config · 1 unmodified line
66
77 OBJS= \
88 lapi.o \
9− lauxlib.o \
10− lbuffer.o \
11− lbuiltin.o \
9+ lcode.o \
10+ ldebug.o \
1211 ldo.o \
1312 lfunc.o \
1413 lgc.o \
@@ -19,6 +18,7 @@ OBJS= \ · 4 unmodified lines
1918 lstate.o \
2019 lstring.o \
2120 ltable.o \
21+ ltests.o \
2222 ltm.o \
2323 lundump.o \
2424 lvm.o \
@@ -26,9 +26,8 @@ OBJS= \ · 1 unmodified line
2626
2727 SRCS= \
2828 lapi.c \
29− lauxlib.c \
30− lbuffer.c \
31− lbuiltin.c \
29+ lcode.c \
30+ ldebug.c \
3231 ldo.c \
3332 lfunc.c \
3433 lgc.c \
@@ -39,16 +38,19 @@ SRCS= \ · 4 unmodified lines
3938 lstate.c \
4039 lstring.c \
4140 ltable.c \
41+ ltests.c \
4242 ltm.c \
4343 lundump.c \
4444 lvm.c \
4545 lzio.c \
4646 lapi.h \
47− lbuiltin.h \
47+ lcode.h \
48+ ldebug.h \
4849 ldo.h \
4950 lfunc.h \
5051 lgc.h \
5152 llex.h \
53+ llimits.h \
5254 lmem.h \
5355 lobject.h \
5456 lopcodes.h \
src/lapi.c+298−498
@@ -1,15 +1,15 @@
11 /*
2−** $Id: lapi.c,v 1.47b 1999/06/22 20:37:23 roberto Exp $
2+** $Id: lapi.c,v 1.110 2000/10/30 12:50:09 roberto Exp $
33 ** Lua API
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <stdlib.h>
98 #include <string.h>
109
10+#include "lua.h"
11+
1112 #include "lapi.h"
12−#include "lauxlib.h"
1313 #include "ldo.h"
1414 #include "lfunc.h"
1515 #include "lgc.h"
@@ -19,676 +19,476 @@ · 3 unmodified lines
1919 #include "lstring.h"
2020 #include "ltable.h"
2121 #include "ltm.h"
22−#include "lua.h"
23−#include "luadebug.h"
2422 #include "lvm.h"
2523
2624
27−char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
28− "$Authors: " LUA_AUTHORS " $";
29−
30−
31−
32−TObject *luaA_Address (lua_Object o) {
33− return (o != LUA_NOOBJECT) ? Address(o) : NULL;
34−}
35−
36−
37−static lua_Type normalized_type (TObject *o)
38−{
39− int t = ttype(o);
40− switch (t) {
41− case LUA_T_PMARK:
42− return LUA_T_PROTO;
43− case LUA_T_CMARK:
44− return LUA_T_CPROTO;
45− case LUA_T_CLMARK:
46− return LUA_T_CLOSURE;
47− default:
48− return t;
49− }
50−}
25+const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
26+ "$Authors: " LUA_AUTHORS " $";
5127
5228
53−static void set_normalized (TObject *d, TObject *s)
54−{
55− d->value = s->value;
56− d->ttype = normalized_type(s);
57−}
5829
30+#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
5931
60−static TObject *luaA_protovalue (TObject *o)
61−{
62− return (normalized_type(o) == LUA_T_CLOSURE) ? protovalue(o) : o;
63−}
32+#define api_incr_top(L) incr_top
6433
6534
66−void luaA_packresults (void)
67−{
68− luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
69− incr_top;
70−}
7135
7236
73−int luaA_passresults (void) {
74− L->Cstack.base = L->Cstack.lua2C; /* position of first result */
75− return L->Cstack.num;
37+TObject *luaA_index (lua_State *L, int index) {
38+ return Index(L, index);
7639 }
7740
7841
79−static void checkCparams (int nParams)
80−{
81− if (L->stack.top-L->stack.stack < L->Cstack.base+nParams)
82− lua_error("API error - wrong number of arguments in C2lua stack");
83−}
84−
85−
86−static lua_Object put_luaObject (TObject *o) {
87− luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
88− L->stack.stack[L->Cstack.base++] = *o;
89− return L->Cstack.base; /* this is +1 real position (see Ref) */
42+static TObject *luaA_indexAcceptable (lua_State *L, int index) {
43+ if (index >= 0) {
44+ TObject *o = L->Cbase+(index-1);
45+ if (o >= L->top) return NULL;
46+ else return o;
47+ }
48+ else return L->top+index;
9049 }
9150
9251
93−static lua_Object put_luaObjectonTop (void) {
94− luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
95− L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
96− return L->Cstack.base; /* this is +1 real position (see Ref) */
52+void luaA_pushobject (lua_State *L, const TObject *o) {
53+ *L->top = *o;
54+ incr_top;
9755 }
9856
99−
100−static void top2LC (int n) {
101− /* Put the 'n' elements on the top as the Lua2C contents */
102− L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */
103− L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
104− L->Cstack.num = n; /* number of results */
57+LUA_API int lua_stackspace (lua_State *L) {
58+ return (L->stack_last - L->top);
10559 }
10660
10761
108−lua_Object lua_pop (void) {
109− checkCparams(1);
110− return put_luaObjectonTop();
111−}
112−
11362
11463 /*
115−** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
116−** 'number' must be 1 to get the first parameter.
64+** basic stack manipulation
11765 */
118−lua_Object lua_lua2C (int number)
119−{
120− if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
121− /* Ref(L->stack.stack+(L->Cstack.lua2C+number-1)) ==
122− L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */
123− return L->Cstack.lua2C+number;
124−}
12566
12667
127−int lua_callfunction (lua_Object function)
128−{
129− if (function == LUA_NOOBJECT)
130− return 1;
131− else {
132− luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
133− set_normalized(L->stack.stack+L->Cstack.base, Address(function));
134− return luaD_protectedrun();
135− }
68+LUA_API int lua_gettop (lua_State *L) {
69+ return (L->top - L->Cbase);
13670 }
13771
13872
139−lua_Object lua_gettagmethod (int tag, char *event)
140−{
141− return put_luaObject(luaT_gettagmethod(tag, event));
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 */
14278 }
14379
14480
145−lua_Object lua_settagmethod (int tag, char *event)
146−{
147− checkCparams(1);
148− luaT_settagmethod(tag, event, L->stack.top-1);
149− return put_luaObjectonTop();
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;
84+ L->top--;
15085 }
15186
15287
153−lua_Object lua_seterrormethod (void) {
154− lua_Object temp;
155− checkCparams(1);
156− temp = lua_getglobal("_ERRORMESSAGE");
157− lua_setglobal("_ERRORMESSAGE");
158− return temp;
88+LUA_API void lua_insert (lua_State *L, int index) {
89+ StkId p = luaA_index(L, index);
90+ StkId q;
91+ for (q = L->top; q>p; q--)
92+ *q = *(q-1);
93+ *p = *L->top;
15994 }
16095
16196
162−lua_Object lua_gettable (void)
163−{
164− checkCparams(2);
165− luaV_gettable();
166− return put_luaObjectonTop();
97+LUA_API void lua_pushvalue (lua_State *L, int index) {
98+ *L->top = *luaA_index(L, index);
99+ api_incr_top(L);
167100 }
168101
169102
170−lua_Object lua_rawgettable (void) {
171− checkCparams(2);
172− if (ttype(L->stack.top-2) != LUA_T_ARRAY)
173− lua_error("indexed expression not a table in rawgettable");
174− *(L->stack.top-2) = *luaH_get(avalue(L->stack.top-2), L->stack.top-1);
175− --L->stack.top;
176− return put_luaObjectonTop();
177−}
178−
179103
180−void lua_settable (void) {
181− checkCparams(3);
182− luaD_checkstack(3); /* may need that to call T.M. */
183− luaV_settable(L->stack.top-3);
184− L->stack.top -= 2; /* pop table and index */
185−}
104+/*
105+** access functions (stack -> C)
106+*/
186107
187108
188−void lua_rawsettable (void) {
189− checkCparams(3);
190− luaV_rawsettable(L->stack.top-3);
109+LUA_API int lua_type (lua_State *L, int index) {
110+ StkId o = luaA_indexAcceptable(L, index);
111+ return (o == NULL) ? LUA_TNONE : ttype(o);
191112 }
192113
193−
194−lua_Object lua_createtable (void)
195−{
196− TObject o;
197− luaC_checkGC();
198− avalue(&o) = luaH_new(0);
199− ttype(&o) = LUA_T_ARRAY;
200− return put_luaObject(&o);
114+LUA_API const char *lua_typename (lua_State *L, int t) {
115+ UNUSED(L);
116+ return (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
201117 }
202118
203119
204−lua_Object lua_getglobal (char *name)
205−{
206− luaD_checkstack(2); /* may need that to call T.M. */
207− luaV_getglobal(luaS_new(name));
208− return put_luaObjectonTop();
120+LUA_API int lua_iscfunction (lua_State *L, int index) {
121+ StkId o = luaA_indexAcceptable(L, index);
122+ return (o == NULL) ? 0 : iscfunction(o);
209123 }
210124
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);
128+}
211129
212−lua_Object lua_rawgetglobal (char *name)
213−{
214− TaggedString *ts = luaS_new(name);
215− return put_luaObject(&ts->u.s.globalval);
130+LUA_API int lua_isstring (lua_State *L, int index) {
131+ int t = lua_type(L, index);
132+ return (t == LUA_TSTRING || t == LUA_TNUMBER);
216133 }
217134
218135
219−void lua_setglobal (char *name)
220−{
221− checkCparams(1);
222− luaD_checkstack(2); /* may need that to call T.M. */
223− luaV_setglobal(luaS_new(name));
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);
224139 }
225140
141+LUA_API int lua_equal (lua_State *L, int index1, int index2) {
142+ StkId o1 = luaA_indexAcceptable(L, index1);
143+ 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);
146+}
226147
227−void lua_rawsetglobal (char *name)
228−{
229− TaggedString *ts = luaS_new(name);
230− checkCparams(1);
231− luaS_rawsetglobal(ts, --L->stack.top);
148+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);
232153 }
233154
234155
235156
236−int lua_isnil (lua_Object o)
237−{
238− return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_NIL);
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);
239160 }
240161
241−int lua_istable (lua_Object o)
242−{
243− return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY);
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);
244165 }
245166
246−int lua_isuserdata (lua_Object o)
247−{
248− return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA);
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;
249170 }
250171
251−int lua_iscfunction (lua_Object o)
252−{
253− return (lua_tag(o) == LUA_T_CPROTO);
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;
254175 }
255176
256−int lua_isnumber (lua_Object o)
257−{
258− return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0);
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;
259181 }
260182
261−int lua_isstring (lua_Object o)
262−{
263− int t = lua_tag(o);
264− return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
183+LUA_API const void *lua_topointer (lua_State *L, int index) {
184+ StkId o = luaA_indexAcceptable(L, index);
185+ if (o == NULL) return NULL;
186+ switch (ttype(o)) {
187+ case LUA_TTABLE:
188+ return hvalue(o);
189+ case LUA_TFUNCTION:
190+ return clvalue(o);
191+ default: return NULL;
192+ }
265193 }
266194
267−int lua_isfunction (lua_Object o)
268−{
269− int t = lua_tag(o);
270− return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
271−}
272195
273196
274−double lua_getnumber (lua_Object object)
275−{
276− if (object == LUA_NOOBJECT) return 0.0;
277− if (tonumber(Address(object))) return 0.0;
278− else return (nvalue(Address(object)));
279−}
197+/*
198+** push functions (C -> stack)
199+*/
280200
281−char *lua_getstring (lua_Object object)
282−{
283− luaC_checkGC(); /* "tostring" may create a new string */
284− if (object == LUA_NOOBJECT || tostring(Address(object)))
285− return NULL;
286− else return (svalue(Address(object)));
287−}
288201
289−long lua_strlen (lua_Object object)
290−{
291− luaC_checkGC(); /* "tostring" may create a new string */
292− if (object == LUA_NOOBJECT || tostring(Address(object)))
293− return 0L;
294− else return (tsvalue(Address(object))->u.s.len);
202+LUA_API void lua_pushnil (lua_State *L) {
203+ ttype(L->top) = LUA_TNIL;
204+ api_incr_top(L);
295205 }
296206
297−void *lua_getuserdata (lua_Object object)
298−{
299− if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
300− return NULL;
301− else return tsvalue(Address(object))->u.d.v;
302−}
303207
304−lua_CFunction lua_getcfunction (lua_Object object)
305−{
306− if (!lua_iscfunction(object))
307− return NULL;
308− else return fvalue(luaA_protovalue(Address(object)));
208+LUA_API void lua_pushnumber (lua_State *L, double n) {
209+ nvalue(L->top) = n;
210+ ttype(L->top) = LUA_TNUMBER;
211+ api_incr_top(L);
309212 }
310213
311214
312−void lua_pushnil (void)
313−{
314− ttype(L->stack.top) = LUA_T_NIL;
315− incr_top;
215+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;
218+ api_incr_top(L);
316219 }
317220
318−void lua_pushnumber (double n)
319−{
320− ttype(L->stack.top) = LUA_T_NUMBER;
321− nvalue(L->stack.top) = n;
322− incr_top;
323−}
324221
325−void lua_pushlstring (char *s, long len)
326−{
327− tsvalue(L->stack.top) = luaS_newlstr(s, len);
328− ttype(L->stack.top) = LUA_T_STRING;
329− incr_top;
330− luaC_checkGC();
331−}
332−
333−void lua_pushstring (char *s)
334−{
222+LUA_API void lua_pushstring (lua_State *L, const char *s) {
335223 if (s == NULL)
336− lua_pushnil();
224+ lua_pushnil(L);
337225 else
338− lua_pushlstring(s, strlen(s));
226+ lua_pushlstring(L, s, strlen(s));
339227 }
340228
341−void lua_pushcclosure (lua_CFunction fn, int n)
342−{
343− if (fn == NULL)
344− lua_error("API error - attempt to push a NULL Cfunction");
345− checkCparams(n);
346− ttype(L->stack.top) = LUA_T_CPROTO;
347− fvalue(L->stack.top) = fn;
348− incr_top;
349− luaV_closure(n);
350− luaC_checkGC();
351−}
352229
353−void lua_pushusertag (void *u, int tag)
354−{
355− if (tag < 0 && tag != LUA_ANYTAG)
356− luaT_realtag(tag); /* error if tag is not valid */
357− tsvalue(L->stack.top) = luaS_createudata(u, tag);
358− ttype(L->stack.top) = LUA_T_USERDATA;
359− incr_top;
360− luaC_checkGC();
230+LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
231+ luaV_Cclosure(L, fn, n);
361232 }
362233
363−void luaA_pushobject (TObject *o)
364−{
365− *L->stack.top = *o;
366− incr_top;
367−}
368234
369−void lua_pushobject (lua_Object o) {
370− if (o == LUA_NOOBJECT)
371− lua_error("API error - attempt to push a NOOBJECT");
372− set_normalized(L->stack.top, Address(o));
373− incr_top;
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);
374242 }
375243
376244
377−int lua_tag (lua_Object lo)
378−{
379− if (lo == LUA_NOOBJECT)
380− return LUA_T_NIL;
381− else {
382− TObject *o = Address(lo);
383− int t;
384− switch (t = ttype(o)) {
385− case LUA_T_USERDATA:
386− return o->value.ts->u.d.tag;
387− case LUA_T_ARRAY:
388− return o->value.a->htag;
389− case LUA_T_PMARK:
390− return LUA_T_PROTO;
391− case LUA_T_CMARK:
392− return LUA_T_CPROTO;
393− case LUA_T_CLOSURE: case LUA_T_CLMARK:
394− return o->value.cl->consts[0].ttype;
395−#ifdef DEBUG
396− case LUA_T_LINE:
397− LUA_INTERNALERROR("invalid type");
398−#endif
399− default:
400− return t;
401− }
402− }
403−}
404−
405245
406−void lua_settag (int tag)
407−{
408− checkCparams(1);
409− luaT_realtag(tag);
410− switch (ttype(L->stack.top-1)) {
411− case LUA_T_ARRAY:
412− (L->stack.top-1)->value.a->htag = tag;
413− break;
414− case LUA_T_USERDATA:
415− (L->stack.top-1)->value.ts->u.d.tag = tag;
416− break;
417− default:
418− luaL_verror("cannot change the tag of a %.20s",
419− luaO_typename(L->stack.top-1));
420− }
421− L->stack.top--;
422−}
246+/*
247+** get functions (Lua -> stack)
248+*/
423249
424250
425−TaggedString *luaA_nextvar (TaggedString *g) {
426− if (g == NULL)
427− g = (TaggedString *)L->rootglobal.next; /* first variable */
428− else {
429− /* check whether name is in global var list */
430− luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
431− g = (TaggedString *)g->head.next; /* get next */
432− }
433− while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
434− g = (TaggedString *)g->head.next;
435− if (g) {
436− ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
437− incr_top;
438− luaA_pushobject(&g->u.s.globalval);
439− }
440− return g;
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;
255+ api_incr_top(L);
441256 }
442257
443258
444−char *lua_nextvar (char *varname) {
445− TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname);
446− g = luaA_nextvar(g);
447− if (g) {
448− top2LC(2);
449− return g->str;
450− }
451− else {
452− top2LC(0);
453− return NULL;
454− }
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 */
455264 }
456265
457266
458−int luaA_next (Hash *t, int i) {
459− int tsize = nhash(t);
460− for (; i<tsize; i++) {
461− Node *n = node(t, i);
462− if (ttype(val(n)) != LUA_T_NIL) {
463− luaA_pushobject(ref(n));
464− luaA_pushobject(val(n));
465− return i+1; /* index to be used next time */
466− }
467− }
468− return 0; /* no more elements */
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);
469271 }
470272
471273
472−int lua_next (lua_Object o, int i) {
473− TObject *t = Address(o);
474− if (ttype(t) != LUA_T_ARRAY)
475− lua_error("API error - object is not a table in `lua_next'");
476− i = luaA_next(avalue(t), i);
477− top2LC((i==0) ? 0 : 2);
478− return i;
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);
479279 }
480280
481281
482−
483−/*
484−** {======================================================
485−** To manipulate some state information
486−** =======================================================
487−*/
488−
489−lua_State *lua_setstate (lua_State *st) {
490− lua_State *old = lua_state;
491− lua_state = st;
492− return old;
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);
493286 }
494287
495−lua_LHFunction lua_setlinehook (lua_LHFunction func) {
496− lua_LHFunction old = L->linehook;
497− L->linehook = func;
498− return old;
499−}
500288
501−lua_CHFunction lua_setcallhook (lua_CHFunction func) {
502− lua_CHFunction old = L->callhook;
503− L->callhook = func;
504− return old;
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;
297+ api_incr_top(L);
298+ return 1;
505299 }
506300
507−int lua_setdebug (int debug) {
508− int old = L->debug;
509− L->debug = debug;
510− return old;
301+
302+LUA_API void lua_newtable (lua_State *L) {
303+ hvalue(L->top) = luaH_new(L, 0);
304+ ttype(L->top) = LUA_TTABLE;
305+ api_incr_top(L);
511306 }
512307
513−/* }====================================================== */
514308
515309
516310 /*
517−** {======================================================
518−** Debug interface
519−** =======================================================
311+** set functions (stack -> Lua)
520312 */
521313
522314
523−lua_Function lua_stackedfunction (int level)
524−{
525− StkId i;
526− for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) {
527− int t = L->stack.stack[i].ttype;
528− if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
529− if (level-- == 0)
530− return Ref(L->stack.stack+i);
531− }
532− return LUA_NOOBJECT;
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 */
533319 }
534320
535321
536−int lua_nups (lua_Function func) {
537− TObject *o = luaA_Address(func);
538− return (!o || normalized_type(o) != LUA_T_CLOSURE) ? 0 : o->value.cl->nelems;
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 */
539327 }
540328
541329
542−int lua_currentline (lua_Function func)
543−{
544− TObject *f = Address(func);
545− return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ?
546− (f+1)->value.i : -1;
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;
547335 }
548336
549337
550−lua_Object lua_getlocal (lua_Function func, int local_number, char **name) {
551− /* check whether func is a Lua function */
552− if (lua_tag(func) != LUA_T_PROTO)
553− return LUA_NOOBJECT;
554− else {
555− TObject *f = Address(func);
556− TProtoFunc *fp = luaA_protovalue(f)->value.tf;
557− *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
558− if (*name) {
559− /* if "*name", there must be a LUA_T_LINE */
560− /* therefore, f+2 points to function base */
561− return put_luaObject((f+2)+(local_number-1));
562− }
563− else
564− return LUA_NOOBJECT;
565− }
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);
342+ L->top--;
566343 }
567344
568345
569−int lua_setlocal (lua_Function func, int local_number)
570−{
571− /* check whether func is a Lua function */
572− if (lua_tag(func) != LUA_T_PROTO)
573− return 0;
574− else {
575− TObject *f = Address(func);
576− TProtoFunc *fp = luaA_protovalue(f)->value.tf;
577− char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
578− checkCparams(1);
579− --L->stack.top;
580− if (name) {
581− /* if "name", there must be a LUA_T_LINE */
582− /* therefore, f+2 points to function base */
583− *((f+2)+(local_number-1)) = *L->stack.top;
584− return 1;
585− }
586− else
587− return 0;
588− }
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);
589350 }
590351
591352
592−void lua_funcinfo (lua_Object func, char **source, int *linedefined) {
593− if (!lua_isfunction(func))
594− lua_error("API error - `funcinfo' called with a non-function value");
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;
595357 else {
596− TObject *f = luaA_protovalue(Address(func));
597− if (normalized_type(f) == LUA_T_PROTO) {
598− *source = tfvalue(f)->source->str;
599− *linedefined = tfvalue(f)->lineDefined;
358+ if (L->refFree != NONEXT) { /* is there a free place? */
359+ ref = L->refFree;
360+ L->refFree = L->refArray[ref].st;
600361 }
601− else {
602− *source = "(C)";
603− *linedefined = -1;
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++;
604367 }
368+ L->refArray[ref].o = *(L->top-1);
369+ L->refArray[ref].st = lock ? LOCK : HOLD;
605370 }
371+ L->top--;
372+ return ref;
606373 }
607374
608375
609−static int checkfunc (TObject *o)
610−{
611− return luaO_equalObj(o, L->stack.top);
612−}
613−
376+/*
377+** "do" functions (run Lua code)
378+** (most of them are in ldo.c)
379+*/
614380
615−char *lua_getobjname (lua_Object o, char **name)
616−{ /* try to find a name for given function */
617− set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
618− if ((*name = luaS_travsymbol(checkfunc)) != NULL)
619− return "global";
620− else if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
621− return "tag-method";
622− else return "";
381+LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
382+ luaD_call(L, L->top-(nargs+1), nresults);
623383 }
624384
625−/* }====================================================== */
626−
627385
628386 /*
629−** {======================================================
630−** BLOCK mechanism
631−** =======================================================
387+** Garbage-collection functions
632388 */
633389
390+/* GC values are expressed in Kbytes: #bytes/2^10 */
391+#define GCscale(x) ((int)((x)>>10))
392+#define GCunscale(x) ((unsigned long)(x)<<10)
634393
635−#ifndef MAX_C_BLOCKS
636−#define MAX_C_BLOCKS 1000 /* arbitrary limit */
637−#endif
638−
394+LUA_API int lua_getgcthreshold (lua_State *L) {
395+ return GCscale(L->GCthreshold);
396+}
639397
640−void lua_beginblock (void) {
641− luaM_growvector(L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
642− "too many nested blocks", MAX_C_BLOCKS);
643− L->Cblocks[L->numCblocks] = L->Cstack;
644− L->numCblocks++;
398+LUA_API int lua_getgccount (lua_State *L) {
399+ return GCscale(L->nblocks);
645400 }
646401
647−void lua_endblock (void) {
648− --L->numCblocks;
649− L->Cstack = L->Cblocks[L->numCblocks];
650− luaD_adjusttop(L->Cstack.base);
402+LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
403+ if (newthreshold > GCscale(ULONG_MAX))
404+ L->GCthreshold = ULONG_MAX;
405+ else
406+ L->GCthreshold = GCunscale(newthreshold);
407+ luaC_checkGC(L);
651408 }
652409
653410
411+/*
412+** miscellaneous functions
413+*/
654414
655−int lua_ref (int lock) {
656− int ref;
657− checkCparams(1);
658− ref = luaC_ref(L->stack.top-1, lock);
659− L->stack.top--;
660− return ref;
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+ }
661428 }
662429
663430
664−
665−lua_Object lua_getref (int ref) {
666− TObject *o = luaC_getref(ref);
667− return (o ? put_luaObject(o) : LUA_NOOBJECT);
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+ }
668437 }
669438
670−/* }====================================================== */
671439
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);
448+ api_incr_top(L);
449+ return 1;
450+ }
451+ else { /* no more elements */
452+ L->top -= 1; /* remove key */
453+ return 0;
454+ }
455+}
672456
673457
674−#ifdef LUA_COMPAT2_5
675−/*
676−** API: set a function as a fallback
677−*/
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);
463+ 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;
475+ }
476+}
477+
678478
679−static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults) {
680− luaD_openstack(nParams);
681− (L->stack.top-nParams)->ttype = LUA_T_CPROTO;
682− (L->stack.top-nParams)->value.f = f;
683− luaD_calln(nParams, nResults);
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);
684484 }
685485
686486
687−lua_Object lua_setfallback (char *name, lua_CFunction fallback) {
688− lua_pushstring(name);
689− lua_pushcfunction(fallback);
690− do_unprotectedrun(luaT_setfallback, 2, 1);
691− return put_luaObjectonTop();
487+LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
488+ TString *ts = luaS_newudata(L, size, NULL);
489+ tsvalue(L->top) = ts;
490+ ttype(L->top) = LUA_TUSERDATA;
491+ api_incr_top(L);
492+ return ts->u.d.value;
692493 }
693−#endif
694494
src/lapi.h+3−8
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lapi.h,v 1.4 1999/02/23 14:57:28 roberto Exp $
2+** $Id: lapi.h,v 1.20 2000/08/31 14:08:27 roberto Exp $
33 ** Auxiliary functions from Lua API
44 ** See Copyright Notice in lua.h
55 */
@@ -8,15 +8,10 @@ · 2 unmodified lines
88 #define lapi_h
99
1010
11−#include "lua.h"
1211 #include "lobject.h"
1312
1413
15−TObject *luaA_Address (lua_Object o);
16−void luaA_pushobject (TObject *o);
17−void luaA_packresults (void);
18−int luaA_passresults (void);
19−TaggedString *luaA_nextvar (TaggedString *g);
20−int luaA_next (Hash *t, int i);
14+TObject *luaA_index (lua_State *L, int index);
15+void luaA_pushobject (lua_State *L, const TObject *o);
2116
2217 #endif
src/lauxlib.c+0−133
@@ -1,133 +0,0 @@
1−/*
2−** $Id: lauxlib.c,v 1.17 1999/03/11 18:59:19 roberto Exp $
3−** Auxiliary functions for building Lua libraries
4−** See Copyright Notice in lua.h
5−*/
6−
7−
8−#include <stdarg.h>
9−#include <stdio.h>
10−#include <string.h>
11−
12−/* Please Notice: This file uses only the official API of Lua
13−** Any function declared here could be written as an application function.
14−** With care, these functions can be used by other libraries.
15−*/
16−
17−#include "lauxlib.h"
18−#include "lua.h"
19−#include "luadebug.h"
20−
21−
22−
23−int luaL_findstring (char *name, char *list[]) {
24− int i;
25− for (i=0; list[i]; i++)
26− if (strcmp(list[i], name) == 0)
27− return i;
28− return -1; /* name not found */
29−}
30−
31−void luaL_argerror (int numarg, char *extramsg) {
32− lua_Function f = lua_stackedfunction(0);
33− char *funcname;
34− lua_getobjname(f, &funcname);
35− numarg -= lua_nups(f);
36− if (funcname == NULL)
37− funcname = "?";
38− if (extramsg == NULL)
39− luaL_verror("bad argument #%d to function `%.50s'", numarg, funcname);
40− else
41− luaL_verror("bad argument #%d to function `%.50s' (%.100s)",
42− numarg, funcname, extramsg);
43−}
44−
45−char *luaL_check_lstr (int numArg, long *len)
46−{
47− lua_Object o = lua_getparam(numArg);
48− luaL_arg_check(lua_isstring(o), numArg, "string expected");
49− if (len) *len = lua_strlen(o);
50− return lua_getstring(o);
51−}
52−
53−char *luaL_opt_lstr (int numArg, char *def, long *len)
54−{
55− return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
56− luaL_check_lstr(numArg, len);
57−}
58−
59−double luaL_check_number (int numArg)
60−{
61− lua_Object o = lua_getparam(numArg);
62− luaL_arg_check(lua_isnumber(o), numArg, "number expected");
63− return lua_getnumber(o);
64−}
65−
66−
67−double luaL_opt_number (int numArg, double def)
68−{
69− return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
70− luaL_check_number(numArg);
71−}
72−
73−
74−lua_Object luaL_tablearg (int arg)
75−{
76− lua_Object o = lua_getparam(arg);
77− luaL_arg_check(lua_istable(o), arg, "table expected");
78− return o;
79−}
80−
81−lua_Object luaL_functionarg (int arg)
82−{
83− lua_Object o = lua_getparam(arg);
84− luaL_arg_check(lua_isfunction(o), arg, "function expected");
85− return o;
86−}
87−
88−lua_Object luaL_nonnullarg (int numArg)
89−{
90− lua_Object o = lua_getparam(numArg);
91− luaL_arg_check(o != LUA_NOOBJECT, numArg, "value expected");
92− return o;
93−}
94−
95−void luaL_openlib (struct luaL_reg *l, int n)
96−{
97− int i;
98− lua_open(); /* make sure lua is already open */
99− for (i=0; i<n; i++)
100− lua_register(l[i].name, l[i].func);
101−}
102−
103−
104−void luaL_verror (char *fmt, ...)
105−{
106− char buff[500];
107− va_list argp;
108− va_start(argp, fmt);
109− vsprintf(buff, fmt, argp);
110− va_end(argp);
111− lua_error(buff);
112−}
113−
114−
115−void luaL_chunkid (char *out, char *source, int len) {
116− len -= 13; /* 13 = strlen("string ''...\0") */
117− if (*source == '@')
118− sprintf(out, "file `%.*s'", len, source+1);
119− else if (*source == '(')
120− strcpy(out, "(C code)");
121− else {
122− char *b = strchr(source , '\n'); /* stop string at first new line */
123− int lim = (b && (b-source)<len) ? b-source : len;
124− sprintf(out, "string `%.*s'", lim, source);
125− strcpy(out+lim+(13-5), "...'"); /* 5 = strlen("...'\0") */
126− }
127−}
128−
129−
130−void luaL_filesource (char *out, char *filename, int len) {
131− if (filename == NULL) filename = "(stdin)";
132− sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
133−}
src/lbuffer.c+0−75
@@ -1,75 +0,0 @@
1−/*
2−** $Id: lbuffer.c,v 1.9 1999/02/26 15:48:55 roberto Exp $
3−** Auxiliary functions for building Lua libraries
4−** See Copyright Notice in lua.h
5−*/
6−
7−
8−#include <stdio.h>
9−
10−#include "lauxlib.h"
11−#include "lmem.h"
12−#include "lstate.h"
13−
14−
15−/*-------------------------------------------------------
16−** Auxiliary buffer
17−-------------------------------------------------------*/
18−
19−
20−#define EXTRABUFF 32
21−
22−
23−#define openspace(size) if (L->Mbuffnext+(size) > L->Mbuffsize) Openspace(size)
24−
25−static void Openspace (int size) {
26− lua_State *l = L; /* to optimize */
27− size += EXTRABUFF;
28− l->Mbuffsize = l->Mbuffnext+size;
29− luaM_growvector(l->Mbuffer, l->Mbuffnext, size, char, arrEM, MAX_INT);
30−}
31−
32−
33−char *luaL_openspace (int size) {
34− openspace(size);
35− return L->Mbuffer+L->Mbuffnext;
36−}
37−
38−
39−void luaL_addchar (int c) {
40− openspace(1);
41− L->Mbuffer[L->Mbuffnext++] = (char)c;
42−}
43−
44−
45−void luaL_resetbuffer (void) {
46− L->Mbuffnext = L->Mbuffbase;
47−}
48−
49−
50−void luaL_addsize (int n) {
51− L->Mbuffnext += n;
52−}
53−
54−int luaL_getsize (void) {
55− return L->Mbuffnext-L->Mbuffbase;
56−}
57−
58−int luaL_newbuffer (int size) {
59− int old = L->Mbuffbase;
60− openspace(size);
61− L->Mbuffbase = L->Mbuffnext;
62− return old;
63−}
64−
65−
66−void luaL_oldbuffer (int old) {
67− L->Mbuffnext = L->Mbuffbase;
68− L->Mbuffbase = old;
69−}
70−
71−
72−char *luaL_buffer (void) {
73− return L->Mbuffer+L->Mbuffbase;
74−}
75−
src/lbuiltin.c+0−736
@@ -1,736 +0,0 @@
1−/*
2−** $Id: lbuiltin.c,v 1.59 1999/06/17 17:04:03 roberto Exp $
3−** Built-in functions
4−** See Copyright Notice in lua.h
5−*/
6−
7−
8−#include <ctype.h>
9−#include <stdio.h>
10−#include <stdlib.h>
11−#include <string.h>
12−
13−#include "lapi.h"
14−#include "lauxlib.h"
15−#include "lbuiltin.h"
16−#include "ldo.h"
17−#include "lfunc.h"
18−#include "lmem.h"
19−#include "lobject.h"
20−#include "lstate.h"
21−#include "lstring.h"
22−#include "ltable.h"
23−#include "ltm.h"
24−#include "lua.h"
25−#include "lundump.h"
26−#include "lvm.h"
27−
28−
29−
30−/*
31−** {======================================================
32−** Auxiliary functions
33−** =======================================================
34−*/
35−
36−
37−static void pushtagstring (TaggedString *s) {
38− TObject o;
39− o.ttype = LUA_T_STRING;
40− o.value.ts = s;
41− luaA_pushobject(&o);
42−}
43−
44−
45−static real getsize (Hash *h) {
46− real max = 0;
47− int i;
48− for (i = 0; i<nhash(h); i++) {
49− Node *n = h->node+i;
50− if (ttype(ref(n)) == LUA_T_NUMBER &&
51− ttype(val(n)) != LUA_T_NIL &&
52− nvalue(ref(n)) > max)
53− max = nvalue(ref(n));
54− }
55− return max;
56−}
57−
58−
59−static real getnarg (Hash *a) {
60− TObject index;
61− TObject *value;
62− /* value = table.n */
63− ttype(&index) = LUA_T_STRING;
64− tsvalue(&index) = luaS_new("n");
65− value = luaH_get(a, &index);
66− return (ttype(value) == LUA_T_NUMBER) ? nvalue(value) : getsize(a);
67−}
68−
69−
70−static Hash *gethash (int arg) {
71− return avalue(luaA_Address(luaL_tablearg(arg)));
72−}
73−
74−/* }====================================================== */
75−
76−
77−/*
78−** {======================================================
79−** Functions that use only the official API
80−** =======================================================
81−*/
82−
83−
84−/*
85−** If your system does not support "stderr", redefine this function, or
86−** redefine _ERRORMESSAGE so that it won't need _ALERT.
87−*/
88−static void luaB_alert (void) {
89− fputs(luaL_check_string(1), stderr);
90−}
91−
92−
93−/*
94−** Standard implementation of _ERRORMESSAGE.
95−** The library "iolib" redefines _ERRORMESSAGE for better error information.
96−*/
97−static void error_message (void) {
98− lua_Object al = lua_rawgetglobal("_ALERT");
99− if (lua_isfunction(al)) { /* avoid error loop if _ALERT is not defined */
100− char buff[600];
101− sprintf(buff, "lua error: %.500s\n", luaL_check_string(1));
102− lua_pushstring(buff);
103− lua_callfunction(al);
104− }
105−}
106−
107−
108−/*
109−** If your system does not support "stdout", just remove this function.
110−** If you need, you can define your own "print" function, following this
111−** model but changing "fputs" to put the strings at a proper place
112−** (a console window or a log file, for instance).
113−*/
114−#ifndef MAXPRINT
115−#define MAXPRINT 40 /* arbitrary limit */
116−#endif
117−
118−static void luaB_print (void) {
119− lua_Object args[MAXPRINT];
120− lua_Object obj;
121− int n = 0;
122− int i;
123− while ((obj = lua_getparam(n+1)) != LUA_NOOBJECT) {
124− luaL_arg_check(n < MAXPRINT, n+1, "too many arguments");
125− args[n++] = obj;
126− }
127− for (i=0; i<n; i++) {
128− lua_pushobject(args[i]);
129− if (lua_call("tostring"))
130− lua_error("error in `tostring' called by `print'");
131− obj = lua_getresult(1);
132− if (!lua_isstring(obj))
133− lua_error("`tostring' must return a string to `print'");
134− if (i>0) fputs("\t", stdout);
135− fputs(lua_getstring(obj), stdout);
136− }
137− fputs("\n", stdout);
138−}
139−
140−
141−static void luaB_tonumber (void) {
142− int base = luaL_opt_int(2, 10);
143− if (base == 10) { /* standard conversion */
144− lua_Object o = lua_getparam(1);
145− if (lua_isnumber(o)) lua_pushnumber(lua_getnumber(o));
146− else lua_pushnil(); /* not a number */
147− }
148− else {
149− char *s = luaL_check_string(1);
150− long n;
151− luaL_arg_check(0 <= base && base <= 36, 2, "base out of range");
152− n = strtol(s, &s, base);
153− while (isspace((unsigned char)*s)) s++; /* skip trailing spaces */
154− if (*s) lua_pushnil(); /* invalid format: return nil */
155− else lua_pushnumber(n);
156− }
157−}
158−
159−
160−static void luaB_error (void) {
161− lua_error(lua_getstring(lua_getparam(1)));
162−}
163−
164−static void luaB_setglobal (void) {
165− char *n = luaL_check_string(1);
166− lua_Object value = luaL_nonnullarg(2);
167− lua_pushobject(value);
168− lua_setglobal(n);
169− lua_pushobject(value); /* return given value */
170−}
171−
172−static void luaB_rawsetglobal (void) {
173− char *n = luaL_check_string(1);
174− lua_Object value = luaL_nonnullarg(2);
175− lua_pushobject(value);
176− lua_rawsetglobal(n);
177− lua_pushobject(value); /* return given value */
178−}
179−
180−static void luaB_getglobal (void) {
181− lua_pushobject(lua_getglobal(luaL_check_string(1)));
182−}
183−
184−static void luaB_rawgetglobal (void) {
185− lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
186−}
187−
188−static void luaB_luatag (void) {
189− lua_pushnumber(lua_tag(lua_getparam(1)));
190−}
191−
192−static void luaB_settag (void) {
193− lua_Object o = luaL_tablearg(1);
194− lua_pushobject(o);
195− lua_settag(luaL_check_int(2));
196− lua_pushobject(o); /* return first argument */
197−}
198−
199−static void luaB_newtag (void) {
200− lua_pushnumber(lua_newtag());
201−}
202−
203−static void luaB_copytagmethods (void) {
204− lua_pushnumber(lua_copytagmethods(luaL_check_int(1),
205− luaL_check_int(2)));
206−}
207−
208−static void luaB_rawgettable (void) {
209− lua_pushobject(luaL_nonnullarg(1));
210− lua_pushobject(luaL_nonnullarg(2));
211− lua_pushobject(lua_rawgettable());
212−}
213−
214−static void luaB_rawsettable (void) {
215− lua_pushobject(luaL_nonnullarg(1));
216− lua_pushobject(luaL_nonnullarg(2));
217− lua_pushobject(luaL_nonnullarg(3));
218− lua_rawsettable();
219−}
220−
221−static void luaB_settagmethod (void) {
222− lua_Object nf = luaL_nonnullarg(3);
223− lua_pushobject(nf);
224− lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2)));
225−}
226−
227−static void luaB_gettagmethod (void) {
228− lua_pushobject(lua_gettagmethod(luaL_check_int(1), luaL_check_string(2)));
229−}
230−
231−static void luaB_seterrormethod (void) {
232− lua_Object nf = luaL_functionarg(1);
233− lua_pushobject(nf);
234− lua_pushobject(lua_seterrormethod());
235−}
236−
237−static void luaB_collectgarbage (void) {
238− lua_pushnumber(lua_collectgarbage(luaL_opt_int(1, 0)));
239−}
240−
241−/* }====================================================== */
242−
243−
244−/*
245−** {======================================================
246−** Functions that could use only the official API but
247−** do not, for efficiency.
248−** =======================================================
249−*/
250−
251−static void luaB_dostring (void) {
252− long l;
253− char *s = luaL_check_lstr(1, &l);
254− if (*s == ID_CHUNK)
255− lua_error("`dostring' cannot run pre-compiled code");
256− if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
257− if (luaA_passresults() == 0)
258− lua_pushuserdata(NULL); /* at least one result to signal no errors */
259−}
260−
261−
262−static void luaB_dofile (void) {
263− char *fname = luaL_opt_string(1, NULL);
264− if (lua_dofile(fname) == 0)
265− if (luaA_passresults() == 0)
266− lua_pushuserdata(NULL); /* at least one result to signal no errors */
267−}
268−
269−
270−static void luaB_call (void) {
271− lua_Object f = luaL_nonnullarg(1);
272− Hash *arg = gethash(2);
273− char *options = luaL_opt_string(3, "");
274− lua_Object err = lua_getparam(4);
275− int narg = (int)getnarg(arg);
276− int i, status;
277− if (err != LUA_NOOBJECT) { /* set new error method */
278− lua_pushobject(err);
279− err = lua_seterrormethod();
280− }
281− /* push arg[1...n] */
282− luaD_checkstack(narg);
283− for (i=0; i<narg; i++)
284− *(L->stack.top++) = *luaH_getint(arg, i+1);
285− status = lua_callfunction(f);
286− if (err != LUA_NOOBJECT) { /* restore old error method */
287− lua_pushobject(err);
288− lua_seterrormethod();
289− }
290− if (status != 0) { /* error in call? */
291− if (strchr(options, 'x')) {
292− lua_pushnil();
293− return; /* return nil to signal the error */
294− }
295− else
296− lua_error(NULL);
297− }
298− else { /* no errors */
299− if (strchr(options, 'p'))
300− luaA_packresults();
301− else
302− luaA_passresults();
303− }
304−}
305−
306−
307−static void luaB_nextvar (void) {
308− TObject *o = luaA_Address(luaL_nonnullarg(1));
309− TaggedString *g;
310− if (ttype(o) == LUA_T_NIL)
311− g = NULL;
312− else {
313− luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
314− g = tsvalue(o);
315− }
316− if (!luaA_nextvar(g))
317− lua_pushnil();
318−}
319−
320−
321−static void luaB_next (void) {
322− Hash *a = gethash(1);
323− TObject *k = luaA_Address(luaL_nonnullarg(2));
324− int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1;
325− if (luaA_next(a, i) == 0)
326− lua_pushnil();
327−}
328−
329−
330−static void luaB_tostring (void) {
331− lua_Object obj = lua_getparam(1);
332− TObject *o = luaA_Address(obj);
333− char buff[64];
334− switch (ttype(o)) {
335− case LUA_T_NUMBER:
336− lua_pushstring(lua_getstring(obj));
337− return;
338− case LUA_T_STRING:
339− lua_pushobject(obj);
340− return;
341− case LUA_T_ARRAY:
342− sprintf(buff, "table: %p", (void *)o->value.a);
343− break;
344− case LUA_T_CLOSURE:
345− sprintf(buff, "function: %p", (void *)o->value.cl);
346− break;
347− case LUA_T_PROTO:
348− sprintf(buff, "function: %p", (void *)o->value.tf);
349− break;
350− case LUA_T_CPROTO:
351− sprintf(buff, "function: %p", (void *)o->value.f);
352− break;
353− case LUA_T_USERDATA:
354− sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
355− break;
356− case LUA_T_NIL:
357− lua_pushstring("nil");
358− return;
359− default:
360− LUA_INTERNALERROR("invalid type");
361− }
362− lua_pushstring(buff);
363−}
364−
365−
366−static void luaB_type (void) {
367− lua_Object o = luaL_nonnullarg(1);
368− lua_pushstring(luaO_typename(luaA_Address(o)));
369− lua_pushnumber(lua_tag(o));
370−}
371−
372−/* }====================================================== */
373−
374−
375−
376−/*
377−** {======================================================
378−** "Extra" functions
379−** These functions can be written in Lua, so you can
380−** delete them if you need a tiny Lua implementation.
381−** If you delete them, remove their entries in array
382−** "builtin_funcs".
383−** =======================================================
384−*/
385−
386−static void luaB_assert (void) {
387− lua_Object p = lua_getparam(1);
388− if (p == LUA_NOOBJECT || lua_isnil(p))
389− luaL_verror("assertion failed! %.100s", luaL_opt_string(2, ""));
390−}
391−
392−
393−static void luaB_foreachi (void) {
394− Hash *t = gethash(1);
395− int i;
396− int n = (int)getnarg(t);
397− TObject f;
398− /* 'f' cannot be a pointer to TObject, because it is on the stack, and the
399− stack may be reallocated by the call. Moreover, some C compilers do not
400− initialize structs, so we must do the assignment after the declaration */
401− f = *luaA_Address(luaL_functionarg(2));
402− luaD_checkstack(3); /* for f, ref, and val */
403− for (i=1; i<=n; i++) {
404− *(L->stack.top++) = f;
405− ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i;
406− *(L->stack.top++) = *luaH_getint(t, i);
407− luaD_calln(2, 1);
408− if (ttype(L->stack.top-1) != LUA_T_NIL)
409− return;
410− L->stack.top--;
411− }
412−}
413−
414−
415−static void luaB_foreach (void) {
416− Hash *a = gethash(1);
417− int i;
418− TObject f; /* see comment in 'foreachi' */
419− f = *luaA_Address(luaL_functionarg(2));
420− luaD_checkstack(3); /* for f, ref, and val */
421− for (i=0; i<a->nhash; i++) {
422− Node *nd = &(a->node[i]);
423− if (ttype(val(nd)) != LUA_T_NIL) {
424− *(L->stack.top++) = f;
425− *(L->stack.top++) = *ref(nd);
426− *(L->stack.top++) = *val(nd);
427− luaD_calln(2, 1);
428− if (ttype(L->stack.top-1) != LUA_T_NIL)
429− return;
430− L->stack.top--; /* remove result */
431− }
432− }
433−}
434−
435−
436−static void luaB_foreachvar (void) {
437− GCnode *g;
438− TObject f; /* see comment in 'foreachi' */
439− f = *luaA_Address(luaL_functionarg(1));
440− luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
441− for (g = L->rootglobal.next; g; g = g->next) {
442− TaggedString *s = (TaggedString *)g;
443− if (s->u.s.globalval.ttype != LUA_T_NIL) {
444− pushtagstring(s); /* keep (extra) s on stack to avoid GC */
445− *(L->stack.top++) = f;
446− pushtagstring(s);
447− *(L->stack.top++) = s->u.s.globalval;
448− luaD_calln(2, 1);
449− if (ttype(L->stack.top-1) != LUA_T_NIL) {
450− L->stack.top--;
451− *(L->stack.top-1) = *L->stack.top; /* remove extra s */
452− return;
453− }
454− L->stack.top-=2; /* remove result and extra s */
455− }
456− }
457−}
458−
459−
460−static void luaB_getn (void) {
461− lua_pushnumber(getnarg(gethash(1)));
462−}
463−
464−
465−static void luaB_tinsert (void) {
466− Hash *a = gethash(1);
467− lua_Object v = lua_getparam(3);
468− int n = (int)getnarg(a);
469− int pos;
470− if (v != LUA_NOOBJECT)
471− pos = luaL_check_int(2);
472− else { /* called with only 2 arguments */
473− v = luaL_nonnullarg(2);
474− pos = n+1;
475− }
476− luaV_setn(a, n+1); /* a.n = n+1 */
477− for ( ;n>=pos; n--)
478− luaH_move(a, n, n+1); /* a[n+1] = a[n] */
479− luaH_setint(a, pos, luaA_Address(v)); /* a[pos] = v */
480−}
481−
482−
483−static void luaB_tremove (void) {
484− Hash *a = gethash(1);
485− int n = (int)getnarg(a);
486− int pos = luaL_opt_int(2, n);
487− if (n <= 0) return; /* table is "empty" */
488− luaA_pushobject(luaH_getint(a, pos)); /* result = a[pos] */
489− for ( ;pos<n; pos++)
490− luaH_move(a, pos+1, pos); /* a[pos] = a[pos+1] */
491− luaV_setn(a, n-1); /* a.n = n-1 */
492− luaH_setint(a, n, &luaO_nilobject); /* a[n] = nil */
493−}
494−
495−
496−/* {
497−** Quicksort
498−*/
499−
500−static void swap (Hash *a, int i, int j) {
501− TObject temp;
502− temp = *luaH_getint(a, i);
503− luaH_move(a, j, i);
504− luaH_setint(a, j, &temp);
505−}
506−
507−static int sort_comp (lua_Object f, TObject *a, TObject *b) {
508− /* notice: the caller (auxsort) must check stack space */
509− if (f != LUA_NOOBJECT) {
510− *(L->stack.top) = *luaA_Address(f);
511− *(L->stack.top+1) = *a;
512− *(L->stack.top+2) = *b;
513− L->stack.top += 3;
514− luaD_calln(2, 1);
515− }
516− else { /* a < b? */
517− *(L->stack.top) = *a;
518− *(L->stack.top+1) = *b;
519− L->stack.top += 2;
520− luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
521− }
522− return ttype(--(L->stack.top)) != LUA_T_NIL;
523−}
524−
525−static void auxsort (Hash *a, int l, int u, lua_Object f) {
526− while (l < u) { /* for tail recursion */
527− TObject *P;
528− int i, j;
529− /* sort elements a[l], a[(l+u)/2] and a[u] */
530− if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */
531− swap(a, l, u);
532− if (u-l == 1) break; /* only 2 elements */
533− i = (l+u)/2;
534− P = luaH_getint(a, i);
535− if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */
536− swap(a, l, i);
537− else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */
538− swap(a, i, u);
539− if (u-l == 2) break; /* only 3 elements */
540− P = L->stack.top++;
541− *P = *luaH_getint(a, i); /* save pivot on stack (for GC) */
542− swap(a, i, u-1); /* put median element as pivot (a[u-1]) */
543− /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
544− i = l; j = u-1;
545− for (;;) {
546− /* invariant: a[l..i] <= P <= a[j..u] */
547− while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */
548− if (i>u) lua_error("invalid order function for sorting");
549− while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */
550− if (j<l) lua_error("invalid order function for sorting");
551− if (j<i) break;
552− swap(a, i, j);
553− }
554− swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */
555− L->stack.top--; /* remove pivot from stack */
556− /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
557− /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
558− if (i-l < u-i) {
559− j=l; i=i-1; l=i+2;
560− }
561− else {
562− j=i+1; i=u; u=j-2;
563− }
564− auxsort(a, j, i, f); /* call recursively the smaller one */
565− } /* repeat the routine for the larger one */
566−}
567−
568−static void luaB_sort (void) {
569− lua_Object t = lua_getparam(1);
570− Hash *a = gethash(1);
571− int n = (int)getnarg(a);
572− lua_Object func = lua_getparam(2);
573− luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2,
574− "function expected");
575− luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */
576− auxsort(a, 1, n, func);
577− lua_pushobject(t);
578−}
579−
580−/* }}===================================================== */
581−
582−
583−/*
584−** ====================================================== */
585−
586−
587−
588−#ifdef DEBUG
589−/*
590−** {======================================================
591−** some DEBUG functions
592−** =======================================================
593−*/
594−
595−static void mem_query (void) {
596− lua_pushnumber(totalmem);
597− lua_pushnumber(numblocks);
598−}
599−
600−
601−static void query_strings (void) {
602− lua_pushnumber(L->string_root[luaL_check_int(1)].nuse);
603−}
604−
605−
606−static void countlist (void) {
607− char *s = luaL_check_string(1);
608− GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
609− (s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
610− int i=0;
611− while (l) {
612− i++;
613− l = l->next;
614− }
615− lua_pushnumber(i);
616−}
617−
618−
619−static void testC (void) {
620−#define getnum(s) ((*s++) - '0')
621−#define getname(s) (nome[0] = *s++, nome)
622−
623− static int locks[10];
624− lua_Object reg[10];
625− char nome[2];
626− char *s = luaL_check_string(1);
627− nome[1] = 0;
628− for (;;) {
629− switch (*s++) {
630− case '0': case '1': case '2': case '3': case '4':
631− case '5': case '6': case '7': case '8': case '9':
632− lua_pushnumber(*(s-1) - '0');
633− break;
634−
635− case 'c': reg[getnum(s)] = lua_createtable(); break;
636− case 'C': { lua_CFunction f = lua_getcfunction(lua_getglobal(getname(s)));
637− lua_pushcclosure(f, getnum(s));
638− break;
639− }
640− case 'P': reg[getnum(s)] = lua_pop(); break;
641− case 'g': { int n=getnum(s); reg[n]=lua_getglobal(getname(s)); break; }
642− case 'G': { int n = getnum(s);
643− reg[n] = lua_rawgetglobal(getname(s));
644− break;
645− }
646− case 'l': locks[getnum(s)] = lua_ref(1); break;
647− case 'L': locks[getnum(s)] = lua_ref(0); break;
648− case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; }
649− case 'u': lua_unref(locks[getnum(s)]); break;
650− case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; }
651− case '=': lua_setglobal(getname(s)); break;
652− case 's': lua_pushstring(getname(s)); break;
653− case 'o': lua_pushobject(reg[getnum(s)]); break;
654− case 'f': lua_call(getname(s)); break;
655− case 'i': reg[getnum(s)] = lua_gettable(); break;
656− case 'I': reg[getnum(s)] = lua_rawgettable(); break;
657− case 't': lua_settable(); break;
658− case 'T': lua_rawsettable(); break;
659− case 'N' : lua_pushstring(lua_nextvar(lua_getstring(reg[getnum(s)])));
660− break;
661− case 'n' : { int n=getnum(s);
662− n=lua_next(reg[n], (int)lua_getnumber(reg[getnum(s)]));
663− lua_pushnumber(n); break;
664− }
665− default: luaL_verror("unknown command in `testC': %c", *(s-1));
666− }
667− if (*s == 0) return;
668− if (*s++ != ' ') lua_error("missing ` ' between commands in `testC'");
669− }
670−}
671−
672−/* }====================================================== */
673−#endif
674−
675−
676−
677−static struct luaL_reg builtin_funcs[] = {
678−#ifdef LUA_COMPAT2_5
679− {"setfallback", luaT_setfallback},
680−#endif
681−#ifdef DEBUG
682− {"testC", testC},
683− {"totalmem", mem_query},
684− {"count", countlist},
685− {"querystr", query_strings},
686−#endif
687− {"_ALERT", luaB_alert},
688− {"_ERRORMESSAGE", error_message},
689− {"call", luaB_call},
690− {"collectgarbage", luaB_collectgarbage},
691− {"copytagmethods", luaB_copytagmethods},
692− {"dofile", luaB_dofile},
693− {"dostring", luaB_dostring},
694− {"error", luaB_error},
695− {"getglobal", luaB_getglobal},
696− {"gettagmethod", luaB_gettagmethod},
697− {"newtag", luaB_newtag},
698− {"next", luaB_next},
699− {"nextvar", luaB_nextvar},
700− {"print", luaB_print},
701− {"rawgetglobal", luaB_rawgetglobal},
702− {"rawgettable", luaB_rawgettable},
703− {"rawsetglobal", luaB_rawsetglobal},
704− {"rawsettable", luaB_rawsettable},
705− {"seterrormethod", luaB_seterrormethod},
706− {"setglobal", luaB_setglobal},
707− {"settag", luaB_settag},
708− {"settagmethod", luaB_settagmethod},
709− {"tag", luaB_luatag},
710− {"tonumber", luaB_tonumber},
711− {"tostring", luaB_tostring},
712− {"type", luaB_type},
713− /* "Extra" functions */
714− {"assert", luaB_assert},
715− {"foreach", luaB_foreach},
716− {"foreachi", luaB_foreachi},
717− {"foreachvar", luaB_foreachvar},
718− {"getn", luaB_getn},
719− {"sort", luaB_sort},
720− {"tinsert", luaB_tinsert},
721− {"tremove", luaB_tremove}
722−};
723−
724−
725−#define INTFUNCSIZE (sizeof(builtin_funcs)/sizeof(builtin_funcs[0]))
726−
727−
728−void luaB_predefine (void) {
729− /* pre-register mem error messages, to avoid loop when error arises */
730− luaS_newfixedstring(tableEM);
731− luaS_newfixedstring(memEM);
732− luaL_openlib(builtin_funcs, (sizeof(builtin_funcs)/sizeof(builtin_funcs[0])));
733− lua_pushstring(LUA_VERSION);
734− lua_setglobal("_VERSION");
735−}
736−
src/lbuiltin.h+0−14
@@ -1,14 +0,0 @@
1−/*
2−** $Id: lbuiltin.h,v 1.1 1997/09/16 19:25:59 roberto Exp $
3−** Built-in functions
4−** See Copyright Notice in lua.h
5−*/
6−
7−#ifndef lbuiltin_h
8−#define lbuiltin_h
9−
10−
11−void luaB_predefine (void);
12−
13−
14−#endif
src/lcode.c+701−0
@@ -0,0 +1,701 @@
1+/*
2+** $Id: lcode.c,v 1.51 2000/09/29 12:42:13 roberto Exp $
3+** Code generator for Lua
4+** See Copyright Notice in lua.h
5+*/
6+
7+
8+#include "stdlib.h"
9+
10+#include "lua.h"
11+
12+#include "lcode.h"
13+#include "ldo.h"
14+#include "llex.h"
15+#include "lmem.h"
16+#include "lobject.h"
17+#include "lopcodes.h"
18+#include "lparser.h"
19+
20+
21+void luaK_error (LexState *ls, const char *msg) {
22+ luaX_error(ls, msg, ls->t.token);
23+}
24+
25+
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' */
36+}
37+
38+
39+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+ return j;
46+}
47+
48+
49+static void luaK_fixjump (FuncState *fs, int pc, int dest) {
50+ 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+ }
59+}
60+
61+
62+static int luaK_getjump (FuncState *fs, int pc) {
63+ int offset = GETARG_S(fs->f->code[pc]);
64+ if (offset == NO_JUMP) /* point to itself represents end of list */
65+ return NO_JUMP; /* end of list */
66+ else
67+ return (pc+1)+offset; /* turn offset into absolute position */
68+}
69+
70+
71+/*
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.
75+*/
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) */
82+ }
83+ return fs->pc;
84+}
85+
86+
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+ }
94+}
95+
96+
97+void luaK_kstr (LexState *ls, int c) {
98+ luaK_code1(ls->fs, OP_PUSHSTRING, c);
99+}
100+
101+
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));
123+}
124+
125+
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);
131+}
132+
133+
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;
140+}
141+
142+
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 */
147+ }
148+}
149+
150+
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 */
164+ }
165+ var->k = VEXP;
166+ var->u.l.t = var->u.l.f = NO_JUMP;
167+ return 1;
168+}
169+
170+
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 */
176+}
177+
178+
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");
193+ }
194+}
195+
196+
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+ }
211+}
212+
213+
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;
231+ }
232+}
233+
234+
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);
240+}
241+
242+
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 */
248+}
249+
250+
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+ }
265+}
266+
267+
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)));
289+ }
290+ luaK_concat(fs, exitlist, prevpos); /* insert last jump in `exitlist' */
291+ luaK_patchlist(fs, *golist, luaK_getlabel(fs));
292+ *golist = NO_JUMP;
293+}
294+
295+
296+void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {
297+ luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);
298+}
299+
300+
301+static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
302+ luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);
303+}
304+
305+
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;
344+ }
345+ }
346+}
347+
348+
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);
354+ }
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; }
365+ }
366+}
367+
368+
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 */
380+ }
381+}
382+
383+
384+
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+};
395+
396+
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);
405+ break;
406+ }
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);
412+ break;
413+ }
414+ default: {
415+ luaK_tostack(ls, v2, 1); /* `v2' must be a value */
416+ luaK_code1(fs, codes[op].opcode, codes[op].arg);
417+ }
418+ }
419+}
420+
421+
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+ }
433+}
434+
435+
436+int luaK_code0 (FuncState *fs, OpCode o) {
437+ return luaK_code2(fs, o, 0, 0);
438+}
439+
440+
441+int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
442+ return luaK_code2(fs, o, arg1, 0);
443+}
444+
445+
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;
453+ break;
454+ }
455+ case OP_SETTABLE: {
456+ delta = -arg2;
457+ break;
458+ }
459+ case OP_SETLIST: {
460+ if (arg2 == 0) return NO_JUMP; /* nothing to do */
461+ delta = -arg2;
462+ break;
463+ }
464+ case OP_SETMAP: {
465+ if (arg1 == 0) return NO_JUMP; /* nothing to do */
466+ delta = -2*arg1;
467+ break;
468+ }
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+ }
475+ break;
476+ }
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+ }
484+ break;
485+ }
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+ }
493+ break;
494+ }
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+ }
507+ break;
508+ }
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+ }
514+ break;
515+ }
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+ }
524+ break;
525+ }
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+ }
535+ break;
536+ }
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+ }
549+ break;
550+ }
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+ }
556+ break;
557+ }
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;
565+ }
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+ }
591+ break;
592+ }
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+ }
615+ break;
616+ }
617+ case OP_GETDOTTED:
618+ case OP_GETINDEXED:
619+ case OP_TAILCALL:
620+ case OP_ADDI: {
621+ LUA_INTERNALERROR("instruction used only for optimizations");
622+ break;
623+ }
624+ default: {
625+ LUA_ASSERT(delta != VD, "invalid delta");
626+ break;
627+ }
628+ }
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 */
633+ }
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;
640+ }
641+ codelineinfo(fs);
642+ /* 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;
646+ return fs->pc++;
647+}
648+
649+
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+};
701+
src/lcode.h+70−0
@@ -0,0 +1,70 @@
1+/*
2+** $Id: lcode.h,v 1.16 2000/08/09 14:49:13 roberto Exp $
3+** Code generator for Lua
4+** See Copyright Notice in lua.h
5+*/
6+
7+#ifndef lcode_h
8+#define lcode_h
9+
10+#include "llex.h"
11+#include "lobject.h"
12+#include "lopcodes.h"
13+#include "lparser.h"
14+
15+
16+/*
17+** Marks the end of a patch list. It is an invalid value both as an absolute
18+** address, and as a list link (would link an element to itself).
19+*/
20+#define NO_JUMP (-1)
21+
22+
23+/*
24+** grep "ORDER OPR" if you change these enums
25+*/
26+typedef enum BinOpr {
27+ OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
28+ OPR_CONCAT,
29+ OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
30+ OPR_AND, OPR_OR,
31+ OPR_NOBINOPR
32+} BinOpr;
33+
34+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
35+
36+
37+enum Mode {iO, iU, iS, iAB}; /* instruction format */
38+
39+#define VD 100 /* flag for variable delta */
40+
41+extern const struct OpProperties {
42+ char mode;
43+ unsigned char push;
44+ unsigned char pop;
45+} luaK_opproperties[];
46+
47+
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);
52+int luaK_jump (FuncState *fs);
53+void luaK_patchlist (FuncState *fs, int list, int target);
54+void luaK_concat (FuncState *fs, int *l1, int l2);
55+void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
56+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);
68+
69+
70+#endif
src/ldebug.c+466−0
@@ -0,0 +1,466 @@
1+/*
2+** $Id: ldebug.c,v 1.50 2000/10/30 12:38:50 roberto Exp $
3+** Debug Interface
4+** See Copyright Notice in lua.h
5+*/
6+
7+
8+#include <stdlib.h>
9+
10+#include "lua.h"
11+
12+#include "lapi.h"
13+#include "lcode.h"
14+#include "ldebug.h"
15+#include "ldo.h"
16+#include "lfunc.h"
17+#include "lobject.h"
18+#include "lopcodes.h"
19+#include "lstate.h"
20+#include "lstring.h"
21+#include "ltable.h"
22+#include "ltm.h"
23+#include "luadebug.h"
24+
25+
26+
27+static const char *getfuncname (lua_State *L, StkId f, const char **name);
28+
29+
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+}
37+
38+
39+static int isLmark (StkId o) {
40+ return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC);
41+}
42+
43+
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;
48+}
49+
50+
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;
55+}
56+
57+
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+ }
66+ }
67+ return NULL;
68+}
69+
70+
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+ }
78+}
79+
80+
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+ }
90+}
91+
92+
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;
121+}
122+
123+
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 */
137+ else {
138+ CallInfo *ci = infovalue(f);
139+ int *lineinfo = ci->func->f.l->lineinfo;
140+ return luaG_getline(lineinfo, currentpc(f), 1, NULL);
141+ }
142+}
143+
144+
145+
146+static Proto *getluaproto (StkId f) {
147+ return (isLmark(f) ? infovalue(f)->func->f.l : NULL);
148+}
149+
150+
151+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
152+ 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 */
159+ return name;
160+}
161+
162+
163+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
164+ const char *name;
165+ StkId f = ar->_func;
166+ Proto *fp = getluaproto(f);
167+ 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;
172+ return name;
173+}
174+
175+
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";
197+ ar->linedefined = -1;
198+ ar->what = "C";
199+ }
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+ }
217+ }
218+ return NULL;
219+}
220+
221+
222+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;
229+ }
230+ return NULL;
231+}
232+
233+
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 */
244+}
245+
246+
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+ }
256+ for (; *what; what++) {
257+ switch (*what) {
258+ case 'S': {
259+ funcinfo(L, ar, func);
260+ break;
261+ }
262+ case 'l': {
263+ ar->currentline = currentline(func);
264+ break;
265+ }
266+ case 'u': {
267+ ar->nups = nups(func);
268+ break;
269+ }
270+ case 'n': {
271+ ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL;
272+ if (ar->namewhat == NULL)
273+ getname(L, func, ar);
274+ break;
275+ }
276+ case 'f': {
277+ setnormalized(L->top, func);
278+ incr_top; /* push function */
279+ break;
280+ }
281+ default: return 0; /* invalid option */
282+ }
283+ }
284+ if (!isactive) L->top--; /* pop function */
285+ return 1;
286+}
287+
288+
289+/*
290+** {======================================================
291+** Symbolic Execution
292+** =======================================================
293+*/
294+
295+
296+static int pushpc (int *stack, int pc, int top, int n) {
297+ while (n--)
298+ stack[top++] = pc-1;
299+ return top;
300+}
301+
302+
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);
317+ break;
318+ }
319+ case OP_TAILCALL: {
320+ LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
321+ top = GETARG_B(i);
322+ break;
323+ }
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);
329+ break;
330+ }
331+ case OP_PUSHNIL: {
332+ top = pushpc(stack, pc, top, GETARG_U(i));
333+ break;
334+ }
335+ case OP_POP: {
336+ top -= GETARG_U(i);
337+ break;
338+ }
339+ case OP_SETTABLE:
340+ case OP_SETLIST: {
341+ top -= GETARG_B(i);
342+ break;
343+ }
344+ case OP_SETMAP: {
345+ top -= 2*GETARG_U(i);
346+ break;
347+ }
348+ case OP_CONCAT: {
349+ top -= GETARG_U(i);
350+ stack[top++] = pc-1;
351+ break;
352+ }
353+ case OP_CLOSURE: {
354+ top -= GETARG_B(i);
355+ stack[top++] = pc-1;
356+ break;
357+ }
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 */
365+ }
366+ else
367+ top--; /* do not jump; pop value */
368+ break;
369+ }
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);
377+ }
378+ }
379+ }
380+ return code[stack[stackpos]];
381+}
382+
383+
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");
394+ switch (GET_OPCODE(i)) {
395+ case OP_GETGLOBAL: {
396+ *name = p->kstr[GETARG_U(i)]->str;
397+ return "global";
398+ }
399+ case OP_GETLOCAL: {
400+ *name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
401+ LUA_ASSERT(*name, "local must exist");
402+ return "local";
403+ }
404+ case OP_PUSHSELF:
405+ case OP_GETDOTTED: {
406+ *name = p->kstr[GETARG_U(i)]->str;
407+ return "field";
408+ }
409+ default:
410+ return NULL; /* no useful name found */
411+ }
412+ }
413+}
414+
415+
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+ }
433+}
434+
435+
436+/* }====================================================== */
437+
438+
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);
443+ if (kind)
444+ luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
445+ op, kind, name, t);
446+ else
447+ luaO_verror(L, "attempt to %.30s a %.10s value", op, t);
448+}
449+
450+
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);
455+}
456+
457+
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);
461+ if (t1[2] == t2[2])
462+ luaO_verror(L, "attempt to compare two %.10s values", t1);
463+ else
464+ luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2);
465+}
466+
src/ldebug.h+21−0
@@ -0,0 +1,21 @@
1+/*
2+** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp $
3+** Auxiliary functions from Debug Interface module
4+** See Copyright Notice in lua.h
5+*/
6+
7+#ifndef ldebug_h
8+#define ldebug_h
9+
10+
11+#include "lstate.h"
12+#include "luadebug.h"
13+
14+
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);
19+
20+
21+#endif
src/ldo.c+271−273
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ldo.c,v 1.45b 1999/06/22 20:37:23 roberto Exp $
2+** $Id: ldo.c,v 1.109 2000/10/30 12:38:50 roberto Exp $
33 ** Stack and Call structure of Lua
44 ** See Copyright Notice in lua.h
55 */
@@ -10,378 +10,376 @@ · 4 unmodified lines
1010 #include <stdlib.h>
1111 #include <string.h>
1212
13−#include "lauxlib.h"
13+#include "lua.h"
14+
15+#include "ldebug.h"
1416 #include "ldo.h"
15−#include "lfunc.h"
1617 #include "lgc.h"
1718 #include "lmem.h"
1819 #include "lobject.h"
1920 #include "lparser.h"
2021 #include "lstate.h"
2122 #include "lstring.h"
23+#include "ltable.h"
2224 #include "ltm.h"
23−#include "lua.h"
24−#include "luadebug.h"
2525 #include "lundump.h"
2626 #include "lvm.h"
2727 #include "lzio.h"
2828
2929
30+/* space to handle stack overflow errors */
31+#define EXTRA_STACK (2*LUA_MINSTACK)
3032
31−#ifndef STACK_LIMIT
32−#define STACK_LIMIT 6000 /* arbitrary limit */
33−#endif
34−
35−
36−
37−#define STACK_UNIT 128
3833
39−
40−#ifdef DEBUG
41−#undef STACK_UNIT
42−#define STACK_UNIT 2
43−#endif
44−
45−
46−void luaD_init (void) {
47− L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
48− L->stack.top = L->stack.stack;
49− L->stack.last = L->stack.stack+(STACK_UNIT-1);
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;
5040 }
5141
5242
53−void luaD_checkstack (int n) {
54− struct Stack *S = &L->stack;
55− if (S->last-S->top <= n) {
56− StkId top = S->top-S->stack;
57− int stacksize = (S->last-S->stack)+STACK_UNIT+n;
58− luaM_reallocvector(S->stack, stacksize, TObject);
59− S->last = S->stack+(stacksize-1);
60− S->top = S->stack + top;
61− if (stacksize >= STACK_LIMIT) { /* stack overflow? */
62− if (lua_stackedfunction(100) == LUA_NOOBJECT) /* 100 funcs on stack? */
63− lua_error("Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */
64− else
65− lua_error("stack size overflow");
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 */
48+ }
49+ else {
50+ L->stack_last += EXTRA_STACK; /* to be used by error message */
51+ lua_error(L, "stack overflow");
6652 }
6753 }
6854 }
6955
7056
57+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);
60+}
61+
62+
7163 /*
72−** Adjust stack. Set top to the given value, pushing NILs if needed.
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)
7367 */
74−void luaD_adjusttop (StkId newtop) {
75− int diff = newtop-(L->stack.top-L->stack.stack);
68+void luaD_adjusttop (lua_State *L, StkId base, int extra) {
69+ int diff = extra-(L->top-base);
7670 if (diff <= 0)
77− L->stack.top += diff;
71+ L->top = base+extra;
7872 else {
79− luaD_checkstack(diff);
73+ luaD_checkstack(L, diff);
8074 while (diff--)
81− ttype(L->stack.top++) = LUA_T_NIL;
75+ ttype(L->top++) = LUA_TNIL;
8276 }
8377 }
8478
8579
8680 /*
87−** Open a hole below "nelems" from the L->stack.top.
81+** Open a hole inside the stack at `pos'
8882 */
89−void luaD_openstack (int nelems) {
90− luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems,
91− nelems*sizeof(TObject));
83+static void luaD_openstack (lua_State *L, StkId pos) {
84+ int i = L->top-pos;
85+ while (i--) pos[i+1] = pos[i];
9286 incr_top;
9387 }
9488
9589
96−void luaD_lineHook (int line) {
97− struct C_Lua_Stack oldCLS = L->Cstack;
98− StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
99− L->Cstack.num = 0;
100− (*L->linehook)(line);
101− L->stack.top = L->stack.stack+old_top;
102− L->Cstack = oldCLS;
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;
103100 }
104101
105102
106−void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn) {
107− struct C_Lua_Stack oldCLS = L->Cstack;
108− StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
109− L->Cstack.num = 0;
110− if (isreturn)
111− (*L->callhook)(LUA_NOOBJECT, "(return)", 0);
112− else {
113− TObject *f = L->stack.stack+base-1;
114− if (tf)
115− (*L->callhook)(Ref(f), tf->source->str, tf->lineDefined);
116− else
117− (*L->callhook)(Ref(f), "(C)", -1);
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);
118110 }
119− L->stack.top = L->stack.stack+old_top;
120− L->Cstack = oldCLS;
121111 }
122112
123113
124−/*
125−** Call a C function.
126−** Cstack.num is the number of arguments; Cstack.lua2C points to the
127−** first argument. Returns an index to the first result from C.
128−*/
129−static StkId callC (lua_CFunction f, StkId base) {
130− struct C_Lua_Stack *cls = &L->Cstack;
131− struct C_Lua_Stack oldCLS = *cls;
132− StkId firstResult;
133− int numarg = (L->stack.top-L->stack.stack) - base;
134− cls->num = numarg;
135− cls->lua2C = base;
136− cls->base = base+numarg; /* == top-stack */
137− if (L->callhook)
138− luaD_callHook(base, NULL, 0);
139− (*f)(); /* do the actual call */
140− if (L->callhook) /* func may have changed callhook */
141− luaD_callHook(base, NULL, 1);
142− firstResult = cls->base;
143− *cls = oldCLS;
144− return firstResult;
114+static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
115+ const char *event) {
116+ if (L->allowhooks) {
117+ lua_Debug ar;
118+ ar._func = func;
119+ ar.event = event;
120+ infovalue(func)->pc = NULL; /* function is not active */
121+ dohook(L, &ar, callhook);
122+ }
145123 }
146124
147125
148−static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base) {
149− TObject *pbase;
150− int nup = cl->nelems; /* number of upvalues */
151− luaD_checkstack(nup);
152− pbase = L->stack.stack+base; /* care: previous call may change this */
153− /* open space for upvalues as extra arguments */
154− luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject));
155− /* copy upvalues into stack */
156− memcpy(pbase, cl->consts+1, nup*sizeof(TObject));
157− L->stack.top += nup;
158− return callC(f, base);
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 */
159137 }
160138
161139
162−void luaD_callTM (TObject *f, int nParams, int nResults) {
163− luaD_openstack(nParams);
164− *(L->stack.top-nParams-1) = *f;
165− luaD_calln(nParams, nResults);
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);
166146 }
167147
168148
169149 /*
170−** Call a function (C or Lua). The parameters must be on the stack,
171−** between [top-nArgs,top). The function to be called is right below the
172−** arguments.
173−** When returns, the results are on the stack, between [top-nArgs-1,top).
174−** The number of results is nResults, unless nResults=MULT_RET.
175−*/
176−void luaD_calln (int nArgs, int nResults) {
177− struct Stack *S = &L->stack; /* to optimize */
178− StkId base = (S->top-S->stack)-nArgs;
179− TObject *func = S->stack+base-1;
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;
180158 StkId firstResult;
181− int i;
182− switch (ttype(func)) {
183− case LUA_T_CPROTO:
184− ttype(func) = LUA_T_CMARK;
185− firstResult = callC(fvalue(func), base);
186− break;
187− case LUA_T_PROTO:
188− ttype(func) = LUA_T_PMARK;
189− firstResult = luaV_execute(NULL, tfvalue(func), base);
190− break;
191− case LUA_T_CLOSURE: {
192− Closure *c = clvalue(func);
193− TObject *proto = &(c->consts[0]);
194− ttype(func) = LUA_T_CLMARK;
195− firstResult = (ttype(proto) == LUA_T_CPROTO) ?
196− callCclosure(c, fvalue(proto), base) :
197− luaV_execute(c, tfvalue(proto), base);
198− break;
199− }
200− default: { /* func is not a function */
201− /* Check the tag method for invalid functions */
202− TObject *im = luaT_getimbyObj(func, IM_FUNCTION);
203− if (ttype(im) == LUA_T_NIL)
204− lua_error("call expression not a function");
205− luaD_callTM(im, (S->top-S->stack)-(base-1), nResults);
206− return;
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;
169+ }
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;
187+ }
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 */
207195 }
208196 }
209− /* adjust the number of results */
210− if (nResults == MULT_RET)
211− nResults = (S->top-S->stack)-firstResult;
212− else
213− luaD_adjusttop(firstResult+nResults);
214− /* move results to base-1 (to erase parameters and function) */
215− base--;
216− for (i=0; i<nResults; i++)
217− *(S->stack+base+i) = *(S->stack+firstResult+i);
218− S->top -= firstResult-base;
197+ luaC_checkGC(L);
219198 }
220199
221200
222201 /*
223−** Traverse all objects on L->stack.stack
202+** Execute a protected call.
224203 */
225−void luaD_travstack (int (*fn)(TObject *))
226−{
227− StkId i;
228− for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
229− fn(L->stack.stack+i);
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);
230212 }
231213
232214
233−
234−static void message (char *s) {
235− TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
236− if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
237− ttype(em) == LUA_T_CLOSURE) {
238− *L->stack.top = *em;
239− incr_top;
240− lua_pushstring(s);
241− luaD_calln(1, 0);
242− }
243−}
244−
245−/*
246−** Reports an error, and jumps up to the available recover label
247−*/
248−void lua_error (char *s) {
249− if (s) message(s);
250− if (L->errorJmp)
251− longjmp(L->errorJmp->b, 1);
252− else {
253− message("exit(1). Unable to recover.\n");
254− exit(1);
255− }
256−}
257−
258−
259−/*
260−** Execute a protected call. Assumes that function is at L->Cstack.base and
261−** parameters are on top of it. Leave nResults on the stack.
262−*/
263−int luaD_protectedrun (void) {
264− volatile struct C_Lua_Stack oldCLS = L->Cstack;
265− struct lua_longjmp myErrorJmp;
266− volatile int status;
267− struct lua_longjmp *volatile oldErr = L->errorJmp;
268− L->errorJmp = &myErrorJmp;
269− if (setjmp(myErrorJmp.b) == 0) {
270− StkId base = L->Cstack.base;
271− luaD_calln((L->stack.top-L->stack.stack)-base-1, MULT_RET);
272− L->Cstack.lua2C = base; /* position of the new results */
273− L->Cstack.num = (L->stack.top-L->stack.stack) - base;
274− L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
275− status = 0;
276− }
277− else { /* an error occurred: restore L->Cstack and L->stack.top */
278− L->Cstack = oldCLS;
279− L->stack.top = L->stack.stack+L->Cstack.base;
280− status = 1;
281− }
282− L->errorJmp = oldErr;
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 */
283223 return status;
284224 }
285225
286226
287227 /*
288−** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
228+** Execute a protected parser.
289229 */
290−static int protectedparser (ZIO *z, int bin) {
291− volatile struct C_Lua_Stack oldCLS = L->Cstack;
292− struct lua_longjmp myErrorJmp;
293− volatile int status;
294− TProtoFunc *volatile tf;
295− struct lua_longjmp *volatile oldErr = L->errorJmp;
296− L->errorJmp = &myErrorJmp;
297− if (setjmp(myErrorJmp.b) == 0) {
298− tf = bin ? luaU_undump1(z) : luaY_parser(z);
299− status = 0;
300− }
301− else { /* an error occurred: restore L->Cstack and L->stack.top */
302− L->Cstack = oldCLS;
303− L->stack.top = L->stack.stack+L->Cstack.base;
304− tf = NULL;
305− status = 1;
306− }
307− L->errorJmp = oldErr;
308− if (status) return 1; /* error code */
309− if (tf == NULL) return 2; /* 'natural' end */
310− luaD_adjusttop(L->Cstack.base+1); /* one slot for the pseudo-function */
311− L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO;
312− L->stack.stack[L->Cstack.base].value.tf = tf;
313− luaV_closure(0);
314− return 0;
315−}
316−
230+struct ParserS { /* data to `f_parser' */
231+ ZIO *z;
232+ int bin;
233+};
317234
318−static int do_main (ZIO *z, int bin) {
319− int status;
320− int debug = L->debug; /* save debug status */
321− do {
322− long old_blocks = (luaC_checkGC(), L->nblocks);
323− status = protectedparser(z, bin);
324− if (status == 1) return 1; /* error */
325− else if (status == 2) return 0; /* 'natural' end */
326− else {
327− unsigned long newelems2 = 2*(L->nblocks-old_blocks);
328− L->GCthreshold += newelems2;
329− status = luaD_protectedrun();
330− L->GCthreshold -= newelems2;
331− }
332− } while (bin && status == 0);
333− L->debug = debug; /* restore debug status */
334− return status;
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);
335239 }
336240
337241
338−void luaD_gcIM (TObject *o)
339−{
340− TObject *im = luaT_getimbyObj(o, IM_GC);
341− if (ttype(im) != LUA_T_NIL) {
342− *L->stack.top = *o;
343− incr_top;
344− luaD_callTM(im, 1, 0);
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+ luaC_checkGC(L);
248+ old_blocks = L->nblocks;
249+ status = luaD_runprotected(L, f_parser, &p);
250+ if (status == 0) {
251+ /* add new memory to threshold (as it probably will stay) */
252+ L->GCthreshold += (L->nblocks - old_blocks);
345253 }
254+ else if (status == LUA_ERRRUN) /* an error occurred: correct error code */
255+ status = LUA_ERRSYNTAX;
256+ return status;
346257 }
347258
348259
349−#define MAXFILENAME 260 /* maximum part of a file name kept */
350−
351−int lua_dofile (char *filename) {
260+static int parse_file (lua_State *L, const char *filename) {
352261 ZIO z;
353262 int status;
354− int c;
355− int bin;
356− char source[MAXFILENAME];
263+ int bin; /* flag for file mode */
264+ int c; /* look ahead char */
357265 FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
358− if (f == NULL)
359− return 2;
360− luaL_filesource(source, filename, sizeof(source));
266+ if (f == NULL) return LUA_ERRFILE; /* unable to open file */
361267 c = fgetc(f);
362268 ungetc(c, f);
363269 bin = (c == ID_CHUNK);
364270 if (bin && f != stdin) {
365271 f = freopen(filename, "rb", f); /* set binary mode */
366− if (f == NULL) return 2;
272+ if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */
367273 }
368− luaZ_Fopen(&z, f, source);
369− status = do_main(&z, bin);
274+ lua_pushstring(L, "@");
275+ lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
276+ lua_concat(L, 2);
277+ filename = lua_tostring(L, -1); /* filename = '@'..filename */
278+ lua_pop(L, 1); /* OK: there is no GC during parser */
279+ luaZ_Fopen(&z, f, filename);
280+ status = protectedparser(L, &z, bin);
370281 if (f != stdin)
371282 fclose(f);
372283 return status;
373284 }
374285
375286
376−int lua_dostring (char *str) {
377− return lua_dobuffer(str, strlen(str), str);
287+LUA_API int lua_dofile (lua_State *L, const char *filename) {
288+ int status = parse_file(L, filename);
289+ if (status == 0) /* parse OK? */
290+ status = lua_call(L, 0, LUA_MULTRET); /* call main */
291+ return status;
378292 }
379293
380294
381−int lua_dobuffer (char *buff, int size, char *name) {
295+static int parse_buffer (lua_State *L, const char *buff, size_t size,
296+ const char *name) {
382297 ZIO z;
383298 if (!name) name = "?";
384299 luaZ_mopen(&z, buff, size, name);
385− return do_main(&z, buff[0]==ID_CHUNK);
300+ return protectedparser(L, &z, buff[0]==ID_CHUNK);
386301 }
387302
303+
304+LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
305+ int status = parse_buffer(L, buff, size, name);
306+ if (status == 0) /* parse OK? */
307+ status = lua_call(L, 0, LUA_MULTRET); /* call main */
308+ return status;
309+}
310+
311+
312+LUA_API int lua_dostring (lua_State *L, const char *str) {
313+ return lua_dobuffer(L, str, strlen(str), str);
314+}
315+
316+
317+/*
318+** {======================================================
319+** Error-recover functions (based on long jumps)
320+** =======================================================
321+*/
322+
323+/* chain list of long jump buffers */
324+struct lua_longjmp {
325+ jmp_buf b;
326+ struct lua_longjmp *previous;
327+ volatile int status; /* error code */
328+};
329+
330+
331+static void message (lua_State *L, const char *s) {
332+ const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE);
333+ if (ttype(em) == LUA_TFUNCTION) {
334+ *L->top = *em;
335+ incr_top;
336+ lua_pushstring(L, s);
337+ luaD_call(L, L->top-2, 0);
338+ }
339+}
340+
341+
342+/*
343+** Reports an error, and jumps up to the available recovery label
344+*/
345+LUA_API void lua_error (lua_State *L, const char *s) {
346+ if (s) message(L, s);
347+ luaD_breakrun(L, LUA_ERRRUN);
348+}
349+
350+
351+void luaD_breakrun (lua_State *L, int errcode) {
352+ if (L->errorJmp) {
353+ L->errorJmp->status = errcode;
354+ longjmp(L->errorJmp->b, 1);
355+ }
356+ else {
357+ if (errcode != LUA_ERRMEM)
358+ message(L, "unable to recover; exiting\n");
359+ exit(EXIT_FAILURE);
360+ }
361+}
362+
363+
364+int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
365+ StkId oldCbase = L->Cbase;
366+ StkId oldtop = L->top;
367+ struct lua_longjmp lj;
368+ int allowhooks = L->allowhooks;
369+ lj.status = 0;
370+ lj.previous = L->errorJmp; /* chain new error handler */
371+ L->errorJmp = &lj;
372+ if (setjmp(lj.b) == 0)
373+ (*f)(L, ud);
374+ else { /* an error occurred: restore the state */
375+ L->allowhooks = allowhooks;
376+ L->Cbase = oldCbase;
377+ L->top = oldtop;
378+ restore_stack_limit(L);
379+ }
380+ L->errorJmp = lj.previous; /* restore old error handler */
381+ return lj.status;
382+}
383+
384+/* }====================================================== */
385+
src/ldo.h+10−23
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ldo.h,v 1.6 1999/06/22 20:37:23 roberto Exp $
2+** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp $
33 ** Stack and Call structure of Lua
44 ** See Copyright Notice in lua.h
55 */
@@ -12,35 +12,22 @@ · 6 unmodified lines
1212 #include "lstate.h"
1313
1414
15−#define MULT_RET 255
16−
17−
18−
1915 /*
2016 ** macro to increment stack top.
2117 ** There must be always an empty slot at the L->stack.top
2218 */
23−#define incr_top { if (L->stack.top >= L->stack.last) luaD_checkstack(1); \
24− L->stack.top++; }
25−
26−
27−/* macros to convert from lua_Object to (TObject *) and back */
19+#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
2820
29−#define Address(lo) ((lo)+L->stack.stack-1)
30−#define Ref(st) ((st)-L->stack.stack+1)
3121
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);
3228
33−void luaD_init (void);
34−void luaD_adjusttop (StkId newtop);
35−void luaD_openstack (int nelems);
36−void luaD_lineHook (int line);
37−void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn);
38−void luaD_calln (int nArgs, int nResults);
39−void luaD_callTM (TObject *f, int nParams, int nResults);
40−int luaD_protectedrun (void);
41−void luaD_gcIM (TObject *o);
42−void luaD_travstack (int (*fn)(TObject *));
43−void luaD_checkstack (int n);
29+void luaD_breakrun (lua_State *L, int errcode);
30+int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);
4431
4532
4633 #endif
src/lfunc.c+66−55
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lfunc.c,v 1.10 1999/03/04 21:17:26 roberto Exp $
2+** $Id: lfunc.c,v 1.34 2000/10/30 12:20:29 roberto Exp $
33 ** Auxiliary functions to manipulate prototypes and closures
44 ** See Copyright Notice in lua.h
55 */
@@ -7,92 +7,103 @@ · 1 unmodified line
77
88 #include <stdlib.h>
99
10+#include "lua.h"
11+
1012 #include "lfunc.h"
1113 #include "lmem.h"
1214 #include "lstate.h"
1315
14−#define gcsizeproto(p) 5 /* approximate "weight" for a prototype */
15−#define gcsizeclosure(c) 1 /* approximate "weight" for a closure */
1616
17+#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1))
1718
1819
19−Closure *luaF_newclosure (int nelems)
20−{
21− Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
22− luaO_insertlist(&(L->rootcl), (GCnode *)c);
23− L->nblocks += gcsizeclosure(c);
24− c->nelems = nelems;
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;
2528 return c;
2629 }
2730
2831
29−TProtoFunc *luaF_newproto (void)
30−{
31− TProtoFunc *f = luaM_new(TProtoFunc);
32+Proto *luaF_newproto (lua_State *L) {
33+ 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;
3240 f->code = NULL;
41+ f->ncode = 0;
42+ f->numparams = 0;
43+ f->is_vararg = 0;
44+ f->maxstacksize = 0;
45+ f->marked = 0;
46+ f->lineinfo = NULL;
47+ f->nlineinfo = 0;
48+ f->nlocvars = 0;
49+ f->locvars = NULL;
3350 f->lineDefined = 0;
3451 f->source = NULL;
35− f->consts = NULL;
36− f->nconsts = 0;
37− f->locvars = NULL;
38− luaO_insertlist(&(L->rootproto), (GCnode *)f);
39− L->nblocks += gcsizeproto(f);
52+ f->next = L->rootproto; /* chain in list of protos */
53+ L->rootproto = f;
4054 return f;
4155 }
4256
4357
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+}
4467
45−static void freefunc (TProtoFunc *f)
46−{
47− luaM_free(f->code);
48− luaM_free(f->locvars);
49− luaM_free(f->consts);
50− luaM_free(f);
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);
5172 }
5273
5374
54−void luaF_freeproto (TProtoFunc *l)
55−{
56− while (l) {
57− TProtoFunc *next = (TProtoFunc *)l->head.next;
58− L->nblocks -= gcsizeproto(l);
59− freefunc(l);
60− l = next;
61− }
75+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);
6285 }
6386
6487
65−void luaF_freeclosure (Closure *l)
66−{
67− while (l) {
68− Closure *next = (Closure *)l->head.next;
69− L->nblocks -= gcsizeclosure(l);
70− luaM_free(l);
71− l = next;
72− }
88+void luaF_freeclosure (lua_State *L, Closure *c) {
89+ L->nblocks -= sizeclosure(c->nupvalues);
90+ luaM_free(L, c);
7391 }
7492
7593
7694 /*
77−** Look for n-th local variable at line "line" in function "func".
95+** Look for n-th local variable at line `line' in function `func'.
7896 ** Returns NULL if not found.
7997 */
80−char *luaF_getlocalname (TProtoFunc *func, int local_number, int line)
81−{
82− int count = 0;
83− char *varname = NULL;
84− LocVar *lv = func->locvars;
85− if (lv == NULL)
86− return NULL;
87− for (; lv->line != -1 && lv->line < line; lv++) {
88− if (lv->varname) { /* register */
89− if (++count == local_number)
90− varname = lv->varname->str;
98+const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
99+ int i;
100+ for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
101+ if (pc < f->locvars[i].endpc) { /* is variable active? */
102+ local_number--;
103+ if (local_number == 0)
104+ return f->locvars[i].varname->str;
91105 }
92− else /* unregister */
93− if (--count < local_number)
94− varname = NULL;
95106 }
96− return varname;
107+ return NULL; /* not found */
97108 }
98109
src/lfunc.h+8−7
@@ -1,6 +1,6 @@
11 /*
2−** $Id: lfunc.h,v 1.5 1997/12/15 16:17:20 roberto Exp $
3−** Lua Function structures
2+** $Id: lfunc.h,v 1.13 2000/09/29 12:42:13 roberto Exp $
3+** Auxiliary functions to manipulate prototypes and closures
44 ** See Copyright Notice in lua.h
55 */
66
@@ -12,12 +12,13 @@ · 5 unmodified lines
1212
1313
1414
15−TProtoFunc *luaF_newproto (void);
16−Closure *luaF_newclosure (int nelems);
17−void luaF_freeproto (TProtoFunc *l);
18−void luaF_freeclosure (Closure *l);
15+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);
18+void luaF_freeproto (lua_State *L, Proto *f);
19+void luaF_freeclosure (lua_State *L, Closure *c);
1920
20−char *luaF_getlocalname (TProtoFunc *func, int local_number, int line);
21+const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
2122
2223
2324 #endif
src/lgc.c+260−182
@@ -1,9 +1,10 @@
11 /*
2−** $Id: lgc.c,v 1.23 1999/03/04 21:17:26 roberto Exp $
2+** $Id: lgc.c,v 1.72 2000/10/26 12:47:05 roberto Exp $
33 ** Garbage Collector
44 ** See Copyright Notice in lua.h
55 */
66
7+#include "lua.h"
78
89 #include "ldo.h"
910 #include "lfunc.h"
@@ -14,262 +15,339 @@ · 4 unmodified lines
1415 #include "lstring.h"
1516 #include "ltable.h"
1617 #include "ltm.h"
17−#include "lua.h"
1818
1919
20+typedef struct GCState {
21+ Hash *tmark; /* list of marked tables to be visited */
22+ Closure *cmark; /* list of marked closures to be visited */
23+} GCState;
2024
21−static int markobject (TObject *o);
2225
2326
27+static void markobject (GCState *st, TObject *o);
2428
25−/*
26−** =======================================================
27−** REF mechanism
28−** =======================================================
29−*/
3029
30+/* mark a string; marks larger than 1 cannot be changed */
31+#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;}
3132
32−int luaC_ref (TObject *o, int lock) {
33− int ref;
34− if (ttype(o) == LUA_T_NIL)
35− ref = -1; /* special ref for nil */
36− else {
37− for (ref=0; ref<L->refSize; ref++)
38− if (L->refArray[ref].status == FREE)
39− break;
40− if (ref == L->refSize) { /* no more empty spaces? */
41− luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
42− L->refSize++;
43− }
44− L->refArray[ref].o = *o;
45− L->refArray[ref].status = lock ? LOCK : HOLD;
33+
34+
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);
4646 }
47− return ref;
4847 }
4948
5049
51−void lua_unref (int ref)
52−{
53− if (ref >= 0 && ref < L->refSize)
54− L->refArray[ref].status = FREE;
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);
5554 }
5655
5756
58−TObject* luaC_getref (int ref)
59−{
60− if (ref == -1)
61− return &luaO_nilobject;
62− if (ref >= 0 && ref < L->refSize &&
63− (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD))
64− return &L->refArray[ref].o;
65− else
66− return NULL;
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);
62+ }
6763 }
6864
6965
70−static void travlock (void)
71−{
72− int i;
73− for (i=0; i<L->refSize; i++)
74− if (L->refArray[i].status == LOCK)
75− markobject(&L->refArray[i].o);
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;
72+ }
73+}
74+
75+
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);
83+ }
84+ }
85+}
86+
87+
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+ }
108+}
109+
110+
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]);
126+ }
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+ }
140+ }
141+ else break; /* nothing else to mark */
142+ }
76143 }
77144
78145
79−static int ismarked (TObject *o)
80−{
146+static int hasmark (const TObject *o) {
81147 /* valid only for locked objects */
82148 switch (o->ttype) {
83− case LUA_T_STRING: case LUA_T_USERDATA:
84− return o->value.ts->head.marked;
85− case LUA_T_ARRAY:
86− return o->value.a->head.marked;
87− case LUA_T_CLOSURE:
88− return o->value.cl->head.marked;
89− case LUA_T_PROTO:
90− return o->value.tf->head.marked;
91−#ifdef DEBUG
92− case LUA_T_LINE: case LUA_T_CLMARK:
93− case LUA_T_CMARK: case LUA_T_PMARK:
94− LUA_INTERNALERROR("invalid type");
95−#endif
96− default: /* nil, number or cproto */
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 */
97156 return 1;
98157 }
99158 }
100159
101160
102−static void invalidaterefs (void)
103−{
161+/* macro for internal debugging; check if a link of free refs is valid */
162+#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
163+
164+static void invalidaterefs (lua_State *L) {
165+ int n = L->refSize;
104166 int i;
105− for (i=0; i<L->refSize; i++)
106− if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
107− L->refArray[i].status = COLLECTED;
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");
177+ }
178+ LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
108179 }
109180
110181
111182
112−void luaC_hashcallIM (Hash *l)
113−{
114− TObject t;
115− ttype(&t) = LUA_T_ARRAY;
116− for (; l; l=(Hash *)l->head.next) {
117− avalue(&t) = l;
118− luaD_gcIM(&t);
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+ }
119195 }
120196 }
121197
122198
123−void luaC_strcallIM (TaggedString *l)
124−{
125− TObject o;
126− ttype(&o) = LUA_T_USERDATA;
127− for (; l; l=(TaggedString *)l->head.next)
128− if (l->constindex == -1) { /* is userdata? */
129− tsvalue(&o) = l;
130− luaD_gcIM(&o);
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;
206+ }
207+ else {
208+ *p = next->next;
209+ luaF_freeclosure(L, next);
131210 }
211+ }
132212 }
133213
134214
135−
136−static GCnode *listcollect (GCnode *l)
137−{
138− GCnode *frees = NULL;
139− while (l) {
140− GCnode *next = l->next;
141− l->marked = 0;
142− while (next && !next->marked) {
143− l->next = next->next;
144− next->next = frees;
145− frees = next;
146− next = l->next;
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;
222+ }
223+ else {
224+ *p = next->next;
225+ luaH_free(L, next);
147226 }
148− l = next;
149227 }
150− return frees;
151228 }
152229
153230
154−static void strmark (TaggedString *s)
155−{
156− if (!s->head.marked)
157− s->head.marked = 1;
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 */
158234 }
159235
160236
161−static void protomark (TProtoFunc *f) {
162− if (!f->head.marked) {
163− int i;
164− f->head.marked = 1;
165− strmark(f->source);
166− for (i=0; i<f->nconsts; i++)
167− markobject(&f->consts[i]);
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+ }
254+ }
168255 }
256+ checktab(L, &L->strt);
169257 }
170258
171259
172−static void closuremark (Closure *f)
173−{
174− if (!f->head.marked) {
175− int i;
176− f->head.marked = 1;
177− for (i=f->nelems; i>=0; i--)
178− markobject(&f->consts[i]);
260+static void collectudata (lua_State *L, int all) {
261+ 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+ }
179280 }
281+ checktab(L, &L->udt);
180282 }
181283
182284
183−static void hashmark (Hash *h)
184−{
185− if (!h->head.marked) {
186− int i;
187− h->head.marked = 1;
188− for (i=0; i<nhash(h); i++) {
189− Node *n = node(h,i);
190− if (ttype(ref(n)) != LUA_T_NIL) {
191− markobject(&n->ref);
192− markobject(&n->val);
193− }
194− }
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);
195292 }
196293 }
197294
198295
199−static void globalmark (void)
200−{
201− TaggedString *g;
202− for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next){
203− LUA_ASSERT(g->constindex >= 0, "userdata in global list");
204− if (g->u.s.globalval.ttype != LUA_T_NIL) {
205− markobject(&g->u.s.globalval);
206− strmark(g); /* cannot collect non nil global variables */
207− }
296+static void callgcTM (lua_State *L, const TObject *o) {
297+ Closure *tm = luaT_gettmbyObj(L, o, TM_GC);
298+ 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;
305+ L->top += 2;
306+ luaD_call(L, L->top-2, 0);
307+ L->allowhooks = oldah; /* restore hooks */
208308 }
209309 }
210310
211311
212−static int markobject (TObject *o)
213−{
214− switch (ttype(o)) {
215− case LUA_T_USERDATA: case LUA_T_STRING:
216− strmark(tsvalue(o));
217− break;
218− case LUA_T_ARRAY:
219− hashmark(avalue(o));
220− break;
221− case LUA_T_CLOSURE: case LUA_T_CLMARK:
222− closuremark(o->value.cl);
223− break;
224− case LUA_T_PROTO: case LUA_T_PMARK:
225− protomark(o->value.tf);
226− break;
227− default: break; /* numbers, cprotos, etc */
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+ }
228325 }
229− return 0;
230326 }
231327
232328
233−
234−static void markall (void)
235−{
236− luaD_travstack(markobject); /* mark stack objects */
237− globalmark(); /* mark global variable values and names */
238− travlock(); /* mark locked objects */
239− luaT_travtagmethods(markobject); /* mark fallbacks */
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);
240336 }
241337
242338
243−long lua_collectgarbage (long limit)
244−{
245− unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */
246− Hash *freetable;
247− TaggedString *freestr;
248− TProtoFunc *freefunc;
249− Closure *freeclos;
250− markall();
251− invalidaterefs();
252− freestr = luaS_collector();
253− freetable = (Hash *)listcollect(&(L->roottable));
254− freefunc = (TProtoFunc *)listcollect(&(L->rootproto));
255− freeclos = (Closure *)listcollect(&(L->rootcl));
256− L->GCthreshold *= 4; /* to avoid GC during GC */
257− luaC_hashcallIM(freetable); /* GC tag methods for tables */
258− luaC_strcallIM(freestr); /* GC tag methods for userdata */
259− luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
260− luaH_free(freetable);
261− luaS_free(freestr);
262− luaF_freeproto(freefunc);
263− luaF_freeclosure(freeclos);
264− recovered = recovered-L->nblocks;
265− L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
266− return recovered;
339+static 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);
267346 }
268347
269348
270−void luaC_checkGC (void)
271−{
349+void luaC_checkGC (lua_State *L) {
272350 if (L->nblocks >= L->GCthreshold)
273− lua_collectgarbage(0);
351+ luaC_collectgarbage(L);
274352 }
275353
src/lgc.h+3−6
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lgc.h,v 1.4 1997/12/01 20:31:25 roberto Exp $
2+** $Id: lgc.h,v 1.8 2000/10/02 14:47:43 roberto Exp $
33 ** Garbage Collector
44 ** See Copyright Notice in lua.h
55 */
@@ -11,11 +11,8 @@ · 5 unmodified lines
1111 #include "lobject.h"
1212
1313
14−void luaC_checkGC (void);
15−TObject* luaC_getref (int ref);
16−int luaC_ref (TObject *o, int lock);
17−void luaC_hashcallIM (Hash *l);
18−void luaC_strcallIM (TaggedString *l);
14+void luaC_collect (lua_State *L, int all);
15+void luaC_checkGC (lua_State *L);
1916
2017
2118 #endif
src/lib/Makefile+3−3
@@ -1,4 +1,4 @@
1−# makefile for lua standard library
1+# makefile for Lua standard library
22
33 LUA= ../..
44
@@ -7,8 +7,8 @@ include $(LUA)/config · 2 unmodified lines
77 # actually only used in liolib.c
88 EXTRA_DEFS= $(POPEN)
99
10−OBJS= linit.o ldblib.o liolib.o lmathlib.o lstrlib.o
11−SRCS= linit.c ldblib.c liolib.c lmathlib.c lstrlib.c
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
1212
1313 T= $(LIB)/liblualib.a
1414
src/lib/README+4−2
@@ -1,4 +1,6 @@
11 This is the standard Lua library.
22 It is implemented entirely on top of the official Lua API as declared in lua.h,
3−using src/lauxlib.c, which contains several useful functions.
4−The code can be read as an example of how to export C functions to Lua.
3+using lauxlib.c, which contains several useful functions for writing libraries.
4+We encourage developers to use lauxlib.c in their own libraries.
5+The code of the standard library can be read as an example of how to export
6+C functions to Lua.
src/lib/lauxlib.c+216−0
@@ -0,0 +1,216 @@
1+/*
2+** $Id: lauxlib.c,v 1.43 2000/10/30 13:07:48 roberto Exp $
3+** Auxiliary functions for building Lua libraries
4+** See Copyright Notice in lua.h
5+*/
6+
7+
8+#include <stdarg.h>
9+#include <stdio.h>
10+#include <string.h>
11+
12+/* This file uses only the official API of Lua.
13+** Any function declared here could be written as an application function.
14+** With care, these functions can be used by other libraries.
15+*/
16+
17+#include "lua.h"
18+
19+#include "lauxlib.h"
20+#include "luadebug.h"
21+
22+
23+
24+LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
25+ int i;
26+ for (i=0; list[i]; i++)
27+ if (strcmp(list[i], name) == 0)
28+ return i;
29+ return -1; /* name not found */
30+}
31+
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);
40+}
41+
42+
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);
48+}
49+
50+
51+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);
54+}
55+
56+
57+LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) {
58+ if (lua_type(L, narg) != t)
59+ type_error(L, narg, t);
60+}
61+
62+
63+LUALIB_API void luaL_checkany (lua_State *L, int narg) {
64+ if (lua_type(L, narg) == LUA_TNONE)
65+ luaL_argerror(L, narg, "value expected");
66+}
67+
68+
69+LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
70+ const char *s = lua_tostring(L, narg);
71+ if (!s) type_error(L, narg, LUA_TSTRING);
72+ if (len) *len = lua_strlen(L, narg);
73+ return s;
74+}
75+
76+
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)) {
79+ if (len)
80+ *len = (def ? strlen(def) : 0);
81+ return def;
82+ }
83+ else return luaL_check_lstr(L, narg, len);
84+}
85+
86+
87+LUALIB_API double luaL_check_number (lua_State *L, int narg) {
88+ double d = lua_tonumber(L, narg);
89+ if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
90+ type_error(L, narg, LUA_TNUMBER);
91+ return d;
92+}
93+
94+
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);
98+}
99+
100+
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);
105+}
106+
107+
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);
115+}
116+
117+
118+/*
119+** {======================================================
120+** Generic Buffer manipulation
121+** =======================================================
122+*/
123+
124+
125+#define buffempty(B) ((B)->p == (B)->buffer)
126+#define bufflen(B) ((B)->p - (B)->buffer)
127+#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
128+
129+#define LIMIT (LUA_MINSTACK/2)
130+
131+
132+static int emptybuffer (luaL_Buffer *B) {
133+ size_t l = bufflen(B);
134+ if (l == 0) return 0; /* put nothing on stack */
135+ else {
136+ lua_pushlstring(B->L, B->buffer, l);
137+ B->p = B->buffer;
138+ B->level++;
139+ return 1;
140+ }
141+}
142+
143+
144+static void adjuststack (luaL_Buffer *B) {
145+ if (B->level > 1) {
146+ lua_State *L = B->L;
147+ int toget = 1; /* number of levels to concat */
148+ size_t toplen = lua_strlen(L, -1);
149+ do {
150+ size_t l = lua_strlen(L, -(toget+1));
151+ if (B->level - toget + 1 >= LIMIT || toplen > l) {
152+ toplen += l;
153+ toget++;
154+ }
155+ else break;
156+ } while (toget < B->level);
157+ if (toget >= 2) {
158+ lua_concat(L, toget);
159+ B->level = B->level - toget + 1;
160+ }
161+ }
162+}
163+
164+
165+LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
166+ if (emptybuffer(B))
167+ adjuststack(B);
168+ return B->buffer;
169+}
170+
171+
172+LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
173+ while (l--)
174+ luaL_putchar(B, *s++);
175+}
176+
177+
178+LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
179+ luaL_addlstring(B, s, strlen(s));
180+}
181+
182+
183+LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
184+ 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;
190+}
191+
192+
193+LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
194+ lua_State *L = B->L;
195+ size_t vl = lua_strlen(L, -1);
196+ if (vl <= bufffree(B)) { /* fit into buffer? */
197+ memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */
198+ B->p += vl;
199+ lua_pop(L, 1); /* remove from stack */
200+ }
201+ else {
202+ if (emptybuffer(B))
203+ lua_insert(L, -2); /* put buffer before new value */
204+ B->level++; /* add new value into B stack */
205+ adjuststack(B);
206+ }
207+}
208+
209+
210+LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
211+ B->L = L;
212+ B->p = B->buffer;
213+ B->level = 0;
214+}
215+
216+/* }====================================================== */
src/lib/lbaselib.c+651−0
@@ -0,0 +1,651 @@
1+/*
2+** $Id: lbaselib.c,v 1.17 2000/11/06 13:45:18 roberto Exp $
3+** Basic library
4+** See Copyright Notice in lua.h
5+*/
6+
7+
8+
9+#include <ctype.h>
10+#include <stdio.h>
11+#include <stdlib.h>
12+#include <string.h>
13+
14+#include "lua.h"
15+
16+#include "lauxlib.h"
17+#include "luadebug.h"
18+#include "lualib.h"
19+
20+
21+
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+
59+
60+/*
61+** If your system does not support `stdout', you can just remove this function.
62+** If you need, you can define your own `print' function, following this
63+** model but changing `fputs' to put the strings at a proper place
64+** (a console window or a log file, for instance).
65+*/
66+static int luaB_print (lua_State *L) {
67+ int n = lua_gettop(L); /* number of arguments */
68+ int i;
69+ lua_getglobal(L, "tostring");
70+ for (i=1; i<=n; i++) {
71+ const char *s;
72+ lua_pushvalue(L, -1); /* function to be called */
73+ lua_pushvalue(L, i); /* value to print */
74+ lua_rawcall(L, 1, 1);
75+ s = lua_tostring(L, -1); /* get result */
76+ if (s == NULL)
77+ lua_error(L, "`tostring' must return a string to `print'");
78+ if (i>1) fputs("\t", stdout);
79+ fputs(s, stdout);
80+ lua_pop(L, 1); /* pop result */
81+ }
82+ fputs("\n", stdout);
83+ return 0;
84+}
85+
86+
87+static int luaB_tonumber (lua_State *L) {
88+ int base = luaL_opt_int(L, 2, 10);
89+ if (base == 10) { /* standard conversion */
90+ luaL_checkany(L, 1);
91+ if (lua_isnumber(L, 1)) {
92+ lua_pushnumber(L, lua_tonumber(L, 1));
93+ return 1;
94+ }
95+ }
96+ else {
97+ const char *s1 = luaL_check_string(L, 1);
98+ char *s2;
99+ unsigned long n;
100+ luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range");
101+ n = strtoul(s1, &s2, base);
102+ if (s1 != s2) { /* at least one valid digit? */
103+ while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */
104+ if (*s2 == '\0') { /* no invalid trailing characters? */
105+ lua_pushnumber(L, n);
106+ return 1;
107+ }
108+ }
109+ }
110+ lua_pushnil(L); /* else not a number */
111+ return 1;
112+}
113+
114+
115+static int luaB_error (lua_State *L) {
116+ lua_error(L, luaL_opt_string(L, 1, NULL));
117+ return 0; /* to avoid warnings */
118+}
119+
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;
124+}
125+
126+static int luaB_getglobal (lua_State *L) {
127+ lua_getglobal(L, luaL_check_string(L, 1));
128+ return 1;
129+}
130+
131+static int luaB_tag (lua_State *L) {
132+ luaL_checkany(L, 1);
133+ lua_pushnumber(L, lua_tag(L, 1));
134+ return 1;
135+}
136+
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 */
142+}
143+
144+static int luaB_newtag (lua_State *L) {
145+ lua_pushnumber(L, lua_newtag(L));
146+ return 1;
147+}
148+
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;
153+}
154+
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+ }
162+ return 1;
163+}
164+
165+static int luaB_rawget (lua_State *L) {
166+ luaL_checktype(L, 1, LUA_TTABLE);
167+ luaL_checkany(L, 2);
168+ lua_rawget(L, -2);
169+ return 1;
170+}
171+
172+static int luaB_rawset (lua_State *L) {
173+ luaL_checktype(L, 1, LUA_TTABLE);
174+ luaL_checkany(L, 2);
175+ luaL_checkany(L, 3);
176+ lua_rawset(L, -3);
177+ return 1;
178+}
179+
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+
203+
204+static int luaB_gcinfo (lua_State *L) {
205+ lua_pushnumber(L, lua_getgccount(L));
206+ lua_pushnumber(L, lua_getgcthreshold(L));
207+ return 2;
208+}
209+
210+
211+static int luaB_collectgarbage (lua_State *L) {
212+ lua_setgcthreshold(L, luaL_opt_int(L, 1, 0));
213+ return 0;
214+}
215+
216+
217+static int luaB_type (lua_State *L) {
218+ luaL_checkany(L, 1);
219+ lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
220+ return 1;
221+}
222+
223+
224+static int luaB_next (lua_State *L) {
225+ luaL_checktype(L, 1, LUA_TTABLE);
226+ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
227+ if (lua_next(L, 1))
228+ return 2;
229+ else {
230+ lua_pushnil(L);
231+ return 1;
232+ }
233+}
234+
235+
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+ }
248+ }
249+ else { /* error */
250+ lua_pushnil(L);
251+ lua_pushstring(L, errornames[status]); /* error code */
252+ return 2;
253+ }
254+}
255+
256+static int luaB_dostring (lua_State *L) {
257+ int oldtop = lua_gettop(L);
258+ size_t l;
259+ const char *s = luaL_check_lstr(L, 1, &l);
260+ if (*s == '\27') /* 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+}
264+
265+
266+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);
270+}
271+
272+
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 */
308+}
309+
310+
311+static int luaB_tostring (lua_State *L) {
312+ char buff[64];
313+ switch (lua_type(L, 1)) {
314+ case LUA_TNUMBER:
315+ lua_pushstring(L, lua_tostring(L, 1));
316+ return 1;
317+ case LUA_TSTRING:
318+ lua_pushvalue(L, 1);
319+ return 1;
320+ case LUA_TTABLE:
321+ sprintf(buff, "table: %p", lua_topointer(L, 1));
322+ break;
323+ case LUA_TFUNCTION:
324+ sprintf(buff, "function: %p", lua_topointer(L, 1));
325+ break;
326+ case LUA_TUSERDATA:
327+ sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1));
328+ break;
329+ case LUA_TNIL:
330+ lua_pushstring(L, "nil");
331+ return 1;
332+ default:
333+ luaL_argerror(L, 1, "value expected");
334+ }
335+ lua_pushstring(L, buff);
336+ return 1;
337+}
338+
339+
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 */
353+ }
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 */
372+ }
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));
387+ return 1;
388+}
389+
390+
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+
412+
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+}
431+
432+
433+
434+
435+/*
436+** {======================================================
437+** Quicksort
438+** (based on `Algorithms in MODULA-3', Robert Sedgewick;
439+** Addison-Wesley, 1993.)
440+*/
441+
442+
443+static void set2 (lua_State *L, int i, int j) {
444+ lua_rawseti(L, 1, i);
445+ lua_rawseti(L, 1, j);
446+}
447+
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;
459+ }
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);
487+ }
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;
509+ }
510+ set2(L, i, j);
511+ }
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;
519+ }
520+ else {
521+ j=i+1; i=u; u=j-2;
522+ }
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;
536+}
537+
538+/* }====================================================== */
539+
540+
541+
542+/*
543+** {======================================================
544+** Deprecated functions to manipulate global environment.
545+** =======================================================
546+*/
547+
548+
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+};
557+
558+
559+#ifdef LUA_DEPRECATEDFUNCS
560+
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 */
570+}
571+
572+
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+ }
580+}
581+
582+
583+#else
584+
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 */
591+}
592+
593+
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);
600+ }
601+}
602+
603+#endif
604+
605+/* }====================================================== */
606+
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}
641+};
642+
643+
644+
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);
650+}
651+
src/lib/ldblib.c+124−153
@@ -1,217 +1,188 @@
11 /*
2−** $Id: ldblib.c,v 1.5 1999/03/04 21:17:26 roberto Exp $
2+** $Id: ldblib.c,v 1.29 2000/11/06 17:58:38 roberto Exp $
33 ** Interface from Lua to its debug API
44 ** See Copyright Notice in lua.h
55 */
66
77
8+#include <stdio.h>
89 #include <stdlib.h>
910 #include <string.h>
1011
11−#include "lauxlib.h"
1212 #include "lua.h"
13+
14+#include "lauxlib.h"
1315 #include "luadebug.h"
1416 #include "lualib.h"
1517
1618
1719
18−static void settabss (lua_Object t, char *i, char *v) {
19− lua_pushobject(t);
20− lua_pushstring(i);
21− lua_pushstring(v);
22− lua_settable();
20+static void settabss (lua_State *L, const char *i, const char *v) {
21+ lua_pushstring(L, i);
22+ lua_pushstring(L, v);
23+ lua_settable(L, -3);
2324 }
2425
2526
26−static void settabsi (lua_Object t, char *i, int v) {
27− lua_pushobject(t);
28− lua_pushstring(i);
29− lua_pushnumber(v);
30− lua_settable();
27+static void settabsi (lua_State *L, const char *i, int v) {
28+ lua_pushstring(L, i);
29+ lua_pushnumber(L, v);
30+ lua_settable(L, -3);
3131 }
3232
3333
34−static lua_Object getfuncinfo (lua_Object func) {
35− lua_Object result = lua_createtable();
36− char *str;
37− int line;
38− lua_funcinfo(func, &str, &line);
39− if (line == -1) /* C function? */
40− settabss(result, "kind", "C");
41− else if (line == 0) { /* "main"? */
42− settabss(result, "kind", "chunk");
43− settabss(result, "source", str);
34+static int getinfo (lua_State *L) {
35+ lua_Debug ar;
36+ const char *options = luaL_opt_string(L, 2, "flnSu");
37+ char buff[20];
38+ if (lua_isnumber(L, 1)) {
39+ if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
40+ lua_pushnil(L); /* level out of range */
41+ return 1;
4442 }
45− else { /* Lua function */
46− settabss(result, "kind", "Lua");
47− settabsi(result, "def_line", line);
48− settabss(result, "source", str);
4943 }
50− if (line != 0) { /* is it not a "main"? */
51− char *kind = lua_getobjname(func, &str);
52− if (*kind) {
53− settabss(result, "name", str);
54− settabss(result, "where", kind);
44+ else if (lua_isfunction(L, 1)) {
45+ lua_pushvalue(L, 1);
46+ sprintf(buff, ">%.10s", options);
47+ options = buff;
48+ }
49+ else
50+ luaL_argerror(L, 1, "function or level expected");
51+ if (!lua_getinfo(L, options, &ar))
52+ luaL_argerror(L, 2, "invalid option");
53+ lua_newtable(L);
54+ for (; *options; options++) {
55+ switch (*options) {
56+ case 'S':
57+ settabss(L, "source", ar.source);
58+ if (ar.source)
59+ settabss(L, "short_src", ar.short_src);
60+ settabsi(L, "linedefined", ar.linedefined);
61+ settabss(L, "what", ar.what);
62+ break;
63+ case 'l':
64+ settabsi(L, "currentline", ar.currentline);
65+ break;
66+ case 'u':
67+ settabsi(L, "nups", ar.nups);
68+ break;
69+ case 'n':
70+ settabss(L, "name", ar.name);
71+ settabss(L, "namewhat", ar.namewhat);
72+ break;
73+ case 'f':
74+ lua_pushstring(L, "func");
75+ lua_pushvalue(L, -3);
76+ lua_settable(L, -3);
77+ break;
5578 }
5679 }
57− return result;
80+ return 1; /* return table */
5881 }
59−
60−
61−static void getstack (void) {
62− lua_Object func = lua_stackedfunction(luaL_check_int(1));
63− if (func == LUA_NOOBJECT) /* level out of range? */
64− return;
65− else {
66− lua_Object result = getfuncinfo(func);
67− int currline = lua_currentline(func);
68− if (currline > 0)
69− settabsi(result, "current", currline);
70− lua_pushobject(result);
71− lua_pushstring("func");
72− lua_pushobject(func);
73− lua_settable(); /* result.func = func */
74− lua_pushobject(result);
82+
83+
84+static int getlocal (lua_State *L) {
85+ lua_Debug ar;
86+ 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));
90+ if (name) {
91+ lua_pushstring(L, name);
92+ lua_pushvalue(L, -2);
93+ return 2;
7594 }
76−}
77−
78−
79−static void funcinfo (void) {
80− lua_pushobject(getfuncinfo(luaL_functionarg(1)));
81−}
82−
83−
84−static int findlocal (lua_Object func, int arg) {
85− lua_Object v = lua_getparam(arg);
86− if (lua_isnumber(v))
87− return (int)lua_getnumber(v);
8895 else {
89− char *name = luaL_check_string(arg);
90− int i = 0;
91− int result = -1;
92− char *vname;
93− while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) {
94− if (strcmp(name, vname) == 0)
95− result = i; /* keep looping to get the last var with this name */
96− }
97− if (result == -1)
98− luaL_verror("no local variable `%.50s' at given level", name);
99− return result;
96+ lua_pushnil(L);
97+ return 1;
10098 }
10199 }
102100
103101
104−static void getlocal (void) {
105− lua_Object func = lua_stackedfunction(luaL_check_int(1));
106− lua_Object val;
107− char *name;
108− if (func == LUA_NOOBJECT) /* level out of range? */
109− return; /* return nil */
110− else if (lua_getparam(2) != LUA_NOOBJECT) { /* 2nd argument? */
111− if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) {
112− lua_pushobject(val);
113− lua_pushstring(name);
114− }
115− /* else return nil */
116− }
117− else { /* collect all locals in a table */
118− lua_Object result = lua_createtable();
119− int i;
120− for (i=1; ;i++) {
121− if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT)
122− break;
123− lua_pushobject(result);
124− lua_pushstring(name);
125− lua_pushobject(val);
126− lua_settable(); /* result[name] = value */
127− }
128− lua_pushobject(result);
129− }
102+static int setlocal (lua_State *L) {
103+ 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");
106+ luaL_checkany(L, 3);
107+ lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
108+ return 1;
130109 }
131110
132111
133−static void setlocal (void) {
134− lua_Object func = lua_stackedfunction(luaL_check_int(1));
135− int numvar;
136− luaL_arg_check(func != LUA_NOOBJECT, 1, "level out of range");
137− numvar = findlocal(func, 2);
138− lua_pushobject(luaL_nonnullarg(3));
139− if (!lua_setlocal(func, numvar))
140− lua_error("no such local variable");
141−}
142112
113+/* dummy variables (to define unique addresses) */
114+static char key1, key2;
115+#define KEY_CALLHOOK (&key1)
116+#define KEY_LINEHOOK (&key2)
143117
144118
145−static int linehook = -1; /* Lua reference to line hook function */
146−static int callhook = -1; /* Lua reference to call hook function */
119+static void hookf (lua_State *L, void *key) {
120+ lua_getregistry(L);
121+ lua_pushuserdata(L, key);
122+ lua_gettable(L, -2);
123+ if (lua_isfunction(L, -1)) {
124+ lua_pushvalue(L, 1);
125+ lua_rawcall(L, 1, 0);
126+ }
127+ else
128+ lua_pop(L, 1); /* pop result from gettable */
129+ lua_pop(L, 1); /* pop table */
130+}
147131
148132
149−static void dohook (int ref) {
150− lua_LHFunction oldlinehook = lua_setlinehook(NULL);
151− lua_CHFunction oldcallhook = lua_setcallhook(NULL);
152− lua_callfunction(lua_getref(ref));
153− lua_setlinehook(oldlinehook);
154− lua_setcallhook(oldcallhook);
133+static void callf (lua_State *L, lua_Debug *ar) {
134+ lua_pushstring(L, ar->event);
135+ hookf(L, KEY_CALLHOOK);
155136 }
156137
157138
158−static void linef (int line) {
159− lua_pushnumber(line);
160− dohook(linehook);
139+static void linef (lua_State *L, lua_Debug *ar) {
140+ lua_pushnumber(L, ar->currentline);
141+ hookf(L, KEY_LINEHOOK);
161142 }
162143
163144
164−static void callf (lua_Function func, char *file, int line) {
165− if (func != LUA_NOOBJECT) {
166− lua_pushobject(func);
167− lua_pushstring(file);
168− lua_pushnumber(line);
169− }
170− dohook(callhook);
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) */
159+ lua_pushvalue(L, 1);
160+ lua_settable(L, -5); /* set new value */
171161 }
172162
173163
174−static void setcallhook (void) {
175− lua_Object f = lua_getparam(1);
176− lua_unref(callhook);
177− if (f == LUA_NOOBJECT) {
178− callhook = -1;
179− lua_setcallhook(NULL);
180− }
181− else {
182− lua_pushobject(f);
183− callhook = lua_ref(1);
184− lua_setcallhook(callf);
185− }
164+static int setcallhook (lua_State *L) {
165+ sethook(L, KEY_CALLHOOK, callf, lua_setcallhook);
166+ return 1;
186167 }
187168
188169
189−static void setlinehook (void) {
190− lua_Object f = lua_getparam(1);
191− lua_unref(linehook);
192− if (f == LUA_NOOBJECT) {
193− linehook = -1;
194− lua_setlinehook(NULL);
195− }
196− else {
197− lua_pushobject(f);
198− linehook = lua_ref(1);
199− lua_setlinehook(linef);
200− }
170+static int setlinehook (lua_State *L) {
171+ sethook(L, KEY_LINEHOOK, linef, lua_setlinehook);
172+ return 1;
201173 }
202174
203175
204−static struct luaL_reg dblib[] = {
205− {"funcinfo", funcinfo},
176+static const struct luaL_reg dblib[] = {
206177 {"getlocal", getlocal},
207− {"getstack", getstack},
178+ {"getinfo", getinfo},
208179 {"setcallhook", setcallhook},
209180 {"setlinehook", setlinehook},
210181 {"setlocal", setlocal}
211182 };
212183
213184
214−void lua_dblibopen (void) {
215− luaL_openlib(dblib, (sizeof(dblib)/sizeof(dblib[0])));
185+LUALIB_API void lua_dblibopen (lua_State *L) {
186+ luaL_openl(L, dblib);
216187 }
217188
src/lib/linit.c+0−17
@@ -1,17 +0,0 @@
1−/*
2−** $Id: linit.c,v 1.1 1999/01/08 16:49:32 roberto Exp $
3−** Initialization of libraries for lua.c
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include "lua.h"
8−#include "lualib.h"
9−
10−
11−void lua_userinit (void) {
12− lua_iolibopen();
13− lua_strlibopen();
14− lua_mathlibopen();
15− lua_dblibopen();
16−}
17−
src/lib/liolib.c+432−297
@@ -1,67 +1,78 @@
11 /*
2−** $Id: liolib.c,v 1.41 1999/06/23 13:48:39 roberto Exp $
2+** $Id: liolib.c,v 1.91 2000/10/31 13:10:24 roberto Exp $
33 ** Standard I/O (and system) library
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <errno.h>
8+#include <ctype.h>
99 #include <stdio.h>
1010 #include <stdlib.h>
1111 #include <string.h>
1212 #include <time.h>
1313
14−#include "lauxlib.h"
1514 #include "lua.h"
15+
16+#include "lauxlib.h"
1617 #include "luadebug.h"
1718 #include "lualib.h"
1819
1920
2021 #ifndef OLD_ANSI
22+#include <errno.h>
2123 #include <locale.h>
24+#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
25+#define free(b) if (b) (free)(b)
2226 #else
2327 /* no support for locale and for strerror: fake them */
24−#define setlocale(a,b) 0
28+#define setlocale(a,b) ((void)a, strcmp((b),"C")==0?"C":NULL)
2529 #define LC_ALL 0
2630 #define LC_COLLATE 0
2731 #define LC_CTYPE 0
2832 #define LC_MONETARY 0
2933 #define LC_NUMERIC 0
3034 #define LC_TIME 0
31−#define strerror(e) "(no error message provided by operating system)"
35+#define strerror(e) "generic I/O error"
36+#define errno (-1)
3237 #endif
3338
3439
35−#define IOTAG 1
36−
37−#define FIRSTARG 2 /* 1st is upvalue */
38−
39−#define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */
40−
41−
42−#define FINPUT "_INPUT"
43−#define FOUTPUT "_OUTPUT"
44−
4540
4641 #ifdef POPEN
47−FILE *popen();
48−int pclose();
49−#define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);}
42+/* FILE *popen();
43+int pclose(); */
44+#define CLOSEFILE(L, f) ((pclose(f) == -1) ? fclose(f) : 0)
5045 #else
5146 /* no support for popen */
5247 #define popen(x,y) NULL /* that is, popen always fails */
53−#define CLOSEFILE(f) {fclose(f);}
48+#define CLOSEFILE(L, f) (fclose(f))
5449 #endif
5550
5651
52+#define INFILE 0
53+#define OUTFILE 1
54+
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;
60+
61+
62+
63+static const char *const filenames[] = {"_INPUT", "_OUTPUT"};
5764
58−static void pushresult (int i) {
59− if (i)
60− lua_pushuserdata(NULL);
65+
66+static int pushresult (lua_State *L, int i) {
67+ if (i) {
68+ lua_pushuserdata(L, NULL);
69+ return 1;
70+ }
6171 else {
62− lua_pushnil();
63− lua_pushstring(strerror(errno));
64− lua_pushnumber(errno);
72+ lua_pushnil(L);
73+ lua_pushstring(L, strerror(errno));
74+ lua_pushnumber(L, errno);
75+ return 3;;
6576 }
6677 }
6778
@@ -72,138 +83,138 @@ static void pushresult (int i) { · 4 unmodified lines
7283 ** =======================================================
7384 */
7485
75−static int gettag (void) {
76− return (int)lua_getnumber(lua_getparam(IOTAG));
77−}
7886
79−
80−static int ishandle (lua_Object f) {
81− if (lua_isuserdata(f)) {
82− int tag = gettag();
83− if (lua_tag(f) == CLOSEDTAG(tag))
84− lua_error("cannot access a closed file");
85− return lua_tag(f) == tag;
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 */
8696 }
87− else return 0;
97+ return NULL;
8898 }
8999
90100
91−static FILE *getfilebyname (char *name) {
92− lua_Object f = lua_getglobal(name);
93− if (!ishandle(f))
94− luaL_verror("global variable `%.50s' is not a file handle", name);
95− return lua_getuserdata(f);
96−}
97−
98−
99−static FILE *getfile (int arg) {
100− lua_Object f = lua_getparam(arg);
101− return (ishandle(f)) ? lua_getuserdata(f) : NULL;
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");
104+ return f;
102105 }
103106
104107
105−static FILE *getnonullfile (int arg) {
106− FILE *f = getfile(arg);
107− luaL_arg_check(f, arg, "invalid file handle");
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]);
108117 return f;
109118 }
110119
111120
112−static FILE *getfileparam (char *name, int *arg) {
113− FILE *f = getfile(*arg);
114− if (f) {
115− (*arg)++;
116− return f;
117− }
118− else
119− return getfilebyname(name);
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);
120125 }
121126
122127
123−static void closefile (FILE *f) {
124− if (f != stdin && f != stdout) {
125− int tag = gettag();
126− CLOSEFILE(f);
127− lua_pushusertag(f, tag);
128− lua_settag(CLOSEDTAG(tag));
129− }
130−}
128+#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout]))
131129
132130
133−static void io_close (void) {
134− closefile(getnonullfile(FIRSTARG));
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;
138+ }
135139 }
136140
137141
138−static void gc_close (void) {
139− FILE *f = getnonullfile(FIRSTARG);
140− if (f != stdin && f != stdout && f != stderr) {
141− CLOSEFILE(f);
142+static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
143+ if (f == stdin || f == stdout || f == stderr)
144+ return 1;
145+ else {
146+ lua_pushusertag(L, f, ctrl->iotag);
147+ lua_settag(L, ctrl->closedtag);
148+ return (CLOSEFILE(L, f) == 0);
142149 }
143150 }
144151
145152
146−static void io_open (void) {
147− FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1));
148− if (f) lua_pushusertag(f, gettag());
149− else pushresult(0);
153+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)));
150157 }
151158
152159
153−static void setfile (FILE *f, char *name, int tag) {
154− lua_pushusertag(f, tag);
155− lua_setglobal(name);
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);
165+ return 0;
156166 }
157167
158168
159−static void setreturn (FILE *f, char *name) {
160− if (f == NULL)
161− pushresult(0);
162− else {
163− int tag = gettag();
164− setfile(f, name, tag);
165− lua_pushusertag(f, tag);
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;
166177 }
178+ else
179+ return pushresult(L, 0);
167180 }
168181
169182
170−static void io_readfrom (void) {
183+
184+static int io_fromto (lua_State *L, int inout, const char *mode) {
185+ IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
171186 FILE *current;
172− lua_Object f = lua_getparam(FIRSTARG);
173− if (f == LUA_NOOBJECT) {
174− closefile(getfilebyname(FINPUT));
175− current = stdin;
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;
176191 }
177− else if (lua_tag(f) == gettag()) /* deprecated option */
178− current = lua_getuserdata(f);
192+ else if (lua_tag(L, 1) == ctrl->iotag) /* deprecated option */
193+ current = (FILE *)lua_touserdata(L, 1);
179194 else {
180− char *s = luaL_check_string(FIRSTARG);
181− current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
195+ const char *s = luaL_check_string(L, 1);
196+ current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
182197 }
183− setreturn(current, FINPUT);
198+ return setreturn(L, ctrl, current, inout);
184199 }
185200
186201
187−static void io_writeto (void) {
188− FILE *current;
189− lua_Object f = lua_getparam(FIRSTARG);
190− if (f == LUA_NOOBJECT) {
191− closefile(getfilebyname(FOUTPUT));
192− current = stdout;
193− }
194− else if (lua_tag(f) == gettag()) /* deprecated option */
195− current = lua_getuserdata(f);
196− else {
197− char *s = luaL_check_string(FIRSTARG);
198− current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w");
199− }
200− setreturn(current, FOUTPUT);
202+static int io_readfrom (lua_State *L) {
203+ return io_fromto(L, INFILE, "r");
201204 }
202205
203206
204−static void io_appendto (void) {
205− FILE *current = fopen(luaL_check_string(FIRSTARG), "a");
206− setreturn(current, FOUTPUT);
207+static int io_writeto (lua_State *L) {
208+ return io_fromto(L, OUTFILE, "w");
209+}
210+
211+
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);
207218 }
208219
209220
@@ -215,6 +226,9 @@ static void io_appendto (void) { · 5 unmodified lines
215226 */
216227
217228
229+
230+#ifdef LUA_COMPAT_READPATTERN
231+
218232 /*
219233 ** We cannot lookahead without need, because this can lock stdin.
220234 ** This flag signals when we need to read a next char.
@@ -222,9 +236,11 @@ static void io_appendto (void) { · 1 unmodified line
222236 #define NEED_OTHER (EOF-1) /* just some flag different from EOF */
223237
224238
225−static int read_pattern (FILE *f, char *p) {
239+static int read_pattern (lua_State *L, FILE *f, const char *p) {
226240 int inskip = 0; /* {skip} level */
227241 int c = NEED_OTHER;
242+ luaL_Buffer b;
243+ luaL_buffinit(L, &b);
228244 while (*p != '\0') {
229245 switch (*p) {
230246 case '{':
@@ -232,17 +248,17 @@ static int read_pattern (FILE *f, char *p) { · 1 unmodified line
232248 p++;
233249 continue;
234250 case '}':
235− if (!inskip) lua_error("unbalanced braces in read pattern");
251+ if (!inskip) lua_error(L, "unbalanced braces in read pattern");
236252 inskip--;
237253 p++;
238254 continue;
239255 default: {
240− char *ep = luaI_classend(p); /* get what is next */
256+ const char *ep = luaI_classend(L, p); /* get what is next */
241257 int m; /* match result */
242258 if (c == NEED_OTHER) c = getc(f);
243259 m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
244260 if (m) {
245− if (!inskip) luaL_addchar(c);
261+ if (!inskip) luaL_putchar(&b, c);
246262 c = NEED_OTHER;
247263 }
248264 switch (*ep) {
@@ -253,7 +269,7 @@ static int read_pattern (FILE *f, char *p) { · 4 unmodified lines
253269 while (m) { /* reads the same item until it fails */
254270 c = getc(f);
255271 m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
256− if (m && !inskip) luaL_addchar(c);
272+ if (m && !inskip) luaL_putchar(&b, c);
257273 }
258274 /* go through to continue reading the pattern */
259275 case '?': /* optional */
@@ -267,116 +283,210 @@ static int read_pattern (FILE *f, char *p) { · 7 unmodified lines
267283 }
268284 } break_while:
269285 if (c != NEED_OTHER) ungetc(c, f);
286+ luaL_pushresult(&b); /* close buffer */
270287 return (*p == '\0');
271288 }
272289
290+#else
291+
292+#define read_pattern(L, f, p) (lua_error(L, "read patterns are deprecated"), 0)
273293
274−static int read_number (FILE *f) {
294+#endif
295+
296+
297+static int read_number (lua_State *L, FILE *f) {
275298 double d;
276299 if (fscanf(f, "%lf", &d) == 1) {
277− lua_pushnumber(d);
300+ lua_pushnumber(L, d);
278301 return 1;
279302 }
280303 else return 0; /* read fails */
281304 }
282305
283306
284−#define HUNK_LINE 1024
285−#define HUNK_FILE BUFSIZ
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+ }
316+ ungetc(c, f);
317+ luaL_pushresult(&b); /* close buffer */
318+ return (lua_strlen(L, -1) > 0);
319+}
286320
287−static int read_line (FILE *f) {
288− /* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */
289− int n;
290− char *b;
291− do {
292− b = luaL_openspace(HUNK_LINE);
293− if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */
294− n = strlen(b);
295− luaL_addsize(n);
296− } while (b[n-1] != '\n');
297− luaL_addsize(-1); /* remove '\n' */
298− return 1;
321+
322+static int read_line (lua_State *L, FILE *f) {
323+ int n = 0;
324+ luaL_Buffer b;
325+ luaL_buffinit(L, &b);
326+ for (;;) {
327+ 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;
336+ }
337+ }
338+ luaL_pushresult(&b); /* close buffer */
339+ return (n > 0); /* read something? */
299340 }
300341
301342
302−static void read_file (FILE *f) {
303− /* equivalent to: return read_pattern(f, ".*"); */
304− int n;
305− do {
306− char *b = luaL_openspace(HUNK_FILE);
307− n = fread(b, sizeof(char), HUNK_FILE, f);
308− luaL_addsize(n);
309− } while (n==HUNK_FILE);
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");
352+ }
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;
357+ }
358+ lua_pushlstring(L, buffer, len);
359+ free(buffer);
310360 }
311361
312362
313−static void io_read (void) {
314− static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL};
315− int arg = FIRSTARG;
316− FILE *f = getfileparam(FINPUT, &arg);
317− char *p = luaL_opt_string(arg++, "*l");
318− do { /* repeat for each part */
319− long l;
363+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);
378+}
379+
380+
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);
386+ 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 */
394+ }
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++) {
320398 int success;
321− luaL_resetbuffer();
322− switch (luaL_findstring(p, options)) {
323− case 0: /* number */
324− if (!read_number(f)) return; /* read fails */
325− continue; /* number is already pushed; avoid the "pushstring" */
326− case 1: /* line */
327− success = read_line(f);
328− break;
329− case 2: case 3: /* file */
330− read_file(f);
331− success = 1; /* always success */
332− break;
333− case 4: /* word */
334− success = read_pattern(f, "{%s*}%S+");
335− break;
336− default:
337− success = read_pattern(f, p);
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! */
405+ else {
406+ switch (p[1]) {
407+ case 'n': /* number */
408+ if (!read_number(L, f)) goto endloop; /* read fails */
409+ continue; /* number is already pushed; avoid the "pushstring" */
410+ case 'l': /* line */
411+ success = read_line(L, f);
412+ break;
413+ case 'a': /* file */
414+ read_file(L, f);
415+ success = 1; /* always success */
416+ break;
417+ case 'w': /* word */
418+ success = read_word(L, f);
419+ break;
420+ default:
421+ luaL_argerror(L, n, "invalid format");
422+ success = 0; /* to avoid warnings */
423+ }
424+ }
338425 }
339− l = luaL_getsize();
340− if (!success && l==0) return; /* read fails */
341− lua_pushlstring(luaL_buffer(), l);
342− } while ((p = luaL_opt_string(arg++, NULL)) != NULL);
426+ if (!success) {
427+ lua_pop(L, 1); /* remove last result */
428+ break; /* read fails */
429+ }
430+ } endloop:
431+ return n - firstarg;
343432 }
344433
345434 /* }====================================================== */
346435
347436
348−static void io_write (void) {
349− int arg = FIRSTARG;
350− FILE *f = getfileparam(FOUTPUT, &arg);
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;
351441 int status = 1;
352− char *s;
353− long l;
354− while ((s = luaL_opt_lstr(arg++, NULL, &l)) != NULL)
355− status = status && ((long)fwrite(s, 1, l, f) == l);
356− pushresult(status);
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 */
447+ /* optimization: could be done exactly as for strings */
448+ status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0;
449+ }
450+ else {
451+ size_t l;
452+ const char *s = luaL_check_lstr(L, arg, &l);
453+ status = status && (fwrite(s, sizeof(char), l, f) == l);
454+ }
455+ }
456+ pushresult(L, status);
457+ return 1;
357458 }
358459
359460
360−static void io_seek (void) {
361− static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
362− static char *modenames[] = {"set", "cur", "end", NULL};
363− FILE *f = getnonullfile(FIRSTARG);
364− int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames);
365− long offset = luaL_opt_long(FIRSTARG+2, 0);
366− luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode");
461+static int io_seek (lua_State *L) {
462+ static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
463+ 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");
367473 op = fseek(f, offset, mode[op]);
368474 if (op)
369− pushresult(0); /* error */
370− else
371− lua_pushnumber(ftell(f));
475+ return pushresult(L, 0); /* error */
476+ else {
477+ lua_pushnumber(L, ftell(f));
478+ return 1;
479+ }
372480 }
373481
374482
375−static void io_flush (void) {
376− FILE *f = getfile(FIRSTARG);
377− luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG,
378− "invalid file handle");
379− pushresult(fflush(f) == 0);
483+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);
380490 }
381491
382492 /* }====================================================== */
@@ -388,145 +498,165 @@ static void io_flush (void) { · 5 unmodified lines
388498 ** =======================================================
389499 */
390500
391−static void io_execute (void) {
392− lua_pushnumber(system(luaL_check_string(1)));
501+static int io_execute (lua_State *L) {
502+ lua_pushnumber(L, system(luaL_check_string(L, 1)));
503+ return 1;
393504 }
394505
395506
396−static void io_remove (void) {
397− pushresult(remove(luaL_check_string(1)) == 0);
507+static int io_remove (lua_State *L) {
508+ return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
398509 }
399510
400511
401−static void io_rename (void) {
402− pushresult(rename(luaL_check_string(1),
403− luaL_check_string(2)) == 0);
512+static int io_rename (lua_State *L) {
513+ return pushresult(L, rename(luaL_check_string(L, 1),
514+ luaL_check_string(L, 2)) == 0);
404515 }
405516
406517
407−static void io_tmpname (void) {
408− lua_pushstring(tmpnam(NULL));
518+static int io_tmpname (lua_State *L) {
519+ lua_pushstring(L, tmpnam(NULL));
520+ return 1;
409521 }
410522
411523
412524
413−static void io_getenv (void) {
414− lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
525+static int io_getenv (lua_State *L) {
526+ lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */
527+ return 1;
415528 }
416529
417530
418−static void io_clock (void) {
419− lua_pushnumber(((double)clock())/CLOCKS_PER_SEC);
531+static int io_clock (lua_State *L) {
532+ lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC);
533+ return 1;
420534 }
421535
422536
423−static void io_date (void) {
537+static int io_date (lua_State *L) {
424538 char b[256];
425− char *s = luaL_opt_string(1, "%c");
426− struct tm *tm;
539+ const char *s = luaL_opt_string(L, 1, "%c");
540+ struct tm *stm;
427541 time_t t;
428− time(&t); tm = localtime(&t);
429− if (strftime(b,sizeof(b),s,tm))
430− lua_pushstring(b);
542+ time(&t); stm = localtime(&t);
543+ if (strftime(b, sizeof(b), s, stm))
544+ lua_pushstring(L, b);
431545 else
432− lua_error("invalid `date' format");
546+ lua_error(L, "invalid `date' format");
547+ return 1;
433548 }
434549
435550
436−static void setloc (void) {
437− static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC,
438− LC_TIME};
439− static char *catnames[] = {"all", "collate", "ctype", "monetary",
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",
440555 "numeric", "time", NULL};
441− int op = luaL_findstring(luaL_opt_string(2, "all"), catnames);
442− luaL_arg_check(op != -1, 2, "invalid option");
443− lua_pushstring(setlocale(cat[op], luaL_check_string(1)));
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)));
559+ return 1;
444560 }
445561
446562
447−static void io_exit (void) {
448− lua_Object o = lua_getparam(1);
449− exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1);
563+static int io_exit (lua_State *L) {
564+ exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
565+ return 0; /* to avoid warnings */
450566 }
451567
452568 /* }====================================================== */
453569
454570
455571
456−static void io_debug (void) {
572+static int io_debug (lua_State *L) {
457573 for (;;) {
458574 char buffer[250];
459575 fprintf(stderr, "lua_debug> ");
460576 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
461577 strcmp(buffer, "cont\n") == 0)
462− return;
463− lua_dostring(buffer);
578+ return 0;
579+ lua_dostring(L, buffer);
580+ lua_settop(L, 0); /* remove eventual returns */
464581 }
465582 }
466583
467584
585+#define LEVELS1 12 /* size of the first part of the stack */
586+#define LEVELS2 10 /* size of the second part of the stack */
468587
469−#define MESSAGESIZE 150
470−#define MAXMESSAGE (MESSAGESIZE*10)
471−
472−
473−#define MAXSRC 60
474−
475−
476−static void errorfb (void) {
477− char buff[MAXMESSAGE];
588+static int errorfb (lua_State *L) {
478589 int level = 1; /* skip level 0 (it's this function) */
479− lua_Object func;
480− sprintf(buff, "lua error: %.200s\n", lua_getstring(lua_getparam(1)));
481− while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
482− char *name;
483− int currentline;
484− char *chunkname;
485− char buffchunk[MAXSRC];
486− int linedefined;
487− lua_funcinfo(func, &chunkname, &linedefined);
488− luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk));
489− if (level == 2) strcat(buff, "Active Stack:\n");
490− strcat(buff, " ");
491− if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) {
492− strcat(buff, "...\n");
493− break; /* buffer is full */
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;
494612 }
495− switch (*lua_getobjname(func, &name)) {
496− case 'g':
497− sprintf(buff+strlen(buff), "function `%.50s'", name);
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);
498619 break;
499− case 't':
500− sprintf(buff+strlen(buff), "`%.50s' tag method", name);
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);
501625 break;
502626 default: {
503− if (linedefined == 0)
504− sprintf(buff+strlen(buff), "main of %.70s", buffchunk);
505− else if (linedefined < 0)
506− sprintf(buff+strlen(buff), "%.70s", buffchunk);
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);
507631 else
508− sprintf(buff+strlen(buff), "function <%d:%.70s>",
509− linedefined, buffchunk);
510− chunkname = NULL;
632+ sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src);
633+ ar.source = NULL; /* do not print source again */
511634 }
512635 }
513− if ((currentline = lua_currentline(func)) > 0)
514− sprintf(buff+strlen(buff), " at line %d", currentline);
515− if (chunkname)
516− sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
517− strcat(buff, "\n");
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");
518646 }
519− func = lua_rawgetglobal("_ALERT");
520− if (lua_isfunction(func)) { /* avoid error loop if _ALERT is not defined */
521− lua_pushstring(buff);
522− lua_callfunction(func);
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);
523652 }
653+ return 0;
524654 }
525655
526656
527657
528−static struct luaL_reg iolib[] = {
529− {"_ERRORMESSAGE", errorfb},
658+static const struct luaL_reg iolib[] = {
659+ {LUA_ERRORMESSAGE, errorfb},
530660 {"clock", io_clock},
531661 {"date", io_date},
532662 {"debug", io_debug},
@@ -540,7 +670,7 @@ static struct luaL_reg iolib[] = { · 7 unmodified lines
540670 };
541671
542672
543−static struct luaL_reg iolibtag[] = {
673+static const struct luaL_reg iolibtag[] = {
544674 {"appendto", io_appendto},
545675 {"closefile", io_close},
546676 {"flush", io_flush},
@@ -553,31 +683,36 @@ static struct luaL_reg iolibtag[] = { · 6 unmodified lines
553683 };
554684
555685
556−static void openwithtags (void) {
557− int i;
558− int iotag = lua_newtag();
559− lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */
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);
560691 for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
561− /* put iotag as upvalue for these functions */
562− lua_pushnumber(iotag);
563− lua_pushcclosure(iolibtag[i].func, 1);
564− lua_setglobal(iolibtag[i].name);
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);
565696 }
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);
566702 /* predefined file handles */
567− setfile(stdin, FINPUT, iotag);
568− setfile(stdout, FOUTPUT, iotag);
569− setfile(stdin, "_STDIN", iotag);
570− setfile(stdout, "_STDOUT", iotag);
571− setfile(stderr, "_STDERR", iotag);
572− /* close file when collected */
573− lua_pushnumber(iotag);
574− lua_pushcclosure(gc_close, 1);
575− lua_settagmethod(iotag, "gc");
576−}
577−
578−void lua_iolibopen (void) {
579− /* register lib functions */
580− luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
581− openwithtags();
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);
582717 }
583718
src/lib/lmathlib.c+114−79
@@ -1,6 +1,6 @@
11 /*
2−** $Id: lmathlib.c,v 1.17 1999/07/07 17:54:08 roberto Exp $
3−** Lua standard mathematical library
2+** $Id: lmathlib.c,v 1.32 2000/10/31 13:10:24 roberto Exp $
3+** Standard mathematical library
44 ** See Copyright Notice in lua.h
55 */
66
@@ -8,14 +8,15 @@ · 1 unmodified line
88 #include <stdlib.h>
99 #include <math.h>
1010
11−#include "lauxlib.h"
1211 #include "lua.h"
12+
13+#include "lauxlib.h"
1314 #include "lualib.h"
1415
1516
1617 #undef PI
17−#define PI (3.14159265358979323846)
18−#define RADIANS_PER_DEGREE (PI/180.0)
18+#define PI (3.14159265358979323846)
19+#define RADIANS_PER_DEGREE (PI/180.0)
1920
2021
2122
@@ -32,139 +33,173 @@ · 10 unmodified lines
3233 #endif
3334
3435
35−static void math_abs (void) {
36− lua_pushnumber(fabs(luaL_check_number(1)));
36+static int math_abs (lua_State *L) {
37+ lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
38+ return 1;
3739 }
3840
39−static void math_sin (void) {
40− lua_pushnumber(sin(TORAD(luaL_check_number(1))));
41+static int math_sin (lua_State *L) {
42+ lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
43+ return 1;
4144 }
4245
43−static void math_cos (void) {
44− lua_pushnumber(cos(TORAD(luaL_check_number(1))));
46+static int math_cos (lua_State *L) {
47+ lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
48+ return 1;
4549 }
4650
47−static void math_tan (void) {
48− lua_pushnumber(tan(TORAD(luaL_check_number(1))));
51+static int math_tan (lua_State *L) {
52+ lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
53+ return 1;
4954 }
5055
51−static void math_asin (void) {
52− lua_pushnumber(FROMRAD(asin(luaL_check_number(1))));
56+static int math_asin (lua_State *L) {
57+ lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
58+ return 1;
5359 }
5460
55−static void math_acos (void) {
56− lua_pushnumber(FROMRAD(acos(luaL_check_number(1))));
61+static int math_acos (lua_State *L) {
62+ lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
63+ return 1;
5764 }
5865
59−static void math_atan (void) {
60− lua_pushnumber(FROMRAD(atan(luaL_check_number(1))));
66+static int math_atan (lua_State *L) {
67+ lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
68+ return 1;
6169 }
6270
63−static void math_atan2 (void) {
64− lua_pushnumber(FROMRAD(atan2(luaL_check_number(1), luaL_check_number(2))));
71+static int math_atan2 (lua_State *L) {
72+ lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
73+ return 1;
6574 }
6675
67−static void math_ceil (void) {
68− lua_pushnumber(ceil(luaL_check_number(1)));
76+static int math_ceil (lua_State *L) {
77+ lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
78+ return 1;
6979 }
7080
71−static void math_floor (void) {
72− lua_pushnumber(floor(luaL_check_number(1)));
81+static int math_floor (lua_State *L) {
82+ lua_pushnumber(L, floor(luaL_check_number(L, 1)));
83+ return 1;
7384 }
7485
75−static void math_mod (void) {
76− lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2)));
86+static int math_mod (lua_State *L) {
87+ lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
88+ return 1;
7789 }
7890
79−static void math_sqrt (void) {
80− lua_pushnumber(sqrt(luaL_check_number(1)));
91+static int math_sqrt (lua_State *L) {
92+ lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
93+ return 1;
8194 }
8295
83−static void math_pow (void) {
84− lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2)));
96+static int math_pow (lua_State *L) {
97+ lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
98+ return 1;
8599 }
86100
87−static void math_log (void) {
88− lua_pushnumber(log(luaL_check_number(1)));
101+static int math_log (lua_State *L) {
102+ lua_pushnumber(L, log(luaL_check_number(L, 1)));
103+ return 1;
89104 }
90105
91−static void math_log10 (void) {
92− lua_pushnumber(log10(luaL_check_number(1)));
106+static int math_log10 (lua_State *L) {
107+ lua_pushnumber(L, log10(luaL_check_number(L, 1)));
108+ return 1;
93109 }
94110
95−static void math_exp (void) {
96− lua_pushnumber(exp(luaL_check_number(1)));
111+static int math_exp (lua_State *L) {
112+ lua_pushnumber(L, exp(luaL_check_number(L, 1)));
113+ return 1;
97114 }
98115
99−static void math_deg (void) {
100− lua_pushnumber(luaL_check_number(1)/RADIANS_PER_DEGREE);
116+static int math_deg (lua_State *L) {
117+ lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
118+ return 1;
101119 }
102120
103−static void math_rad (void) {
104− lua_pushnumber(luaL_check_number(1)*RADIANS_PER_DEGREE);
121+static int math_rad (lua_State *L) {
122+ lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
123+ return 1;
105124 }
106125
107−static void math_frexp (void) {
126+static int math_frexp (lua_State *L) {
108127 int e;
109− lua_pushnumber(frexp(luaL_check_number(1), &e));
110− lua_pushnumber(e);
128+ lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
129+ lua_pushnumber(L, e);
130+ return 2;
111131 }
112132
113−static void math_ldexp (void) {
114− lua_pushnumber(ldexp(luaL_check_number(1), luaL_check_int(2)));
133+static int math_ldexp (lua_State *L) {
134+ lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
135+ return 1;
115136 }
116137
117138
118139
119−static void math_min (void) {
120− int i = 1;
121− double dmin = luaL_check_number(i);
122− while (lua_getparam(++i) != LUA_NOOBJECT) {
123− double d = luaL_check_number(i);
140+static int math_min (lua_State *L) {
141+ int n = lua_gettop(L); /* number of arguments */
142+ double dmin = luaL_check_number(L, 1);
143+ int i;
144+ for (i=2; i<=n; i++) {
145+ double d = luaL_check_number(L, i);
124146 if (d < dmin)
125147 dmin = d;
126148 }
127− lua_pushnumber(dmin);
149+ lua_pushnumber(L, dmin);
150+ return 1;
128151 }
129152
130153
131−static void math_max (void) {
132− int i = 1;
133− double dmax = luaL_check_number(i);
134− while (lua_getparam(++i) != LUA_NOOBJECT) {
135− double d = luaL_check_number(i);
154+static int math_max (lua_State *L) {
155+ int n = lua_gettop(L); /* number of arguments */
156+ double dmax = luaL_check_number(L, 1);
157+ int i;
158+ for (i=2; i<=n; i++) {
159+ double d = luaL_check_number(L, i);
136160 if (d > dmax)
137161 dmax = d;
138162 }
139− lua_pushnumber(dmax);
163+ lua_pushnumber(L, dmax);
164+ return 1;
140165 }
141166
142167
143−static void math_random (void) {
168+static int math_random (lua_State *L) {
144169 /* the '%' avoids the (rare) case of r==1, and is needed also because on
145− some systems (SunOS!) "rand()" may return a value bigger than RAND_MAX */
170+ some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
146171 double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
147− int l = luaL_opt_int(1, 0);
148− if (l == 0)
149− lua_pushnumber(r);
150− else {
151− int u = luaL_opt_int(2, 0);
152− if (u == 0) {
153− u = l;
154− l = 1;
172+ switch (lua_gettop(L)) { /* check number of arguments */
173+ case 0: { /* no arguments */
174+ lua_pushnumber(L, r); /* Number between 0 and 1 */
175+ break;
176+ }
177+ 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' */
181+ break;
182+ }
183+ 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' */
188+ break;
155189 }
156− luaL_arg_check(l<=u, 1, "interval is empty");
157− lua_pushnumber((int)(r*(u-l+1))+l);
190+ default: lua_error(L, "wrong number of arguments");
158191 }
192+ return 1;
159193 }
160194
161195
162−static void math_randomseed (void) {
163− srand(luaL_check_int(1));
196+static int math_randomseed (lua_State *L) {
197+ srand(luaL_check_int(L, 1));
198+ return 0;
164199 }
165200
166201
167−static struct luaL_reg mathlib[] = {
202+static const struct luaL_reg mathlib[] = {
168203 {"abs", math_abs},
169204 {"sin", math_sin},
170205 {"cos", math_cos},
@@ -193,11 +228,11 @@ static struct luaL_reg mathlib[] = { · 22 unmodified lines
193228 /*
194229 ** Open math library
195230 */
196−void lua_mathlibopen (void) {
197− luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
198− lua_pushcfunction(math_pow);
199− lua_pushnumber(0); /* to get its tag */
200− lua_settagmethod(lua_tag(lua_pop()), "pow");
201− lua_pushnumber(PI); lua_setglobal("PI");
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");
235+ lua_pushnumber(L, PI);
236+ lua_setglobal(L, "PI");
202237 }
203238
src/lib/lstrlib.c+265−238
@@ -1,112 +1,111 @@
11 /*
2−** $Id: lstrlib.c,v 1.32 1999/06/17 17:04:03 roberto Exp $
3−** Standard library for strings and pattern-matching
2+** $Id: lstrlib.c,v 1.56 2000/10/27 16:15:53 roberto Exp $
3+** Standard library for string operations and pattern-matching
44 ** See Copyright Notice in lua.h
55 */
66
77
88 #include <ctype.h>
9+#include <stddef.h>
910 #include <stdio.h>
1011 #include <stdlib.h>
1112 #include <string.h>
1213
13−#include "lauxlib.h"
1414 #include "lua.h"
15−#include "lualib.h"
16−
17−
18−
19−static void addnchar (char *s, int n)
20−{
21− char *b = luaL_openspace(n);
22− memcpy(b, s, n);
23− luaL_addsize(n);
24−}
2515
16+#include "lauxlib.h"
17+#include "lualib.h"
2618
27−static void str_len (void)
28−{
29− long l;
30− luaL_check_lstr(1, &l);
31− lua_pushnumber(l);
32−}
3319
3420
35−static void closeandpush (void) {
36− lua_pushlstring(luaL_buffer(), luaL_getsize());
21+static int str_len (lua_State *L) {
22+ size_t l;
23+ luaL_check_lstr(L, 1, &l);
24+ lua_pushnumber(L, l);
25+ return 1;
3726 }
3827
3928
40−static long posrelat (long pos, long len) {
29+static long posrelat (long pos, size_t len) {
4130 /* relative string position: negative means back from end */
42− return (pos>=0) ? pos : len+pos+1;
31+ return (pos>=0) ? pos : (long)len+pos+1;
4332 }
4433
4534
46−static void str_sub (void) {
47− long l;
48− char *s = luaL_check_lstr(1, &l);
49− long start = posrelat(luaL_check_long(2), l);
50− long end = posrelat(luaL_opt_long(3, -1), l);
35+static int str_sub (lua_State *L) {
36+ 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);
5140 if (start < 1) start = 1;
52− if (end > l) end = l;
41+ if (end > (long)l) end = l;
5342 if (start <= end)
54− lua_pushlstring(s+start-1, end-start+1);
55− else lua_pushstring("");
43+ lua_pushlstring(L, s+start-1, end-start+1);
44+ else lua_pushstring(L, "");
45+ return 1;
5646 }
5747
5848
59−static void str_lower (void) {
60− long l;
61− int i;
62− char *s = luaL_check_lstr(1, &l);
63− luaL_resetbuffer();
49+static int str_lower (lua_State *L) {
50+ size_t l;
51+ size_t i;
52+ luaL_Buffer b;
53+ const char *s = luaL_check_lstr(L, 1, &l);
54+ luaL_buffinit(L, &b);
6455 for (i=0; i<l; i++)
65− luaL_addchar(tolower((unsigned char)(s[i])));
66− closeandpush();
56+ luaL_putchar(&b, tolower((unsigned char)(s[i])));
57+ luaL_pushresult(&b);
58+ return 1;
6759 }
6860
6961
70−static void str_upper (void) {
71− long l;
72− int i;
73− char *s = luaL_check_lstr(1, &l);
74− luaL_resetbuffer();
62+static int str_upper (lua_State *L) {
63+ size_t l;
64+ size_t i;
65+ luaL_Buffer b;
66+ const char *s = luaL_check_lstr(L, 1, &l);
67+ luaL_buffinit(L, &b);
7568 for (i=0; i<l; i++)
76− luaL_addchar(toupper((unsigned char)(s[i])));
77− closeandpush();
69+ luaL_putchar(&b, toupper((unsigned char)(s[i])));
70+ luaL_pushresult(&b);
71+ return 1;
7872 }
7973
80−static void str_rep (void)
81−{
82− long l;
83− char *s = luaL_check_lstr(1, &l);
84− int n = luaL_check_int(2);
85− luaL_resetbuffer();
74+static int str_rep (lua_State *L) {
75+ size_t l;
76+ luaL_Buffer b;
77+ const char *s = luaL_check_lstr(L, 1, &l);
78+ int n = luaL_check_int(L, 2);
79+ luaL_buffinit(L, &b);
8680 while (n-- > 0)
87− addnchar(s, l);
88− closeandpush();
81+ luaL_addlstring(&b, s, l);
82+ luaL_pushresult(&b);
83+ return 1;
8984 }
9085
9186
92−static void str_byte (void) {
93− long l;
94− char *s = luaL_check_lstr(1, &l);
95− long pos = posrelat(luaL_opt_long(2, 1), l);
96− luaL_arg_check(0<pos && pos<=l, 2, "out of range");
97− lua_pushnumber((unsigned char)s[pos-1]);
87+static int str_byte (lua_State *L) {
88+ 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]);
93+ return 1;
9894 }
9995
10096
101−static void str_char (void) {
102− int i = 0;
103− luaL_resetbuffer();
104− while (lua_getparam(++i) != LUA_NOOBJECT) {
105− double c = luaL_check_number(i);
106− luaL_arg_check((unsigned char)c == c, i, "invalid value");
107− luaL_addchar((unsigned char)c);
97+static int str_char (lua_State *L) {
98+ int n = lua_gettop(L); /* number of arguments */
99+ int i;
100+ luaL_Buffer b;
101+ luaL_buffinit(L, &b);
102+ 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);
108106 }
109− closeandpush();
107+ luaL_pushresult(&b);
108+ return 1;
110109 }
111110
112111
@@ -117,63 +116,53 @@ static void str_char (void) { · 4 unmodified lines
117116 ** =======================================================
118117 */
119118
120−#ifndef MAX_CAPT
121−#define MAX_CAPT 32 /* arbitrary limit */
119+#ifndef MAX_CAPTURES
120+#define MAX_CAPTURES 32 /* arbitrary limit */
122121 #endif
123122
124123
125124 struct Capture {
126− char *src_end; /* end ('\0') of source string */
125+ const char *src_end; /* end ('\0') of source string */
127126 int level; /* total number of captures (finished or unfinished) */
128127 struct {
129− char *init;
130− int len; /* -1 signals unfinished capture */
131− } capture[MAX_CAPT];
128+ const char *init;
129+ long len; /* -1 signals unfinished capture */
130+ } capture[MAX_CAPTURES];
132131 };
133132
134133
135−#define ESC '%'
136−#define SPECIALS "^$*+?.([%-"
134+#define ESC '%'
135+#define SPECIALS "^$*+?.([%-"
137136
138137
139−static void push_captures (struct Capture *cap) {
140− int i;
141− for (i=0; i<cap->level; i++) {
142− int l = cap->capture[i].len;
143− if (l == -1) lua_error("unfinished capture");
144− lua_pushlstring(cap->capture[i].init, l);
145− }
146−}
147−
148−
149−static int check_cap (int l, struct Capture *cap) {
138+static int check_capture (lua_State *L, int l, struct Capture *cap) {
150139 l -= '1';
151140 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
152− lua_error("invalid capture index");
141+ lua_error(L, "invalid capture index");
153142 return l;
154143 }
155144
156145
157−static int capture_to_close (struct Capture *cap) {
146+static int capture_to_close (lua_State *L, struct Capture *cap) {
158147 int level = cap->level;
159148 for (level--; level>=0; level--)
160149 if (cap->capture[level].len == -1) return level;
161− lua_error("invalid pattern capture");
150+ lua_error(L, "invalid pattern capture");
162151 return 0; /* to avoid warnings */
163152 }
164153
165154
166−char *luaI_classend (char *p) {
155+const char *luaI_classend (lua_State *L, const char *p) {
167156 switch (*p++) {
168157 case ESC:
169− if (*p == '\0')
170− luaL_verror("incorrect pattern (ends with `%c')", ESC);
158+ if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')");
171159 return p+1;
172160 case '[':
173161 if (*p == '^') p++;
174− if (*p == ']') p++;
175− p = strchr(p, ']');
176− if (!p) lua_error("incorrect pattern (missing `]')");
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. '%]') */
165+ } while (*p != ']');
177166 return p+1;
178167 default:
179168 return p;
@@ -181,7 +170,7 @@ char *luaI_classend (char *p) { · 1 unmodified line
181170 }
182171
183172
184−static int matchclass (int c, int cl) {
173+static int match_class (int c, int cl) {
185174 int res;
186175 switch (tolower(cl)) {
187176 case 'a' : res = isalpha(c); break;
@@ -201,36 +190,36 @@ static int matchclass (int c, int cl) { · 13 unmodified lines
201190
202191
203192
204−static int matchbracketclass (int c, char *p, char *end) {
193+static int matchbracketclass (int c, const char *p, const char *endclass) {
205194 int sig = 1;
206195 if (*(p+1) == '^') {
207196 sig = 0;
208197 p++; /* skip the '^' */
209198 }
210− while (++p < end) {
199+ while (++p < endclass) {
211200 if (*p == ESC) {
212201 p++;
213− if ((p < end) && matchclass(c, (unsigned char)*p))
202+ if (match_class(c, (unsigned char)*p))
214203 return sig;
215204 }
216− else if ((*(p+1) == '-') && (p+2 < end)) {
205+ else if ((*(p+1) == '-') && (p+2 < endclass)) {
217206 p+=2;
218207 if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
219208 return sig;
220209 }
221− else if ((unsigned char)*p == c) return sig;
210+ else if ((int)(unsigned char)*p == c) return sig;
222211 }
223212 return !sig;
224213 }
225214
226215
227216
228−int luaI_singlematch (int c, char *p, char *ep) {
217+int luaI_singlematch (int c, const char *p, const char *ep) {
229218 switch (*p) {
230219 case '.': /* matches any char */
231220 return 1;
232221 case ESC:
233− return matchclass(c, (unsigned char)*(p+1));
222+ return match_class(c, (unsigned char)*(p+1));
234223 case '[':
235224 return matchbracketclass(c, p, ep-1);
236225 default:
@@ -239,12 +228,14 @@ int luaI_singlematch (int c, char *p, char *ep) { · 2 unmodified lines
239228 }
240229
241230
242−static char *match (char *s, char *p, struct Capture *cap);
231+static const char *match (lua_State *L, const char *s, const char *p,
232+ struct Capture *cap);
243233
244234
245−static char *matchbalance (char *s, char *p, struct Capture *cap) {
235+static const char *matchbalance (lua_State *L, const char *s, const char *p,
236+ struct Capture *cap) {
246237 if (*p == 0 || *(p+1) == 0)
247− lua_error("unbalanced pattern");
238+ lua_error(L, "unbalanced pattern");
248239 if (*s != *p) return NULL;
249240 else {
250241 int b = *p;
@@ -261,13 +252,14 @@ static char *matchbalance (char *s, char *p, struct Capture *cap) { · 10 unmodified lines
261252 }
262253
263254
264−static char *max_expand (char *s, char *p, char *ep, struct Capture *cap) {
265− int i = 0; /* counts maximum expand for item */
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 */
266258 while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
267259 i++;
268− /* keeps trying to match mith the maximum repetitions */
260+ /* keeps trying to match with the maximum repetitions */
269261 while (i>=0) {
270− char *res = match((s+i), ep+1, cap);
262+ const char *res = match(L, (s+i), ep+1, cap);
271263 if (res) return res;
272264 i--; /* else didn't match; reduce 1 repetition to try again */
273265 }
@@ -275,9 +267,10 @@ static char *max_expand (char *s, char *p, char *ep, struct Capture *cap) { · 1 unmodified line
275267 }
276268
277269
278−static char *min_expand (char *s, char *p, char *ep, struct Capture *cap) {
270+static const char *min_expand (lua_State *L, const char *s, const char *p,
271+ const char *ep, struct Capture *cap) {
279272 for (;;) {
280− char *res = match(s, ep+1, cap);
273+ const char *res = match(L, s, ep+1, cap);
281274 if (res != NULL)
282275 return res;
283276 else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
@@ -287,56 +280,60 @@ static char *min_expand (char *s, char *p, char *ep, struct Capture *cap) { · 3 unmodified lines
287280 }
288281
289282
290−static char *start_capt (char *s, char *p, struct Capture *cap) {
291− char *res;
283+static const char *start_capture (lua_State *L, const char *s, const char *p,
284+ struct Capture *cap) {
285+ const char *res;
292286 int level = cap->level;
293− if (level >= MAX_CAPT) lua_error("too many captures");
287+ if (level >= MAX_CAPTURES) lua_error(L, "too many captures");
294288 cap->capture[level].init = s;
295289 cap->capture[level].len = -1;
296290 cap->level = level+1;
297− if ((res=match(s, p+1, cap)) == NULL) /* match failed? */
291+ if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */
298292 cap->level--; /* undo capture */
299293 return res;
300294 }
301295
302296
303−static char *end_capt (char *s, char *p, struct Capture *cap) {
304− int l = capture_to_close(cap);
305− char *res;
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);
300+ const char *res;
306301 cap->capture[l].len = s - cap->capture[l].init; /* close capture */
307− if ((res = match(s, p+1, cap)) == NULL) /* match failed? */
302+ if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */
308303 cap->capture[l].len = -1; /* undo capture */
309304 return res;
310305 }
311306
312307
313−static char *match_capture (char *s, int level, struct Capture *cap) {
314− int l = check_cap(level, cap);
315− int len = cap->capture[l].len;
316− if (cap->src_end-s >= len &&
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 &&
317313 memcmp(cap->capture[l].init, s, len) == 0)
318314 return s+len;
319315 else return NULL;
320316 }
321317
322318
323−static char *match (char *s, char *p, struct Capture *cap) {
319+static const char *match (lua_State *L, const char *s, const char *p,
320+ struct Capture *cap) {
324321 init: /* using goto's to optimize tail recursion */
325322 switch (*p) {
326323 case '(': /* start capture */
327− return start_capt(s, p, cap);
324+ return start_capture(L, s, p, cap);
328325 case ')': /* end capture */
329− return end_capt(s, p, cap);
326+ return end_capture(L, s, p, cap);
330327 case ESC: /* may be %[0-9] or %b */
331328 if (isdigit((unsigned char)(*(p+1)))) { /* capture? */
332− s = match_capture(s, *(p+1), cap);
329+ s = match_capture(L, s, *(p+1), cap);
333330 if (s == NULL) return NULL;
334− p+=2; goto init; /* else return match(p+2, s, cap) */
331+ p+=2; goto init; /* else return match(L, s, p+2, cap) */
335332 }
336333 else if (*(p+1) == 'b') { /* balanced string? */
337− s = matchbalance(s, p+2, cap);
334+ s = matchbalance(L, s, p+2, cap);
338335 if (s == NULL) return NULL;
339− p+=4; goto init; /* else return match(p+4, s, cap); */
336+ p+=4; goto init; /* else return match(L, s, p+4, cap); */
340337 }
341338 else goto dflt; /* case default */
342339 case '\0': /* end of pattern */
@@ -346,178 +343,208 @@ static char *match (char *s, char *p, struct Capture *cap) { · 3 unmodified lines
346343 return (s == cap->src_end) ? s : NULL; /* check end of string */
347344 else goto dflt;
348345 default: dflt: { /* it is a pattern item */
349− char *ep = luaI_classend(p); /* points to what is next */
346+ const char *ep = luaI_classend(L, p); /* points to what is next */
350347 int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
351348 switch (*ep) {
352349 case '?': { /* optional */
353− char *res;
354− if (m && ((res=match(s+1, ep+1, cap)) != NULL))
350+ const char *res;
351+ if (m && ((res=match(L, s+1, ep+1, cap)) != NULL))
355352 return res;
356− p=ep+1; goto init; /* else return match(s, ep+1, cap); */
353+ p=ep+1; goto init; /* else return match(L, s, ep+1, cap); */
357354 }
358355 case '*': /* 0 or more repetitions */
359− return max_expand(s, p, ep, cap);
356+ return max_expand(L, s, p, ep, cap);
360357 case '+': /* 1 or more repetitions */
361− return (m ? max_expand(s+1, p, ep, cap) : NULL);
358+ return (m ? max_expand(L, s+1, p, ep, cap) : NULL);
362359 case '-': /* 0 or more repetitions (minimum) */
363− return min_expand(s, p, ep, cap);
360+ return min_expand(L, s, p, ep, cap);
364361 default:
365362 if (!m) return NULL;
366− s++; p=ep; goto init; /* else return match(s+1, ep, cap); */
363+ s++; p=ep; goto init; /* else return match(L, s+1, ep, cap); */
364+ }
365+ }
366+ }
367+}
368+
369+
370+
371+static const char *lmemfind (const char *s1, size_t l1,
372+ const char *s2, size_t l2) {
373+ if (l2 == 0) return s1; /* empty strings are everywhere */
374+ else if (l2 > l1) return NULL; /* avoids a negative `l1' */
375+ else {
376+ const char *init; /* to search for a `*s2' inside `s1' */
377+ l2--; /* 1st char will be checked by `memchr' */
378+ l1 = l1-l2; /* `s2' cannot be found after that */
379+ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
380+ init++; /* 1st char is already checked */
381+ if (memcmp(init, s2+1, l2) == 0)
382+ return init-1;
383+ else { /* correct `l1' and `s1' to try again */
384+ l1 -= init-s1;
385+ s1 = init;
367386 }
368387 }
388+ return NULL; /* not found */
369389 }
370390 }
371391
372392
373−static void str_find (void) {
374− long l;
375− char *s = luaL_check_lstr(1, &l);
376− char *p = luaL_check_string(2);
377− long init = posrelat(luaL_opt_long(3, 1), l) - 1;
393+static int push_captures (lua_State *L, struct Capture *cap) {
394+ 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);
400+ }
401+ return cap->level; /* number of strings pushed */
402+}
403+
404+
405+static int str_find (lua_State *L) {
406+ 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;
378410 struct Capture cap;
379− luaL_arg_check(0 <= init && init <= l, 3, "out of range");
380− if (lua_getparam(4) != LUA_NOOBJECT ||
381− strpbrk(p, SPECIALS) == NULL) { /* no special characters? */
382− char *s2 = strstr(s+init, p);
411+ luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
412+ if (lua_gettop(L) > 3 || /* extra argument? */
413+ strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
414+ const char *s2 = lmemfind(s+init, l1-init, p, l2);
383415 if (s2) {
384− lua_pushnumber(s2-s+1);
385− lua_pushnumber(s2-s+strlen(p));
386− return;
416+ lua_pushnumber(L, s2-s+1);
417+ lua_pushnumber(L, s2-s+l2);
418+ return 2;
387419 }
388420 }
389421 else {
390422 int anchor = (*p == '^') ? (p++, 1) : 0;
391− char *s1=s+init;
392− cap.src_end = s+l;
423+ const char *s1=s+init;
424+ cap.src_end = s+l1;
393425 do {
394− char *res;
426+ const char *res;
395427 cap.level = 0;
396− if ((res=match(s1, p, &cap)) != NULL) {
397− lua_pushnumber(s1-s+1); /* start */
398− lua_pushnumber(res-s); /* end */
399− push_captures(&cap);
400− return;
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;
401432 }
402433 } while (s1++<cap.src_end && !anchor);
403434 }
404− lua_pushnil(); /* if arrives here, it didn't find */
435+ lua_pushnil(L); /* not found */
436+ return 1;
405437 }
406438
407439
408−static void add_s (lua_Object newp, struct Capture *cap) {
409− if (lua_isstring(newp)) {
410− char *news = lua_getstring(newp);
411− int l = lua_strlen(newp);
412− int i;
440+static void add_s (lua_State *L, luaL_Buffer *b, struct Capture *cap) {
441+ if (lua_isstring(L, 3)) {
442+ const char *news = lua_tostring(L, 3);
443+ size_t l = lua_strlen(L, 3);
444+ size_t i;
413445 for (i=0; i<l; i++) {
414446 if (news[i] != ESC)
415− luaL_addchar(news[i]);
447+ luaL_putchar(b, news[i]);
416448 else {
417449 i++; /* skip ESC */
418450 if (!isdigit((unsigned char)news[i]))
419− luaL_addchar(news[i]);
451+ luaL_putchar(b, news[i]);
420452 else {
421− int level = check_cap(news[i], cap);
422− addnchar(cap->capture[level].init, cap->capture[level].len);
453+ int level = check_capture(L, news[i], cap);
454+ luaL_addlstring(b, cap->capture[level].init, cap->capture[level].len);
423455 }
424456 }
425457 }
426458 }
427459 else { /* is a function */
428− lua_Object res;
429− int status;
430− int oldbuff;
431− lua_beginblock();
432− push_captures(cap);
433− /* function may use buffer, so save it and create a new one */
434− oldbuff = luaL_newbuffer(0);
435− status = lua_callfunction(newp);
436− /* restore old buffer */
437− luaL_oldbuffer(oldbuff);
438− if (status != 0) {
439− lua_endblock();
440− lua_error(NULL);
441− }
442− res = lua_getresult(1);
443− if (lua_isstring(res))
444− addnchar(lua_getstring(res), lua_strlen(res));
445− lua_endblock();
460+ int n;
461+ lua_pushvalue(L, 3);
462+ n = push_captures(L, cap);
463+ lua_rawcall(L, n, 1);
464+ if (lua_isstring(L, -1))
465+ luaL_addvalue(b); /* add return to accumulated result */
466+ else
467+ lua_pop(L, 1); /* function result is not a string: pop it */
446468 }
447469 }
448470
449471
450−static void str_gsub (void) {
451− long srcl;
452− char *src = luaL_check_lstr(1, &srcl);
453− char *p = luaL_check_string(2);
454− lua_Object newp = lua_getparam(3);
455− int max_s = luaL_opt_int(4, srcl+1);
472+static int str_gsub (lua_State *L) {
473+ 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);
456477 int anchor = (*p == '^') ? (p++, 1) : 0;
457478 int n = 0;
458479 struct Capture cap;
459− luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3,
460− "string or function expected");
461− luaL_resetbuffer();
480+ luaL_Buffer b;
481+ luaL_arg_check(L,
482+ lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
483+ 3, "string or function expected");
484+ luaL_buffinit(L, &b);
462485 cap.src_end = src+srcl;
463486 while (n < max_s) {
464− char *e;
487+ const char *e;
465488 cap.level = 0;
466− e = match(src, p, &cap);
489+ e = match(L, src, p, &cap);
467490 if (e) {
468491 n++;
469− add_s(newp, &cap);
492+ add_s(L, &b, &cap);
470493 }
471494 if (e && e>src) /* non empty match? */
472495 src = e; /* skip it */
473496 else if (src < cap.src_end)
474− luaL_addchar(*src++);
497+ luaL_putchar(&b, *src++);
475498 else break;
476499 if (anchor) break;
477500 }
478− addnchar(src, cap.src_end-src);
479− closeandpush();
480− lua_pushnumber(n); /* number of substitutions */
501+ luaL_addlstring(&b, src, cap.src_end-src);
502+ luaL_pushresult(&b);
503+ lua_pushnumber(L, n); /* number of substitutions */
504+ return 2;
481505 }
482506
483507 /* }====================================================== */
484508
485509
486−static void luaI_addquoted (int arg) {
487− long l;
488− char *s = luaL_check_lstr(arg, &l);
489− luaL_addchar('"');
510+static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
511+ size_t l;
512+ const char *s = luaL_check_lstr(L, arg, &l);
513+ luaL_putchar(b, '"');
490514 while (l--) {
491515 switch (*s) {
492516 case '"': case '\\': case '\n':
493− luaL_addchar('\\');
494− luaL_addchar(*s);
517+ luaL_putchar(b, '\\');
518+ luaL_putchar(b, *s);
495519 break;
496− case '\0': addnchar("\\000", 4); break;
497− default: luaL_addchar(*s);
520+ case '\0': luaL_addlstring(b, "\\000", 4); break;
521+ default: luaL_putchar(b, *s);
498522 }
499523 s++;
500524 }
501− luaL_addchar('"');
525+ luaL_putchar(b, '"');
502526 }
503527
528+/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
529+#define MAX_ITEM 512
504530 /* maximum size of each format specification (such as '%-099.99d') */
505−#define MAX_FORMAT 20 /* arbitrary limit */
531+#define MAX_FORMAT 20
506532
507−static void str_format (void) {
533+static int str_format (lua_State *L) {
508534 int arg = 1;
509− char *strfrmt = luaL_check_string(arg);
510− luaL_resetbuffer();
535+ const char *strfrmt = luaL_check_string(L, arg);
536+ luaL_Buffer b;
537+ luaL_buffinit(L, &b);
511538 while (*strfrmt) {
512539 if (*strfrmt != '%')
513− luaL_addchar(*strfrmt++);
540+ luaL_putchar(&b, *strfrmt++);
514541 else if (*++strfrmt == '%')
515− luaL_addchar(*strfrmt++); /* %% */
542+ luaL_putchar(&b, *strfrmt++); /* %% */
516543 else { /* format item */
517544 struct Capture cap;
518545 char form[MAX_FORMAT]; /* to store the format ('%...') */
519− char *buff; /* to store the formatted item */
520− char *initf = strfrmt;
546+ char buff[MAX_ITEM]; /* to store the formatted item */
547+ const char *initf = strfrmt;
521548 form[0] = '%';
522549 if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
523550 arg = *initf - '0';
@@ -526,33 +553,33 @@ static void str_format (void) { · 2 unmodified lines
526553 arg++;
527554 cap.src_end = strfrmt+strlen(strfrmt)+1;
528555 cap.level = 0;
529− strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
556+ strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
530557 if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
531558 strfrmt-initf > MAX_FORMAT-2)
532− lua_error("invalid format (width or precision too long)");
559+ lua_error(L, "invalid format (width or precision too long)");
533560 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
534561 form[strfrmt-initf+2] = 0;
535− buff = luaL_openspace(512); /* 512 > size of format('%99.99f', -1e308) */
536562 switch (*strfrmt++) {
537563 case 'c': case 'd': case 'i':
538− sprintf(buff, form, luaL_check_int(arg));
564+ sprintf(buff, form, luaL_check_int(L, arg));
539565 break;
540566 case 'o': case 'u': case 'x': case 'X':
541− sprintf(buff, form, (unsigned int)luaL_check_number(arg));
567+ sprintf(buff, form, (unsigned int)luaL_check_number(L, arg));
542568 break;
543569 case 'e': case 'E': case 'f': case 'g': case 'G':
544− sprintf(buff, form, luaL_check_number(arg));
570+ sprintf(buff, form, luaL_check_number(L, arg));
545571 break;
546572 case 'q':
547− luaI_addquoted(arg);
573+ luaI_addquoted(L, &b, arg);
548574 continue; /* skip the "addsize" at the end */
549575 case 's': {
550− long l;
551− char *s = luaL_check_lstr(arg, &l);
576+ size_t l;
577+ const char *s = luaL_check_lstr(L, arg, &l);
552578 if (cap.capture[1].len == 0 && l >= 100) {
553− /* no precision and string is too big to be formatted;
579+ /* no precision and string is too long to be formatted;
554580 keep original string */
555− addnchar(s, l);
581+ lua_pushvalue(L, arg);
582+ luaL_addvalue(&b);
556583 continue; /* skip the "addsize" at the end */
557584 }
558585 else {
@@ -561,16 +588,17 @@ static void str_format (void) { · 2 unmodified lines
561588 }
562589 }
563590 default: /* also treat cases 'pnLlh' */
564− lua_error("invalid option in `format'");
591+ lua_error(L, "invalid option in `format'");
565592 }
566− luaL_addsize(strlen(buff));
593+ luaL_addlstring(&b, buff, strlen(buff));
567594 }
568595 }
569− closeandpush(); /* push the result */
596+ luaL_pushresult(&b);
597+ return 1;
570598 }
571599
572600
573−static struct luaL_reg strlib[] = {
601+static const struct luaL_reg strlib[] = {
574602 {"strlen", str_len},
575603 {"strsub", str_sub},
576604 {"strlower", str_lower},
@@ -588,7 +616,6 @@ static struct luaL_reg strlib[] = { · 11 unmodified lines
588616 /*
589617 ** Open string library
590618 */
591−void strlib_open (void)
592−{
593− luaL_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
619+LUALIB_API void lua_strlibopen (lua_State *L) {
620+ luaL_openl(L, strlib);
594621 }
src/llex.c+219−276
@@ -1,71 +1,85 @@
11 /*
2−** $Id: llex.c,v 1.36 1999/06/17 17:04:03 roberto Exp $
2+** $Id: llex.c,v 1.72 2000/10/20 16:39:03 roberto Exp $
33 ** Lexical Analyzer
44 ** See Copyright Notice in lua.h
55 */
66
77
88 #include <ctype.h>
9+#include <stdio.h>
910 #include <string.h>
1011
11−#include "lauxlib.h"
12+#include "lua.h"
13+
1214 #include "llex.h"
1315 #include "lmem.h"
1416 #include "lobject.h"
1517 #include "lparser.h"
1618 #include "lstate.h"
1719 #include "lstring.h"
20+#include "ltable.h"
1821 #include "luadebug.h"
1922 #include "lzio.h"
2023
2124
2225
23−#define next(LS) (LS->current = zgetc(LS->lex_z))
24−
26+#define next(LS) (LS->current = zgetc(LS->z))
2527
26−#define save(c) luaL_addchar(c)
27−#define save_and_next(LS) (save(LS->current), next(LS))
2828
2929
30−char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
31− "if", "local", "nil", "not", "or", "repeat", "return", "then",
32− "until", "while"};
30+/* ORDER RESERVED */
31+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>"};
3335
3436
35−void luaX_init (void) {
37+void luaX_init (lua_State *L) {
3638 int i;
37− for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
38− TaggedString *ts = luaS_new(reserved[i]);
39− ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
39+ for (i=0; i<NUM_RESERVED; i++) {
40+ TString *ts = luaS_new(L, token2string[i]);
41+ ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */
4042 }
4143 }
4244
4345
4446 #define MAXSRC 80
4547
46−void luaX_syntaxerror (LexState *ls, char *s, char *token) {
48+
49+void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
50+ 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);
54+ }
55+}
56+
57+
58+void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
4759 char buff[MAXSRC];
48− luaL_chunkid(buff, zname(ls->lex_z), sizeof(buff));
49− if (token[0] == '\0')
50− token = "<eof>";
51− luaL_verror("%.100s;\n last token read: `%.50s' at line %d in %.80s",
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",
5262 s, token, ls->linenumber, buff);
5363 }
5464
5565
56−void luaX_error (LexState *ls, char *s) {
57− save('\0');
58− luaX_syntaxerror(ls, s, luaL_buffer());
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);
5973 }
6074
6175
6276 void luaX_token2str (int token, char *s) {
63− if (token < 255) {
77+ if (token < 256) {
6478 s[0] = (char)token;
6579 s[1] = '\0';
6680 }
6781 else
68− strcpy(s, reserved[token-FIRST_RESERVED]);
82+ strcpy(s, token2string[token-FIRST_RESERVED]);
6983 }
7084
7185
@@ -76,200 +90,199 @@ static void luaX_invalidchar (LexState *ls, int c) { · 4 unmodified lines
7690 }
7791
7892
79−static void firstline (LexState *LS)
80−{
81− int c = zgetc(LS->lex_z);
82− if (c == '#')
83− while ((c=zgetc(LS->lex_z)) != '\n' && c != EOZ) /* skip first line */;
84− zungetc(LS->lex_z);
93+static void inclinenumber (LexState *LS) {
94+ next(LS); /* skip '\n' */
95+ ++LS->linenumber;
96+ luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
8597 }
8698
8799
88−void luaX_setinput (LexState *LS, ZIO *z)
89−{
90− LS->current = '\n';
91− LS->linenumber = 0;
92− LS->iflevel = 0;
93− LS->ifstate[0].skip = 0;
94− LS->ifstate[0].elsepart = 1; /* to avoid a free $else */
95− LS->lex_z = z;
100+void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
101+ LS->L = L;
102+ LS->lookahead.token = TK_EOS; /* no look-ahead token */
103+ LS->z = z;
96104 LS->fs = NULL;
97− firstline(LS);
98− luaL_resetbuffer();
105+ LS->linenumber = 1;
106+ LS->lastline = 1;
107+ LS->source = source;
108+ next(LS); /* read first char */
109+ if (LS->current == '#') {
110+ do { /* skip first line */
111+ next(LS);
112+ } while (LS->current != '\n' && LS->current != EOZ);
113+ }
99114 }
100115
101116
102117
103118 /*
104119 ** =======================================================
105−** PRAGMAS
120+** LEXICAL ANALYZER
106121 ** =======================================================
107122 */
108123
109−#ifndef PRAGMASIZE
110−#define PRAGMASIZE 80 /* arbitrary limit */
111−#endif
112124
113−static void skipspace (LexState *LS) {
114− while (LS->current == ' ' || LS->current == '\t' || LS->current == '\r')
115− next(LS);
116−}
125+/* use Mbuffer to store names, literal strings and numbers */
117126
127+#define EXTRABUFF 128
128+#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \
129+ luaO_openspace(L, (len)+(n)+EXTRABUFF)
118130
119−static int checkcond (LexState *LS, char *buff) {
120− static char *opts[] = {"nil", "1", NULL};
121− int i = luaL_findstring(buff, opts);
122− if (i >= 0) return i;
123− else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
124− return luaS_globaldefined(buff);
125− else {
126− luaX_syntaxerror(LS, "invalid $if condition", buff);
127− return 0; /* to avoid warnings */
128− }
129−}
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))
130133
131134
132−static void readname (LexState *LS, char *buff) {
133− int i = 0;
134− skipspace(LS);
135− while (isalnum(LS->current) || LS->current == '_') {
136− if (i >= PRAGMASIZE) {
137− buff[PRAGMASIZE] = 0;
138− luaX_syntaxerror(LS, "pragma too long", buff);
139− }
140− buff[i++] = (char)LS->current;
141− next(LS);
142− }
143− buff[i] = 0;
135+static const char *readname (LexState *LS) {
136+ lua_State *L = LS->L;
137+ size_t l = 0;
138+ checkbuffer(L, 10, l);
139+ do {
140+ checkbuffer(L, 10, l);
141+ save_and_next(L, LS, l);
142+ } while (isalnum(LS->current) || LS->current == '_');
143+ save(L, '\0', l);
144+ return L->Mbuffer;
144145 }
145146
146147
147−static void inclinenumber (LexState *LS);
148−
149−
150−static void ifskip (LexState *LS) {
151− while (LS->ifstate[LS->iflevel].skip) {
152− if (LS->current == '\n')
153− inclinenumber(LS);
154− else if (LS->current == EOZ)
155− luaX_error(LS, "input ends inside a $if");
156− else next(LS);
148+/* LUA_NUMBER */
149+static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
150+ lua_State *L = LS->L;
151+ size_t l = 0;
152+ checkbuffer(L, 10, l);
153+ if (comma) save(L, '.', l);
154+ while (isdigit(LS->current)) {
155+ checkbuffer(L, 10, l);
156+ save_and_next(L, LS, l);
157157 }
158−}
159−
160−
161−static void inclinenumber (LexState *LS) {
162− static char *pragmas [] =
163− {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL};
164− next(LS); /* skip '\n' */
165− ++LS->linenumber;
166− if (LS->current == '$') { /* is a pragma? */
167− char buff[PRAGMASIZE+1];
168− int ifnot = 0;
169− int skip = LS->ifstate[LS->iflevel].skip;
170− next(LS); /* skip $ */
171− readname(LS, buff);
172− switch (luaL_findstring(buff, pragmas)) {
173− case 0: /* debug */
174− if (!skip) L->debug = 1;
175− break;
176− case 1: /* nodebug */
177− if (!skip) L->debug = 0;
178− break;
179− case 2: /* endinput */
180− if (!skip) {
181− LS->current = EOZ;
182− LS->iflevel = 0; /* to allow $endinput inside a $if */
183− }
184− break;
185− case 3: /* end */
186− if (LS->iflevel-- == 0)
187− luaX_syntaxerror(LS, "unmatched $end", "$end");
188− break;
189− case 4: /* ifnot */
190− ifnot = 1;
191− /* go through */
192− case 5: /* if */
193− if (LS->iflevel == MAX_IFS-1)
194− luaX_syntaxerror(LS, "too many nested $ifs", "$if");
195− readname(LS, buff);
196− LS->iflevel++;
197− LS->ifstate[LS->iflevel].elsepart = 0;
198− LS->ifstate[LS->iflevel].condition = checkcond(LS, buff) ? !ifnot : ifnot;
199− LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition;
200− break;
201− case 6: /* else */
202− if (LS->ifstate[LS->iflevel].elsepart)
203− luaX_syntaxerror(LS, "unmatched $else", "$else");
204− LS->ifstate[LS->iflevel].elsepart = 1;
205− LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip ||
206− LS->ifstate[LS->iflevel].condition;
207− break;
208− default:
209− luaX_syntaxerror(LS, "unknown pragma", buff);
158+ if (LS->current == '.') {
159+ save_and_next(L, LS, l);
160+ 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);
210165 }
211− skipspace(LS);
212− if (LS->current == '\n') /* pragma must end with a '\n' ... */
213− inclinenumber(LS);
214− else if (LS->current != EOZ) /* or eof */
215− luaX_syntaxerror(LS, "invalid pragma format", buff);
216− ifskip(LS);
217166 }
167+ while (isdigit(LS->current)) {
168+ checkbuffer(L, 10, l);
169+ save_and_next(L, LS, l);
170+ }
171+ if (LS->current == 'e' || LS->current == 'E') {
172+ save_and_next(L, LS, l); /* read 'E' */
173+ if (LS->current == '+' || LS->current == '-')
174+ save_and_next(L, LS, l); /* optional exponent sign */
175+ while (isdigit(LS->current)) {
176+ checkbuffer(L, 10, l);
177+ save_and_next(L, LS, l);
178+ }
179+ }
180+ save(L, '\0', l);
181+ if (!luaO_str2d(L->Mbuffer, &seminfo->r))
182+ luaX_error(LS, "malformed number", TK_NUMBER);
218183 }
219184
220185
221−
222−/*
223−** =======================================================
224−** LEXICAL ANALIZER
225−** =======================================================
226−*/
227−
228−
229−
230−static int read_long_string (LexState *LS) {
186+static void read_long_string (LexState *LS, SemInfo *seminfo) {
187+ lua_State *L = LS->L;
231188 int cont = 0;
189+ 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 '[' */
232193 for (;;) {
194+ checkbuffer(L, 10, l);
233195 switch (LS->current) {
234196 case EOZ:
235− luaX_error(LS, "unfinished long string");
236− return EOS; /* to avoid warnings */
197+ save(L, '\0', l);
198+ luaX_error(LS, "unfinished long string", TK_STRING);
199+ break; /* to avoid warnings */
237200 case '[':
238− save_and_next(LS);
201+ save_and_next(L, LS, l);
239202 if (LS->current == '[') {
240203 cont++;
241− save_and_next(LS);
204+ save_and_next(L, LS, l);
242205 }
243206 continue;
244207 case ']':
245− save_and_next(LS);
208+ save_and_next(L, LS, l);
246209 if (LS->current == ']') {
247210 if (cont == 0) goto endloop;
248211 cont--;
249− save_and_next(LS);
212+ save_and_next(L, LS, l);
250213 }
251214 continue;
252215 case '\n':
253− save('\n');
216+ save(L, '\n', l);
254217 inclinenumber(LS);
255218 continue;
256219 default:
257− save_and_next(LS);
220+ save_and_next(L, LS, l);
258221 }
259222 } endloop:
260− save_and_next(LS); /* skip the second ']' */
261− LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+2),
262− L->Mbuffnext-L->Mbuffbase-4);
263− return STRING;
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);
264226 }
265227
266228
267−int luaX_lex (LexState *LS) {
268− luaL_resetbuffer();
229+static void read_string (LexState *LS, int del, SemInfo *seminfo) {
230+ lua_State *L = LS->L;
231+ size_t l = 0;
232+ checkbuffer(L, 10, l);
233+ save_and_next(L, LS, l);
234+ while (LS->current != del) {
235+ checkbuffer(L, 10, l);
236+ switch (LS->current) {
237+ case EOZ: case '\n':
238+ save(L, '\0', l);
239+ luaX_error(LS, "unfinished string", TK_STRING);
240+ break; /* to avoid warnings */
241+ case '\\':
242+ next(LS); /* do not save the '\' */
243+ 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);
263+ }
264+ save(L, c, l);
265+ break;
266+ }
267+ default: /* handles \\, \", \', and \? */
268+ save_and_next(L, LS, l);
269+ }
270+ break;
271+ default:
272+ save_and_next(L, LS, l);
273+ }
274+ }
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);
278+}
279+
280+
281+int luaX_lex (LexState *LS, SemInfo *seminfo) {
269282 for (;;) {
270283 switch (LS->current) {
271284
272− case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
285+ case ' ': case '\t': case '\r': /* `\r' to avoid problems with DOS */
273286 next(LS);
274287 continue;
275288
@@ -277,159 +290,89 @@ int luaX_lex (LexState *LS) { · 1 unmodified line
277290 inclinenumber(LS);
278291 continue;
279292
293+ case '$':
294+ luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$');
295+ break;
296+
280297 case '-':
281− save_and_next(LS);
298+ next(LS);
282299 if (LS->current != '-') return '-';
283300 do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
284− luaL_resetbuffer();
285301 continue;
286302
287303 case '[':
288− save_and_next(LS);
304+ next(LS);
289305 if (LS->current != '[') return '[';
290306 else {
291− save_and_next(LS); /* pass the second '[' */
292− return read_long_string(LS);
307+ read_long_string(LS, seminfo);
308+ return TK_STRING;
293309 }
294310
295311 case '=':
296− save_and_next(LS);
312+ next(LS);
297313 if (LS->current != '=') return '=';
298− else { save_and_next(LS); return EQ; }
314+ else { next(LS); return TK_EQ; }
299315
300316 case '<':
301− save_and_next(LS);
317+ next(LS);
302318 if (LS->current != '=') return '<';
303− else { save_and_next(LS); return LE; }
319+ else { next(LS); return TK_LE; }
304320
305321 case '>':
306− save_and_next(LS);
322+ next(LS);
307323 if (LS->current != '=') return '>';
308− else { save_and_next(LS); return GE; }
324+ else { next(LS); return TK_GE; }
309325
310326 case '~':
311− save_and_next(LS);
327+ next(LS);
312328 if (LS->current != '=') return '~';
313− else { save_and_next(LS); return NE; }
329+ else { next(LS); return TK_NE; }
314330
315331 case '"':
316− case '\'': {
317− int del = LS->current;
318− save_and_next(LS);
319− while (LS->current != del) {
320− switch (LS->current) {
321− case EOZ:
322− case '\n':
323− luaX_error(LS, "unfinished string");
324− return EOS; /* to avoid warnings */
325− case '\\':
326− next(LS); /* do not save the '\' */
327− switch (LS->current) {
328− case 'a': save('\a'); next(LS); break;
329− case 'b': save('\b'); next(LS); break;
330− case 'f': save('\f'); next(LS); break;
331− case 'n': save('\n'); next(LS); break;
332− case 'r': save('\r'); next(LS); break;
333− case 't': save('\t'); next(LS); break;
334− case 'v': save('\v'); next(LS); break;
335− case '\n': save('\n'); inclinenumber(LS); break;
336− default : {
337− if (isdigit(LS->current)) {
338− int c = 0;
339− int i = 0;
340− do {
341− c = 10*c + (LS->current-'0');
342− next(LS);
343− } while (++i<3 && isdigit(LS->current));
344− if (c != (unsigned char)c)
345− luaX_error(LS, "escape sequence too large");
346− save(c);
347− }
348− else { /* handles \, ", ', and ? */
349− save(LS->current);
350− next(LS);
351− }
352− break;
353− }
354− }
355− break;
356− default:
357− save_and_next(LS);
358− }
359− }
360− save_and_next(LS); /* skip delimiter */
361− LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1),
362− L->Mbuffnext-L->Mbuffbase-2);
363− return STRING;
364− }
332+ case '\'':
333+ read_string(LS, LS->current, seminfo);
334+ return TK_STRING;
365335
366336 case '.':
367− save_and_next(LS);
368− if (LS->current == '.')
369− {
370− save_and_next(LS);
371− if (LS->current == '.')
372− {
373− save_and_next(LS);
374− return DOTS; /* ... */
337+ next(LS);
338+ if (LS->current == '.') {
339+ next(LS);
340+ if (LS->current == '.') {
341+ next(LS);
342+ return TK_DOTS; /* ... */
375343 }
376− else return CONC; /* .. */
344+ else return TK_CONCAT; /* .. */
377345 }
378346 else if (!isdigit(LS->current)) return '.';
379− goto fraction; /* LS->current is a digit: goes through to number */
347+ else {
348+ read_number(LS, 1, seminfo);
349+ return TK_NUMBER;
350+ }
380351
381352 case '0': case '1': case '2': case '3': case '4':
382353 case '5': case '6': case '7': case '8': case '9':
383− do {
384− save_and_next(LS);
385− } while (isdigit(LS->current));
386− if (LS->current == '.') {
387− save_and_next(LS);
388− if (LS->current == '.') {
389− save('.');
390− luaX_error(LS,
391− "ambiguous syntax (decimal point x string concatenation)");
392− }
393− }
394− fraction:
395− while (isdigit(LS->current))
396− save_and_next(LS);
397− if (toupper(LS->current) == 'E') {
398− save_and_next(LS); /* read 'E' */
399− save_and_next(LS); /* read '+', '-' or first digit */
400− while (isdigit(LS->current))
401− save_and_next(LS);
402− }
403− save('\0');
404− LS->seminfo.r = luaO_str2d(L->Mbuffer+L->Mbuffbase);
405− if (LS->seminfo.r < 0)
406− luaX_error(LS, "invalid numeric format");
407− return NUMBER;
354+ read_number(LS, 0, seminfo);
355+ return TK_NUMBER;
408356
409357 case EOZ:
410− if (LS->iflevel > 0)
411− luaX_error(LS, "input ends inside a $if");
412− return EOS;
358+ return TK_EOS;
359+
360+ case '_': goto tname;
413361
414362 default:
415− if (LS->current != '_' && !isalpha(LS->current)) {
363+ if (!isalpha(LS->current)) {
416364 int c = LS->current;
417365 if (iscntrl(c))
418366 luaX_invalidchar(LS, c);
419− save_and_next(LS);
367+ next(LS);
420368 return c;
421369 }
422− else { /* identifier or reserved word */
423− TaggedString *ts;
424− do {
425− save_and_next(LS);
426− } while (isalnum(LS->current) || LS->current == '_');
427− save('\0');
428− ts = luaS_new(L->Mbuffer+L->Mbuffbase);
429− if (ts->head.marked >= FIRST_RESERVED)
430− return ts->head.marked; /* reserved word */
431− LS->seminfo.ts = ts;
432− return NAME;
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;
374+ seminfo->ts = ts;
375+ return TK_NAME;
433376 }
434377 }
435378 }
src/llex.h+39−31
@@ -1,5 +1,5 @@
11 /*
2−** $Id: llex.h,v 1.12 1999/06/17 17:04:03 roberto Exp $
2+** $Id: llex.h,v 1.31 2000/09/27 17:41:58 roberto Exp $
33 ** Lexical Analyzer
44 ** See Copyright Notice in lua.h
55 */
@@ -11,53 +11,61 @@ · 5 unmodified lines
1111 #include "lzio.h"
1212
1313
14−#define FIRST_RESERVED 260
14+#define FIRST_RESERVED 257
1515
16−/* maximum length of a reserved word (+1 for terminal 0) */
16+/* maximum length of a reserved word (+1 for final 0) */
1717 #define TOKEN_LEN 15
1818
19+
20+/*
21+* WARNING: if you change the order of this enumeration,
22+* grep "ORDER RESERVED"
23+*/
1924 enum RESERVED {
2025 /* terminal symbols denoted by reserved words */
21− AND = FIRST_RESERVED,
22− DO, ELSE, ELSEIF, END, FUNCTION, IF, LOCAL, NIL, NOT, OR,
23− REPEAT, RETURN, THEN, UNTIL, WHILE,
26+ 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,
2429 /* other terminal symbols */
25− NAME, CONC, DOTS, EQ, GE, LE, NE, NUMBER, STRING, EOS};
30+ TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
31+ TK_STRING, TK_EOS
32+};
2633
34+/* number of reserved words */
35+#define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1))
2736
28−#ifndef MAX_IFS
29−#define MAX_IFS 5 /* arbitrary limit */
30−#endif
3137
32−/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
38+typedef union {
39+ Number r;
40+ TString *ts;
41+} SemInfo; /* semantics information */
3342
34−struct ifState {
35− int elsepart; /* true if it's in the $else part */
36− int condition; /* true if $if condition is true */
37− int skip; /* true if part must be skipped */
38−};
43+
44+typedef struct Token {
45+ int token;
46+ SemInfo seminfo;
47+} Token;
3948
4049
4150 typedef struct LexState {
42− int current; /* look ahead character */
43− int token; /* look ahead token */
44− struct FuncState *fs; /* 'FuncState' is private for the parser */
45− union {
46− real r;
47− TaggedString *ts;
48− } seminfo; /* semantics information */
49− struct zio *lex_z; /* input stream */
51+ int current; /* current character */
52+ Token t; /* current token */
53+ Token lookahead; /* look ahead token */
54+ struct FuncState *fs; /* `FuncState' is private to the parser */
55+ struct lua_State *L;
56+ struct zio *z; /* input stream */
5057 int linenumber; /* input line counter */
51− int iflevel; /* level of nested $if's (for lexical analysis) */
52− struct ifState ifstate[MAX_IFS];
58+ int lastline; /* line of last token `consumed' */
59+ TString *source; /* current source name */
5360 } LexState;
5461
5562
56−void luaX_init (void);
57−void luaX_setinput (LexState *LS, ZIO *z);
58−int luaX_lex (LexState *LS);
59−void luaX_syntaxerror (LexState *ls, char *s, char *token);
60−void luaX_error (LexState *ls, char *s);
63+void luaX_init (lua_State *L);
64+void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
65+int luaX_lex (LexState *LS, SemInfo *seminfo);
66+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);
6169 void luaX_token2str (int token, char *s);
6270
6371
src/llimits.h+204−0
@@ -0,0 +1,204 @@
1+/*
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
4+** See Copyright Notice in lua.h
5+*/
6+
7+#ifndef llimits_h
8+#define llimits_h
9+
10+
11+#include <limits.h>
12+#include <stddef.h>
13+
14+
15+
16+/*
17+** try to find number of bits in an integer
18+*/
19+#ifndef BITS_INT
20+/* avoid overflows in comparison */
21+#if INT_MAX-20 < 32760
22+#define BITS_INT 16
23+#else
24+#if INT_MAX > 2147483640L
25+/* machine has at least 32 bits */
26+#define BITS_INT 32
27+#else
28+#error "you must define BITS_INT with number of bits in an integer"
29+#endif
30+#endif
31+#endif
32+
33+
34+/*
35+** Define the type `number' of Lua
36+** GREP LUA_NUMBER to change that
37+*/
38+#ifndef LUA_NUM_TYPE
39+#define LUA_NUM_TYPE double
40+#endif
41+
42+typedef LUA_NUM_TYPE Number;
43+
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))
47+
48+/* function to convert a string to a Number */
49+#define lua_str2number(s,p) strtod((s), (p))
50+
51+
52+
53+typedef unsigned long lint32; /* unsigned int with at least 32 bits */
54+
55+
56+#define MAX_SIZET ((size_t)(~(size_t)0)-2)
57+
58+
59+#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
60+
61+/*
62+** conversion of pointer to int (for hashing only)
63+** (the shift removes bits that are usually 0 because of alignment)
64+*/
65+#define IntPoint(p) (((unsigned long)(p)) >> 3)
66+
67+
68+
69+#define MINPOWER2 4 /* minimum size for "growing" vectors */
70+
71+
72+
73+#ifndef DEFAULT_STACK_SIZE
74+#define DEFAULT_STACK_SIZE 1024
75+#endif
76+
77+
78+
79+/* type to ensure maximum alignment */
80+union L_Umaxalign { double d; char *s; long l; };
81+
82+
83+
84+/*
85+** type for virtual-machine instructions
86+** 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)
89+*/
90+typedef unsigned long Instruction;
91+
92+
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)
107+
108+
109+/*
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)
113+*/
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
121+
122+#if SIZE_A < BITS_INT-1
123+#define MAXARG_A ((1<<SIZE_A)-1)
124+#else
125+#define MAXARG_A MAX_INT
126+#endif
127+
128+#if SIZE_B < BITS_INT-1
129+#define MAXARG_B ((1<<SIZE_B)-1)
130+#else
131+#define MAXARG_B MAX_INT
132+#endif
133+
134+
135+/* maximum stack size in a function */
136+#ifndef MAXSTACK
137+#define MAXSTACK 250
138+#endif
139+
140+#if MAXSTACK > MAXARG_B
141+#undef MAXSTACK
142+#define MAXSTACK MAXARG_B
143+#endif
144+
145+
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)
153+#endif
154+
155+
156+/* maximum number of upvalues */
157+#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)
173+#endif
174+
175+
176+/* maximum number of parameters in a function */
177+#ifndef MAXPARAMS
178+#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
179+#endif
180+#if MAXPARAMS>=MAXLOCALS
181+#undef MAXPARAMS
182+#define MAXPARAMS (MAXLOCALS-1)
183+#endif
184+
185+
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)
191+#endif
192+
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)
196+
197+
198+/* maximum lookback to find a real constant (for code generation) */
199+#ifndef LOOKBACKNUMS
200+#define LOOKBACKNUMS 20 /* arbitrary constant */
201+#endif
202+
203+
204+#endif
src/lmem.c+94−84
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lmem.c,v 1.17 1999/05/24 17:51:05 roberto Exp $
2+** $Id: lmem.c,v 1.39 2000/10/30 16:29:59 roberto Exp $
33 ** Interface to Memory Manager
44 ** See Copyright Notice in lua.h
55 */
@@ -7,134 +7,144 @@ · 1 unmodified line
77
88 #include <stdlib.h>
99
10−#include "lmem.h"
11−#include "lstate.h"
1210 #include "lua.h"
1311
12+#include "ldo.h"
13+#include "lmem.h"
14+#include "lobject.h"
15+#include "lstate.h"
1416
15−/*
16−** real ANSI systems do not need these tests;
17−** but some systems (Sun OS) are not that ANSI...
18−*/
19−#ifdef OLD_ANSI
20−#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
21−#define free(b) if (b) (free)(b)
22−#endif
23−
24−
25−#define MINSIZE 8 /* minimum size for "growing" vectors */
26−
27−
28−
29−
30−static unsigned long power2 (unsigned long n) {
31− unsigned long p = MINSIZE;
32− while (p<=n) p<<=1;
33− return p;
34−}
35−
36−
37−void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
38− char *errormsg, unsigned long limit) {
39− unsigned long newn = nelems+inc;
40− if (newn >= limit) lua_error(errormsg);
41− if ((newn ^ nelems) <= nelems || /* still the same power of 2 limit? */
42− (nelems > 0 && newn < MINSIZE)) /* or block already is MINSIZE? */
43− return block; /* do not need to reallocate */
44− else /* it crossed a power of 2 boundary; grow to next power */
45− return luaM_realloc(block, power2(newn)*size);
46−}
4717
4818
49−#ifndef DEBUG
5019
20+#ifdef LUA_DEBUG
5121 /*
52−** generic allocation routine.
22+** {======================================================================
23+** Controlled version for realloc.
24+** =======================================================================
5325 */
54−void *luaM_realloc (void *block, unsigned long size) {
55− size_t s = (size_t)size;
56− if (s != size)
57− lua_error("memory allocation error: block too big");
58− if (size == 0) {
59− free(block); /* block may be NULL, that is OK for free */
60− return NULL;
61− }
62− block = realloc(block, s);
63− if (block == NULL)
64− lua_error(memEM);
65− return block;
66−}
6726
6827
28+#include <assert.h>
29+#include <limits.h>
30+#include <string.h>
6931
70−#else
71−/* DEBUG */
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)
7235
73−#include <string.h>
7436
37+/* ensures maximum alignment for HEADER */
38+#define HEADER (sizeof(union L_Umaxalign))
7539
76−#define HEADER (sizeof(double))
7740 #define MARKSIZE 16
78−
79−#define MARK 55
41+#define MARK 0x55 /* 01010101 (a nice pattern) */
8042
8143
8244 #define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
8345
84−unsigned long numblocks = 0;
85−unsigned long totalmem = 0;
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;
8650
8751
8852 static void *checkblock (void *block) {
89− if (block == NULL)
90− return NULL;
91− else {
92− unsigned long *b = blocksize(block);
93− unsigned long size = *b;
94− int i;
95− for (i=0;i<MARKSIZE;i++)
96− LUA_ASSERT(*(((char *)b)+HEADER+size+i) == MARK+i, "corrupted block");
97− numblocks--;
98− totalmem -= size;
99− return b;
100− }
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;
10161 }
10262
10363
10464 static void freeblock (void *block) {
105− if (block)
106− memset(block, -1, *blocksize(block)); /* erase block */
107− free(checkblock(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+ }
10871 }
10972
11073
111−void *luaM_realloc (void *block, unsigned long size) {
112− unsigned long realsize = HEADER+size+MARKSIZE;
113− if (realsize != (size_t)realsize)
114− lua_error("memory allocation error: block too big");
74+static void *debug_realloc (void *block, size_t size) {
11575 if (size == 0) {
11676 freeblock(block);
11777 return NULL;
11878 }
79+ else if (memdebug_total+size > memdebug_memlimit)
80+ return NULL; /* to test memory allocation errors */
11981 else {
120− char *newblock = malloc(realsize);
82+ size_t realsize = HEADER+size+MARKSIZE;
83+ char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
12184 int i;
85+ if (realsize < size) return NULL; /* overflow! */
86+ if (newblock == NULL) return NULL;
12287 if (block) {
123− unsigned long oldsize = *blocksize(block);
88+ size_t oldsize = *blocksize(block);
12489 if (oldsize > size) oldsize = size;
12590 memcpy(newblock+HEADER, block, oldsize);
12691 freeblock(block); /* erase (and check) old copy */
12792 }
128− if (newblock == NULL)
129− lua_error(memEM);
130− totalmem += size;
131− numblocks++;
93+ memdebug_total += size;
94+ if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total;
95+ memdebug_numblocks++;
13296 *(unsigned long *)newblock = size;
13397 for (i=0;i<MARKSIZE;i++)
134− *(newblock+HEADER+size+i) = MARK+i;
98+ *(newblock+HEADER+size+i) = (char)(MARK+i);
13599 return newblock+HEADER;
136100 }
137101 }
138102
139103
104+/* }====================================================================== */
105+#endif
106+
107+
108+
109+/*
110+** Real ISO (ANSI) systems do not need these tests;
111+** but some systems (Sun OS) are not that ISO...
112+*/
113+#ifdef OLD_ANSI
114+#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
115+#define free(b) if (b) (free)(b)
140116 #endif
117+
118+
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);
128+}
129+
130+
131+/*
132+** generic allocation routine.
133+*/
134+void *luaM_realloc (lua_State *L, void *block, lint32 size) {
135+ if (size == 0) {
136+ free(block); /* block may be NULL; that is OK for free */
137+ return NULL;
138+ }
139+ 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! */
146+ }
147+ return block;
148+}
149+
150+
src/lmem.h+23−22
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lmem.h,v 1.8 1999/02/26 15:48:55 roberto Exp $
2+** $Id: lmem.h,v 1.16 2000/10/30 16:29:59 roberto Exp $
33 ** Interface to Memory Manager
44 ** See Copyright Notice in lua.h
55 */
@@ -8,32 +8,33 @@ · 2 unmodified lines
88 #define lmem_h
99
1010
11−#include <stdlib.h>
11+#include <stddef.h>
1212
13−/* memory error messages */
14−#define codeEM "code size overflow"
15−#define constantEM "constant table overflow"
16−#define refEM "reference table overflow"
17−#define tableEM "table overflow"
18−#define memEM "not enough memory"
19−#define arrEM "internal array bigger than `int' limit"
13+#include "llimits.h"
14+#include "lua.h"
2015
21−void *luaM_realloc (void *oldblock, unsigned long size);
22−void *luaM_growaux (void *block, unsigned long nelems, int inc, int size,
23− char *errormsg, unsigned long limit);
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);
2420
25−#define luaM_free(b) luaM_realloc((b), 0)
26−#define luaM_malloc(t) luaM_realloc(NULL, (t))
27−#define luaM_new(t) ((t *)luaM_malloc(sizeof(t)))
28−#define luaM_newvector(n,t) ((t *)luaM_malloc((n)*sizeof(t)))
29−#define luaM_growvector(v,nelems,inc,t,e,l) \
30− ((v)=(t *)luaM_growaux(v,nelems,inc,sizeof(t),e,l))
31−#define luaM_reallocvector(v,n,t) ((v)=(t *)luaM_realloc(v,(n)*sizeof(t)))
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)))
3225
26+#define luaM_growvector(L, v,nelems,inc,t,e,l) \
27+ ((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l))
3328
34−#ifdef DEBUG
35−extern unsigned long numblocks;
36−extern unsigned long totalmem;
29+#define luaM_reallocvector(L, v,n,t) \
30+ ((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t)))
31+
32+
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;
3738 #endif
3839
3940
src/lobject.c+83−87
@@ -1,129 +1,125 @@
11 /*
2−** $Id: lobject.c,v 1.19 1999/04/13 19:28:49 roberto Exp $
2+** $Id: lobject.c,v 1.55 2000/10/20 16:36:32 roberto Exp $
33 ** Some generic functions over Lua objects
44 ** See Copyright Notice in lua.h
55 */
66
77 #include <ctype.h>
8+#include <stdarg.h>
9+#include <stdio.h>
810 #include <stdlib.h>
11+#include <string.h>
912
10−#include "lobject.h"
1113 #include "lua.h"
1214
15+#include "lmem.h"
16+#include "lobject.h"
17+#include "lstate.h"
1318
14−char *luaO_typenames[] = { /* ORDER LUA_T */
15− "userdata", "number", "string", "table", "function", "function",
16− "nil", "function", "mark", "mark", "mark", "line", NULL
17−};
1819
1920
20−TObject luaO_nilobject = {LUA_T_NIL, {NULL}};
21+const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
2122
2223
24+const char *const luaO_typenames[] = {
25+ "userdata", "nil", "number", "string", "table", "function"
26+};
2327
24−/* hash dimensions values */
25−static long dimensions[] =
26− {5L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L,
27− 12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L,
28− 1644817L, 3289613L, 6579211L, 13158023L, MAX_INT};
2928
3029
31−int luaO_redimension (int oldsize)
32−{
33− int i;
34− for (i=0; dimensions[i]<MAX_INT; i++) {
35− if (dimensions[i] > oldsize)
36− return dimensions[i];
37− }
38− lua_error("tableEM");
39− return 0; /* to avoid warnings */
30+/*
31+** returns smaller power of 2 larger than `n' (minimum is MINPOWER2)
32+*/
33+lint32 luaO_power2 (lint32 n) {
34+ lint32 p = MINPOWER2;
35+ while (p<=n) p<<=1;
36+ return p;
4037 }
4138
4239
43−int luaO_equalval (TObject *t1, TObject *t2) {
40+int luaO_equalObj (const TObject *t1, const TObject *t2) {
41+ if (ttype(t1) != ttype(t2)) return 0;
4442 switch (ttype(t1)) {
45− case LUA_T_NIL: return 1;
46− case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
47− case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
48− case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
49− case LUA_T_PROTO: return tfvalue(t1) == tfvalue(t2);
50− case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2);
51− case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl;
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);
5251 default:
53− LUA_INTERNALERROR("invalid type");
54− return 0; /* UNREACHABLE */
52+ LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type");
53+ return 1; /* LUA_TNIL */
5554 }
5655 }
5756
5857
59−void luaO_insertlist (GCnode *root, GCnode *node)
60−{
61− node->next = root->next;
62− root->next = node;
63− node->marked = 0;
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;
63+ }
64+ return L->Mbuffer;
6465 }
6566
6667
67−#ifdef OLD_ANSI
68−void luaO_memup (void *dest, void *src, int size) {
69− while (size--)
70− ((char *)dest)[size]=((char *)src)[size];
71−}
72−
73−void luaO_memdown (void *dest, void *src, int size) {
74− int i;
75− for (i=0; i<size; i++)
76− ((char *)dest)[i]=((char *)src)[i];
68+int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */
69+ char *endptr;
70+ Number res = lua_str2number(s, &endptr);
71+ if (endptr == s) return 0; /* no conversion */
72+ while (isspace((unsigned char)*endptr)) endptr++;
73+ if (*endptr != '\0') return 0; /* invalid trailing characters? */
74+ *result = res;
75+ return 1;
7776 }
78−#endif
7977
8078
79+/* maximum length of a string format for `luaO_verror' */
80+#define MAX_VERROR 280
8181
82−static double expten (unsigned int e) {
83− double exp = 10.0;
84− double res = 1.0;
85− for (; e; e>>=1) {
86− if (e & 1) res *= exp;
87− exp *= exp;
88− }
89− return res;
82+/* this function needs to handle only '%d' and '%.XXs' formats */
83+void luaO_verror (lua_State *L, const char *fmt, ...) {
84+ va_list argp;
85+ char buff[MAX_VERROR]; /* to hold formatted message */
86+ va_start(argp, fmt);
87+ vsprintf(buff, fmt, argp);
88+ va_end(argp);
89+ lua_error(L, buff);
9090 }
9191
9292
93−double luaO_str2d (char *s) { /* LUA_NUMBER */
94− double a = 0.0;
95− int point = 0;
96− while (isdigit((unsigned char)*s)) {
97− a = 10.0*a + (*(s++)-'0');
93+void luaO_chunkid (char *out, const char *source, int bufflen) {
94+ if (*source == '=') {
95+ strncpy(out, source+1, bufflen); /* remove first char */
96+ out[bufflen-1] = '\0'; /* ensures null termination */
9897 }
99− if (*s == '.') {
100− s++;
101− while (isdigit((unsigned char)*s)) {
102− a = 10.0*a + (*(s++)-'0');
103− point++;
98+ else {
99+ if (*source == '@') {
100+ int l;
101+ source++; /* skip the `@' */
102+ bufflen -= sizeof("file `...%s'");
103+ l = strlen(source);
104+ if (l>bufflen) {
105+ source += (l-bufflen); /* get last part of file name */
106+ sprintf(out, "file `...%.99s'", source);
107+ }
108+ else
109+ sprintf(out, "file `%.99s'", source);
104110 }
105− }
106− if (toupper((unsigned char)*s) == 'E') {
107− int e = 0;
108− int sig = 1;
109− s++;
110− if (*s == '-') {
111− s++;
112− sig = -1;
111+ else {
112+ int len = strcspn(source, "\n"); /* stop at first newline */
113+ bufflen -= sizeof("string \"%.*s...\"");
114+ if (len > bufflen) len = bufflen;
115+ if (source[len] != '\0') { /* must truncate? */
116+ strcpy(out, "string \"");
117+ out += strlen(out);
118+ strncpy(out, source, len);
119+ strcpy(out+len, "...\"");
120+ }
121+ else
122+ sprintf(out, "string \"%.99s\"", source);
113123 }
114− else if (*s == '+') s++;
115− if (!isdigit((unsigned char)*s)) return -1; /* no digit in the exponent? */
116− do {
117− e = 10*e + (*(s++)-'0');
118− } while (isdigit((unsigned char)*s));
119− point -= sig*e;
120124 }
121− while (isspace((unsigned char)*s)) s++;
122− if (*s != '\0') return -1; /* invalid trailing characters? */
123− if (point > 0)
124− a /= expten(point);
125− else if (point < 0)
126− a *= expten(-point);
127− return a;
128125 }
129−
src/lobject.h+125−125
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lobject.h,v 1.28 1999/03/16 16:43:27 roberto Exp $
2+** $Id: lobject.h,v 1.82 2000/10/30 17:49:19 roberto Exp $
33 ** Type definitions for Lua objects
44 ** See Copyright Notice in lua.h
55 */
@@ -8,197 +8,197 @@ · 2 unmodified lines
88 #define lobject_h
99
1010
11−#include <limits.h>
12−
11+#include "llimits.h"
1312 #include "lua.h"
1413
1514
16−#ifdef DEBUG
17−#include "lauxlib.h"
18−#define LUA_INTERNALERROR(s) \
19− luaL_verror("INTERNAL ERROR - %s [%s:%d]",(s),__FILE__,__LINE__)
20−#define LUA_ASSERT(c,s) { if (!(c)) LUA_INTERNALERROR(s); }
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)))
2120 #else
22−#define LUA_INTERNALERROR(s) /* empty */
23−#define LUA_ASSERT(c,s) /* empty */
21+#define LUA_INTERNALERROR(s) /* empty */
22+#define LUA_ASSERT(c,s) /* empty */
2423 #endif
2524
2625
27−/*
28−** "real" is the type "number" of Lua
29−** GREP LUA_NUMBER to change that
30−*/
31−#ifndef LUA_NUM_TYPE
32−#define LUA_NUM_TYPE double
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 */
3331 #endif
3432
3533
36−typedef LUA_NUM_TYPE real;
37−
38−#define Byte lua_Byte /* some systems have Byte as a predefined type */
39−typedef unsigned char Byte; /* unsigned 8 bits */
40−
34+/* mark for closures active in the stack */
35+#define LUA_TMARK 6
4136
42−#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
4337
44−typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
38+/* tags for values visible from Lua == first user-created tag */
39+#define NUM_TAGS 6
4540
4641
47−/*
48−** Lua TYPES
49−** WARNING: if you change the order of this enumeration,
50−** grep "ORDER LUA_T"
51−*/
52−typedef enum {
53− LUA_T_USERDATA = 0, /* tag default for userdata */
54− LUA_T_NUMBER = -1, /* fixed tag for numbers */
55− LUA_T_STRING = -2, /* fixed tag for strings */
56− LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */
57− LUA_T_PROTO = -4, /* fixed tag for functions */
58− LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */
59− LUA_T_NIL = -6, /* last "pre-defined" tag */
60− LUA_T_CLOSURE = -7,
61− LUA_T_CLMARK = -8, /* mark for closures */
62− LUA_T_PMARK = -9, /* mark for Lua prototypes */
63− LUA_T_CMARK = -10, /* mark for C prototypes */
64− LUA_T_LINE = -11
65−} lua_Type;
66−
67−#define NUM_TAGS 7
42+/* check whether `t' is a mark */
43+#define is_T_MARK(t) ((t) == LUA_TMARK)
6844
6945
7046 typedef union {
71− lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */
72− real n; /* LUA_T_NUMBER */
73− struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
74− struct TProtoFunc *tf; /* LUA_T_PROTO, LUA_T_PMARK */
75− struct Closure *cl; /* LUA_T_CLOSURE, LUA_T_CLMARK */
76− struct Hash *a; /* LUA_T_ARRAY */
77− int i; /* LUA_T_LINE */
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 */
7852 } Value;
7953
8054
81−typedef struct TObject {
82− lua_Type ttype;
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+
65+typedef struct lua_TObject {
66+ int ttype;
8367 Value value;
8468 } TObject;
8569
8670
87−
8871 /*
89−** generic header for garbage collector lists
72+** String headers for string table
9073 */
91−typedef struct GCnode {
92− struct GCnode *next;
93− int marked;
94−} GCnode;
95−
9674
9775 /*
98−** String headers for string table
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.
9979 */
80+#define TSPACK ((int)sizeof(int))
10081
101−typedef struct TaggedString {
102− GCnode head;
103− unsigned long hash;
104− int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
82+typedef struct TString {
10583 union {
106− struct {
107− TObject globalval;
108− long len; /* if this is a string, here is its length */
84+ struct { /* for strings */
85+ unsigned long hash;
86+ int constindex; /* hint to reuse constants */
10987 } s;
110− struct {
88+ struct { /* for userdata */
11189 int tag;
112− void *v; /* if this is a userdata, here is its value */
90+ void *value;
11391 } d;
11492 } u;
115− char str[1]; /* \0 byte already reserved */
116−} TaggedString;
117−
118−
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! */
97+} TString;
11998
12099
121100 /*
122101 ** Function Prototypes
123102 */
124−typedef struct TProtoFunc {
125− GCnode head;
126− struct TObject *consts;
127− int nconsts;
128− Byte *code; /* ends with opcode ENDCODE */
103+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' */
110+ 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 */
118+ int *lineinfo; /* map from opcodes to source lines */
119+ int nlineinfo; /* size of `lineinfo' */
120+ int nlocvars;
121+ struct LocVar *locvars; /* information about local variables */
129122 int lineDefined;
130− TaggedString *source;
131− struct LocVar *locvars; /* ends with line = -1 */
132−} TProtoFunc;
123+ TString *source;
124+} Proto;
125+
133126
134127 typedef struct LocVar {
135− TaggedString *varname; /* NULL signals end of scope */
136− int line;
128+ TString *varname;
129+ int startpc; /* first point where variable is active */
130+ int endpc; /* first point where variable is dead */
137131 } LocVar;
138132
139133
140−
141−
142−
143−/* Macros to access structure members */
144−#define ttype(o) ((o)->ttype)
145−#define nvalue(o) ((o)->value.n)
146−#define svalue(o) ((o)->value.ts->str)
147−#define tsvalue(o) ((o)->value.ts)
148−#define clvalue(o) ((o)->value.cl)
149−#define avalue(o) ((o)->value.a)
150−#define fvalue(o) ((o)->value.f)
151−#define tfvalue(o) ((o)->value.tf)
152−
153−#define protovalue(o) ((o)->value.cl->consts)
154−
155−
156134 /*
157135 ** Closures
158136 */
159137 typedef struct Closure {
160− GCnode head;
161− int nelems; /* not included the first one (always the prototype) */
162− TObject consts[1]; /* at least one for prototype */
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;
146+ TObject upvalue[1];
163147 } Closure;
164148
165149
150+#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
151+
166152
167−typedef struct node {
168− TObject ref;
153+typedef struct Node {
154+ TObject key;
169155 TObject val;
156+ struct Node *next; /* for chaining */
170157 } Node;
171158
172159 typedef struct Hash {
173− GCnode head;
174160 Node *node;
175− int nhash;
176− int nuse;
177161 int htag;
162+ int size;
163+ 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) */
178166 } Hash;
179167
180168
181−extern char *luaO_typenames[];
169+/* unmarked tables and closures are represented by pointing `mark' to
170+** themselves
171+*/
172+#define ismarked(x) ((x)->mark != (x))
173+
182174
183−#define luaO_typename(o) luaO_typenames[-ttype(o)]
175+/*
176+** informations about a call (for debugging)
177+*/
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;
184185
185186
186−extern TObject luaO_nilobject;
187+extern const TObject luaO_nilobject;
188+extern const char *const luaO_typenames[];
187189
188−#define luaO_equalObj(t1,t2) ((ttype(t1) != ttype(t2)) ? 0 \
189− : luaO_equalval(t1,t2))
190−int luaO_equalval (TObject *t1, TObject *t2);
191−int luaO_redimension (int oldsize);
192−void luaO_insertlist (GCnode *root, GCnode *node);
193−double luaO_str2d (char *s);
194190
195−#ifdef OLD_ANSI
196−void luaO_memup (void *dest, void *src, int size);
197−void luaO_memdown (void *dest, void *src, int size);
198−#else
199−#include <string.h>
200−#define luaO_memup(d,s,n) memmove(d,s,n)
201−#define luaO_memdown(d,s,n) memmove(d,s,n)
202−#endif
191+#define luaO_typename(o) (luaO_typenames[ttype(o)])
192+
193+
194+lint32 luaO_power2 (lint32 n);
195+char *luaO_openspace (lua_State *L, size_t n);
196+
197+int luaO_equalObj (const TObject *t1, const TObject *t2);
198+int luaO_str2d (const char *s, Number *result);
199+
200+void luaO_verror (lua_State *L, const char *fmt, ...);
201+void luaO_chunkid (char *out, const char *source, int len);
202+
203203
204204 #endif
src/lopcodes.h+120−90
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lopcodes.h,v 1.33 1999/06/17 17:04:03 roberto Exp $
2+** $Id: lopcodes.h,v 1.68 2000/10/24 16:05:59 roberto Exp $
33 ** Opcodes for Lua virtual machine
44 ** See Copyright Notice in lua.h
55 */
@@ -7,132 +7,162 @@ · 1 unmodified line
77 #ifndef lopcodes_h
88 #define lopcodes_h
99
10+#include "llimits.h"
1011
11−/*
12−** NOTICE: variants of the same opcode must be consecutive: First, those
13−** with word parameter, then with byte parameter.
14−*/
1512
13+/*===========================================================================
14+ 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')
1623
17−typedef enum {
18−/* name parm before after side effect
19−-----------------------------------------------------------------------------*/
20−ENDCODE,/* - - (return) */
21−RETCODE,/* b - (return) */
24+ A signed argument is represented in excess K; that is, the number
25+ value is the unsigned value minus K. K is exactly the maximum value
26+ for that argument (so that -max is represented by 0, and +max is
27+ represented by 2*max), which is half the maximum for the corresponding
28+ unsigned argument.
2229
23−CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
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.
35+===========================================================================*/
2436
25−TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
2637
27−PUSHNIL,/* b - nil_0...nil_b */
28−POP,/* b a_b...a_1 - */
2938
30−PUSHNUMBERW,/* w - (float)w */
31−PUSHNUMBER,/* b - (float)b */
3239
33−PUSHNUMBERNEGW,/* w - (float)-w */
34−PUSHNUMBERNEG,/* b - (float)-b */
40+/* creates a mask with `n' 1 bits at position `p' */
41+#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
3542
36−PUSHCONSTANTW,/*w - CNST[w] */
37−PUSHCONSTANT,/* b - CNST[b] */
43+/* creates a mask with `n' 0 bits at position `p' */
44+#define MASK0(n,p) (~MASK1(n,p))
3845
39−PUSHUPVALUE,/* b - Closure[b] */
46+/*
47+** the following macros help to manipulate instructions
48+*/
4049
41−PUSHLOCAL,/* b - LOC[b] */
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)))
4253
43−GETGLOBALW,/* w - VAR[CNST[w]] */
44−GETGLOBAL,/* b - VAR[CNST[b]] */
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)))
4558
46−GETTABLE,/* - i t t[i] */
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)
4762
48−GETDOTTEDW,/* w t t[CNST[w]] */
49−GETDOTTED,/* b t t[CNST[b]] */
5063
51−PUSHSELFW,/* w t t t[CNST[w]] */
52−PUSHSELF,/* b t t t[CNST[b]] */
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)))
5372
54−CREATEARRAYW,/* w - newarray(size = w) */
55−CREATEARRAY,/* b - newarray(size = b) */
5673
57−SETLOCAL,/* b x - LOC[b]=x */
74+/*
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'
79+*/
5880
59−SETGLOBALW,/* w x - VAR[CNST[w]]=x */
60−SETGLOBAL,/* b x - VAR[CNST[b]]=x */
81+typedef enum {
82+/*----------------------------------------------------------------------
83+name args stack before stack after side effects
84+------------------------------------------------------------------------*/
85+OP_END,/* - - (return) no results */
86+OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */
6187
62−SETTABLEPOP,/* - v i t - t[i]=v */
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) */
6390
64−SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
91+OP_PUSHNIL,/* U - nil_1-nil_u */
92+OP_POP,/* U a_u-a_1 - */
6593
66−SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */
67−SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */
94+OP_PUSHINT,/* S - (Number)s */
95+OP_PUSHSTRING,/* K - KSTR[k] */
96+OP_PUSHNUM,/* N - KNUM[n] */
97+OP_PUSHNEGNUM,/* N - -KNUM[n] */
6898
69−SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */
99+OP_PUSHUPVALUE,/* U - Closure[u] */
70100
71−NEQOP,/* - y x (x~=y)? 1 : nil */
72−EQOP,/* - y x (x==y)? 1 : nil */
73−LTOP,/* - y x (x<y)? 1 : nil */
74−LEOP,/* - y x (x<y)? 1 : nil */
75−GTOP,/* - y x (x>y)? 1 : nil */
76−GEOP,/* - y x (x>=y)? 1 : nil */
77−ADDOP,/* - y x x+y */
78−SUBOP,/* - y x x-y */
79−MULTOP,/* - y x x*y */
80−DIVOP,/* - y x x/y */
81−POWOP,/* - y x x^y */
82−CONCOP,/* - y x x..y */
83−MINUSOP,/* - x -x */
84−NOTOP,/* - x (x==nil)? 1 : nil */
101+OP_GETLOCAL,/* L - LOC[l] */
102+OP_GETGLOBAL,/* K - VAR[KSTR[k]] */
85103
86−ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
87−ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
88−ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
89−ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
90−JMPW,/* w - - PC+=w */
91−JMP,/* b - - PC+=b */
92−IFFJMPW,/* w x - (x==nil)? PC+=w */
93−IFFJMP,/* b x - (x==nil)? PC+=b */
94−IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
95−IFTUPJMP,/* b x - (x!=nil)? PC-=b */
96−IFFUPJMPW,/* w x - (x==nil)? PC-=w */
97−IFFUPJMP,/* b x - (x==nil)? PC-=b */
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]] */
98108
99−CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
100−CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
109+OP_CREATETABLE,/* U - newarray(size = u) */
101110
102−SETLINEW,/* w - - LINE=w */
103−SETLINE,/* b - - LINE=b */
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 */
104114
105−LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
106−LONGARG,/* b (add b*(1<<16) to arg of next instruction) */
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 */
107117
108−CHECKSTACK /* b (assert #temporaries == b; only for internal debuging!) */
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 */
109127
110−} OpCode;
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 */
111134
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 */
112140
113−#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
114−#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
141+OP_PUSHNILJMP,/* - - nil PC++; */
115142
116−#define ZEROVARARG 128
143+OP_FORPREP,/* J */
144+OP_FORLOOP,/* J */
117145
146+OP_LFORPREP,/* J */
147+OP_LFORLOOP,/* J */
118148
119−/* maximum value of an arg of 3 bytes; must fit in an "int" */
120−#if MAX_INT < (1<<24)
121−#define MAX_ARG MAX_INT
122−#else
123−#define MAX_ARG ((1<<24)-1)
124−#endif
149+OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
125150
126−/* maximum value of a word of 2 bytes; cannot be bigger than MAX_ARG */
127−#if MAX_ARG < (1<<16)
128−#define MAX_WORD MAX_ARG
129−#else
130−#define MAX_WORD ((1<<16)-1)
131−#endif
151+} OpCode;
152+
153+#define NUM_OPCODES ((int)OP_CLOSURE+1)
132154
133155
134−/* maximum value of a byte */
135−#define MAX_BYTE ((1<<8)-1)
156+#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)
157+
158+
159+
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
165+#endif
136166
137167
138168 #endif
src/lparser.c+822−1090
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lparser.c,v 1.37a 1999/06/17 17:04:03 roberto Exp $
2+** $Id: lparser.c,v 1.116 2000/10/27 11:39:52 roberto Exp $
33 ** LL(1) Parser and code generator for Lua
44 ** See Copyright Notice in lua.h
55 */
@@ -8,1385 +8,1117 @@ · 2 unmodified lines
88 #include <stdio.h>
99 #include <string.h>
1010
11−#include "lauxlib.h"
12−#include "ldo.h"
11+#include "lua.h"
12+
13+#include "lcode.h"
1314 #include "lfunc.h"
1415 #include "llex.h"
1516 #include "lmem.h"
17+#include "lobject.h"
1618 #include "lopcodes.h"
1719 #include "lparser.h"
1820 #include "lstate.h"
1921 #include "lstring.h"
20−#include "lua.h"
21−#include "luadebug.h"
22−#include "lzio.h"
23−
24−
25−
26−/* size of a "normal" jump instruction: OpCode + 1 byte */
27−#define JMPSIZE 2
28−
29−/* maximum number of local variables */
30−#ifndef MAXLOCALS
31−#define MAXLOCALS 200 /* arbitrary limit (<256) */
32−#endif
33−
34−
35−/* maximum number of upvalues */
36−#ifndef MAXUPVALUES
37−#define MAXUPVALUES 32 /* arbitrary limit (<256) */
38−#endif
39−
40−
41−/* maximum number of variables in the left side of an assignment */
42−#ifndef MAXVARSLH
43−#define MAXVARSLH 100 /* arbitrary limit (<255) */
44−#endif
45−
46−
47−/* maximum number of parameters in a function */
48−#ifndef MAXPARAMS
49−#define MAXPARAMS 100 /* arbitrary limit (<ZEROVARARG) */
50−#endif
51−
52−
53−/*
54−** Variable descriptor:
55−** must include an "exp" option because LL(1) cannot distinguish
56−** between variables, upvalues and function calls on first sight.
57−*/
58−typedef enum {
59− VGLOBAL, /* info is constant index of global name */
60− VLOCAL, /* info is stack index */
61− VDOT, /* info is constant index of index name */
62− VINDEXED, /* no info (table and index are on the stack) */
63− VEXP /* info is pc index of "nparam" of a call (or 0 if exp is closed) */
64−} varkind;
65−
66−typedef struct vardesc {
67− varkind k;
68− int info;
69−} vardesc;
70−
71−
72−/*
73−** Expression List descriptor:
74−** tells number of expressions in the list,
75−** and, if last expression is open (a function call),
76−** where is its pc index of "nparam"
77−*/
78−typedef struct listdesc {
79− int n;
80− int pc; /* 0 if last expression is closed */
81−} listdesc;
8222
8323
8424 /*
8525 ** Constructors descriptor:
86−** "n" indicates number of elements, and "k" signals whether
26+** `n' indicates number of elements, and `k' signals whether
8727 ** it is a list constructor (k = 0) or a record constructor (k = 1)
8828 ** or empty (k = ';' or '}')
8929 */
90−typedef struct constdesc {
30+typedef struct Constdesc {
9131 int n;
9232 int k;
93−} constdesc;
33+} Constdesc;
34+
35+
36+typedef struct Breaklabel {
37+ struct Breaklabel *previous; /* chain */
38+ int breaklist;
39+ int stacklevel;
40+} Breaklabel;
9441
9542
96−/* state needed to generate code for a given function */
97−typedef struct FuncState {
98− TProtoFunc *f; /* current function header */
99− struct FuncState *prev; /* enclosuring function */
100− int pc; /* next position to code */
101− int stacksize; /* number of values on activation register */
102− int maxstacksize; /* maximum number of values on activation register */
103− int nlocalvar; /* number of active local variables */
104− int nupvalues; /* number of upvalues */
105− int nvars; /* number of entries in f->locvars (-1 if no debug information) */
106− int lastsetline; /* line where last SETLINE was issued */
107− vardesc upvalues[MAXUPVALUES]; /* upvalues */
108− TaggedString *localvar[MAXLOCALS]; /* store local variable names */
109−} FuncState;
11043
11144
11245 /*
113−** prototypes for non-terminal functions
46+** prototypes for recursive non-terminal functions
11447 */
115−static int assignment (LexState *ls, vardesc *v, int nvars);
116−static int cond (LexState *ls);
117−static int funcname (LexState *ls, vardesc *v);
118−static int funcparams (LexState *ls, int slf);
119−static int listfields (LexState *ls);
120−static int localnamelist (LexState *ls);
121−static int optional (LexState *ls, int c);
122−static int recfields (LexState *ls);
123−static int stat (LexState *ls);
124−static void block (LexState *ls);
12548 static void body (LexState *ls, int needself, int line);
12649 static void chunk (LexState *ls);
12750 static void constructor (LexState *ls);
128−static void decinit (LexState *ls, listdesc *d);
129−static void exp0 (LexState *ls, vardesc *v);
51+static void expr (LexState *ls, expdesc *v);
13052 static void exp1 (LexState *ls);
131−static void exp2 (LexState *ls, vardesc *v);
132−static void explist (LexState *ls, listdesc *e);
133−static void explist1 (LexState *ls, listdesc *e);
134−static void ifpart (LexState *ls, int line);
135−static void parlist (LexState *ls);
136−static void part (LexState *ls, constdesc *cd);
137−static void recfield (LexState *ls);
138−static void ret (LexState *ls);
139−static void statlist (LexState *ls);
140−static void var_or_func (LexState *ls, vardesc *v);
141−static void var_or_func_tail (LexState *ls, vardesc *v);
142−
143−
144−
145−static void checklimit (LexState *ls, int val, int limit, char *msg) {
146− if (val > limit) {
147− char buff[100];
148− sprintf(buff, "too many %s (limit=%d)", msg, limit);
149− luaX_error(ls, buff);
150− }
151−}
152−
15353
154−static void check_pc (FuncState *fs, int n) {
155− luaM_growvector(fs->f->code, fs->pc, n, Byte, codeEM, MAX_INT);
156−}
157−
158−
159−static void code_byte (FuncState *fs, Byte c) {
160− check_pc(fs, 1);
161− fs->f->code[fs->pc++] = c;
162−}
163−
164−
165−static void deltastack (LexState *ls, int delta) {
166− FuncState *fs = ls->fs;
167− fs->stacksize += delta;
168− if (fs->stacksize > fs->maxstacksize) {
169− if (fs->stacksize > MAX_BYTE)
170− luaX_error(ls, "function/expression too complex");
171− fs->maxstacksize = fs->stacksize;
172− }
173−}
17454
17555
176−static void code_oparg_at (LexState *ls, int pc, OpCode op,
177− int arg, int delta) {
178− Byte *code = ls->fs->f->code;
179− deltastack(ls, delta);
180− if (arg <= MAX_BYTE) {
181− code[pc] = (Byte)op;
182− code[pc+1] = (Byte)arg;
183− }
184− else if (arg > MAX_ARG)
185− luaX_error(ls, "code too long");
186− else { /* MAX_BYTE < arg < MAX_ARG */
187− if (arg > MAX_WORD) {
188− code[pc] = (Byte)LONGARG;
189− code[pc+1] = (Byte)(arg>>16);
190− pc += 2;
191− }
192− code[pc] = (Byte)(op-1); /* opcode for word argument */
193− code[pc+1] = (Byte)((arg&0xFFFF)>>8);
194− code[pc+2] = (Byte)(arg&0xFF);
56+static void next (LexState *ls) {
57+ ls->lastline = ls->linenumber;
58+ if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
59+ ls->t = ls->lookahead; /* use this one */
60+ ls->lookahead.token = TK_EOS; /* and discharge it */
19561 }
62+ else
63+ ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */
19664 }
19765
19866
199−static int codesize (int arg) {
200− if (arg <= MAX_BYTE) return 2; /* opcode + 1 byte */
201− else if (arg <= MAX_WORD) return 3; /* opcode + 1 word (2 bytes) */
202− else return 5; /* LONGARG + 1 byte + opcode + 1 word (2 bytes) */
67+static void lookahead (LexState *ls) {
68+ LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads");
69+ ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
20370 }
20471
20572
206−static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) {
207− int tomove = codesize(arg)-2;
208− if (tomove > 0) { /* need to open space? */
209− FuncState *fs = ls->fs;
210− TProtoFunc *f = fs->f;
211− check_pc(fs, tomove);
212− luaO_memup(f->code+pc+tomove, f->code+pc, fs->pc-pc);
213− fs->pc += tomove;
214− }
215− code_oparg_at(ls, pc, op, arg, 0);
216− return tomove;
73+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);
21778 }
21879
21980
220−static void code_oparg (LexState *ls, OpCode op, int arg, int delta) {
221− int size = codesize(arg);
222− check_pc(ls->fs, size);
223− code_oparg_at(ls, ls->fs->pc, op, arg, delta);
224− ls->fs->pc += size;
81+static void check (LexState *ls, int c) {
82+ if (ls->t.token != c)
83+ error_expected(ls, c);
84+ next(ls);
22585 }
22686
22787
228−static void code_opcode (LexState *ls, OpCode op, int delta) {
229− deltastack(ls, delta);
230− code_byte(ls->fs, (Byte)op);
88+static void check_condition (LexState *ls, int c, const char *msg) {
89+ if (!c) luaK_error(ls, msg);
23190 }
23291
23392
234−static void code_constant (LexState *ls, int c) {
235− code_oparg(ls, PUSHCONSTANT, c, 1);
93+static int optional (LexState *ls, int c) {
94+ if (ls->t.token == c) {
95+ next(ls);
96+ return 1;
97+ }
98+ else return 0;
23699 }
237100
238101
239−static int next_constant (FuncState *fs) {
240− TProtoFunc *f = fs->f;
241− luaM_growvector(f->consts, f->nconsts, 1, TObject, constantEM, MAX_ARG);
242− return f->nconsts++;
102+static void check_match (LexState *ls, int what, int who, int where) {
103+ if (ls->t.token != what) {
104+ if (where == ls->linenumber)
105+ error_expected(ls, what);
106+ 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);
114+ }
115+ }
116+ next(ls);
243117 }
244118
245119
246−static int string_constant (FuncState *fs, TaggedString *s) {
247− TProtoFunc *f = fs->f;
248− int c = s->constindex;
249− if (!(c < f->nconsts &&
250− ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) {
251− c = next_constant(fs);
252− ttype(&f->consts[c]) = LUA_T_STRING;
253− tsvalue(&f->consts[c]) = s;
254− s->constindex = c; /* hint for next time */
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 */
255129 }
256130 return c;
257131 }
258132
259133
260−static void code_string (LexState *ls, TaggedString *s) {
261− code_constant(ls, string_constant(ls->fs, s));
262−}
263−
264−
265−#define LIM 20
266−static int real_constant (FuncState *fs, real r) {
267− /* check whether 'r' has appeared within the last LIM entries */
268− TObject *cnt = fs->f->consts;
269− int c = fs->f->nconsts;
270− int lim = c < LIM ? 0 : c-LIM;
271− while (--c >= lim) {
272− if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r)
273− return c;
274− }
275− /* not found; create a new entry */
276− c = next_constant(fs);
277− cnt = fs->f->consts; /* 'next_constant' may have reallocated this vector */
278− ttype(&cnt[c]) = LUA_T_NUMBER;
279− nvalue(&cnt[c]) = r;
280− return c;
134+static void code_string (LexState *ls, TString *s) {
135+ luaK_kstr(ls, string_constant(ls->fs, s));
281136 }
282137
283138
284−static void code_number (LexState *ls, real f) {
285− real af = (f<0) ? -f : f;
286− if (0 <= af && af <= (real)MAX_WORD && (int)af == af) {
287− /* abs(f) has a short integer value */
288− code_oparg(ls, (f<0) ? PUSHNUMBERNEG : PUSHNUMBER, (int)af, 1);
289− }
290− else
291− code_constant(ls, real_constant(ls->fs, f));
139+static TString *str_checkname (LexState *ls) {
140+ TString *ts;
141+ check_condition(ls, (ls->t.token == TK_NAME), "<name> expected");
142+ ts = ls->t.seminfo.ts;
143+ next(ls);
144+ return ts;
292145 }
293146
294147
295−static void flush_record (LexState *ls, int n) {
296− if (n > 0)
297− code_oparg(ls, SETMAP, n-1, -2*n);
148+static int checkname (LexState *ls) {
149+ return string_constant(ls->fs, str_checkname(ls));
298150 }
299151
300152
301−static void flush_list (LexState *ls, int m, int n) {
302− if (n > 0) {
303− code_oparg(ls, SETLIST, m, -n);
304− code_byte(ls->fs, (Byte)n);
305− }
153+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++;
306158 }
307159
308160
309−static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname,
310− int line) {
311− if (fs->nvars != -1) { /* debug information? */
312− TProtoFunc *f = fs->f;
313− luaM_growvector(f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
314− f->locvars[fs->nvars].varname = varname;
315− f->locvars[fs->nvars].line = line;
316− fs->nvars++;
317− }
161+static void new_localvar (LexState *ls, TString *name, int n) {
162+ 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);
318165 }
319166
320167
321−static void luaI_unregisterlocalvar (FuncState *fs, int line) {
322− luaI_registerlocalvar(fs, NULL, line);
168+static void adjustlocalvars (LexState *ls, int nvars) {
169+ FuncState *fs = ls->fs;
170+ while (nvars--)
171+ fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc;
323172 }
324173
325174
326−static void store_localvar (LexState *ls, TaggedString *name, int n) {
175+static void removelocalvars (LexState *ls, int nvars) {
327176 FuncState *fs = ls->fs;
328− checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables");
329− fs->localvar[fs->nlocalvar+n] = name;
330− luaI_registerlocalvar(fs, name, ls->linenumber);
177+ while (nvars--)
178+ fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
331179 }
332180
333181
334−static void add_localvar (LexState *ls, TaggedString *name) {
335− store_localvar(ls, name, 0);
336− ls->fs->nlocalvar++;
182+static void new_localvarstr (LexState *ls, const char *name, int n) {
183+ new_localvar(ls, luaS_newfixed(ls->L, name), n);
337184 }
338185
339186
340−static void correctvarlines (LexState *ls, int nvars) {
341− FuncState *fs = ls->fs;
342− if (fs->nvars != -1) { /* debug information? */
343− for (; nvars; nvars--) { /* correct line information */
344− fs->f->locvars[fs->nvars-nvars].line = fs->lastsetline;
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+ }
345198 }
199+ level++; /* `var' not found; check outer level */
346200 }
201+ var->k = VGLOBAL; /* not found in any level; must be global */
202+ return -1;
347203 }
348204
349205
350−static int aux_localname (FuncState *fs, TaggedString *n) {
351− int i;
352− for (i=fs->nlocalvar-1; i >= 0; i--)
353− if (n == fs->localvar[i]) return i; /* local var index */
354− return -1; /* not found */
355−}
356−
357−
358−static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) {
359− FuncState *fs = prev ? ls->fs->prev : ls->fs;
360− int i = aux_localname(fs, n);
361− if (i >= 0) { /* local value? */
362− var->k = VLOCAL;
363− var->info = i;
364− }
365− else {
366− FuncState *level = fs;
367− while ((level = level->prev) != NULL) /* check shadowing */
368− if (aux_localname(level, n) >= 0)
369− luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str);
370− var->k = VGLOBAL;
371− var->info = string_constant(fs, n);
372− }
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);
373212 }
374213
375214
376−static int indexupvalue (LexState *ls, TaggedString *n) {
215+static int indexupvalue (LexState *ls, expdesc *v) {
377216 FuncState *fs = ls->fs;
378− vardesc v;
379217 int i;
380− singlevar(ls, n, &v, 1);
381218 for (i=0; i<fs->nupvalues; i++) {
382− if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info)
219+ if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index)
383220 return i;
384221 }
385222 /* new one */
386− ++(fs->nupvalues);
387− checklimit(ls, fs->nupvalues, MAXUPVALUES, "upvalues");
388− fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */
389− return i;
390−}
391−
392−
393−static void pushupvalue (LexState *ls, TaggedString *n) {
394− if (ls->fs->prev == NULL)
395− luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
396− if (aux_localname(ls->fs, n) >= 0)
397− luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
398− code_oparg(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
399−}
400−
401−
402−
403−static void check_debugline (LexState *ls) {
404− if (L->debug && ls->linenumber != ls->fs->lastsetline) {
405− code_oparg(ls, SETLINE, ls->linenumber, 0);
406− ls->fs->lastsetline = ls->linenumber;
407− }
408−}
409−
410−
411−static void adjuststack (LexState *ls, int n) {
412− if (n > 0)
413− code_oparg(ls, POP, n, -n);
414− else if (n < 0)
415− code_oparg(ls, PUSHNIL, (-n)-1, -n);
223+ luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues");
224+ fs->upvalues[fs->nupvalues] = *v;
225+ return fs->nupvalues++;
416226 }
417227
418228
419−static void close_exp (LexState *ls, int pc, int nresults) {
420− if (pc > 0) { /* expression is an open function call? */
421− Byte *code = ls->fs->f->code;
422− code[pc-1] = (Byte)nresults; /* set nresults */
423− /* push results, pop params (at code[pc]) and function */
424− deltastack(ls, nresults-(code[pc]+1));
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);
425237 }
426−#ifdef DEBUG
427− code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
428−#endif
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));
429242 }
430243
431244
432−static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
433− int diff = d->n - nvars;
434− if (d->pc == 0) { /* list is closed */
435− /* push or pop eventual difference between list lengths */
436− adjuststack(ls, diff);
437− }
438− else { /* must correct function call */
245+static void adjust_mult_assign (LexState *ls, int nvars, int nexps) {
246+ FuncState *fs = ls->fs;
247+ int diff = nexps - nvars;
248+ if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */
439249 diff--; /* do not count function call itself */
440250 if (diff <= 0) { /* more variables than values? */
441− /* function call must provide extra values */
442− close_exp(ls, d->pc, -diff);
443− }
444− else { /* more values than variables */
445− close_exp(ls, d->pc, 0); /* call should provide no value */
446− adjuststack(ls, diff); /* pop eventual extra values */
251+ luaK_setcallreturns(fs, -diff); /* function call provide extra values */
252+ diff = 0; /* no more difference */
447253 }
254+ else /* more values than variables */
255+ luaK_setcallreturns(fs, 0); /* call should provide no value */
448256 }
257+ /* push or pop eventual difference between list lengths */
258+ luaK_adjuststack(fs, diff);
449259 }
450260
451261
452−static void code_args (LexState *ls, int nparams, int dots) {
262+static void code_params (LexState *ls, int nparams, int dots) {
453263 FuncState *fs = ls->fs;
454− fs->nlocalvar += nparams; /* "self" may already be there */
455− checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
456− nparams = fs->nlocalvar;
457− if (!dots) {
458− fs->f->code[1] = (Byte)nparams; /* fill-in arg information */
459− deltastack(ls, nparams);
460− }
461− else {
462− fs->f->code[1] = (Byte)(nparams+ZEROVARARG);
463− deltastack(ls, nparams+1);
464− add_localvar(ls, luaS_new("arg"));
465− }
466−}
467−
468−
469−static void unloaddot (LexState *ls, vardesc *v) {
470− /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */
471− if (v->k == VDOT) {
472− code_constant(ls, v->info);
473− v->k = VINDEXED;
474− }
475−}
476−
477−
478−static void lua_pushvar (LexState *ls, vardesc *var) {
479− switch (var->k) {
480− case VLOCAL:
481− code_oparg(ls, PUSHLOCAL, var->info, 1);
482− break;
483− case VGLOBAL:
484− code_oparg(ls, GETGLOBAL, var->info, 1);
485− break;
486− case VDOT:
487− code_oparg(ls, GETDOTTED, var->info, 0);
488− break;
489− case VINDEXED:
490− code_opcode(ls, GETTABLE, -1);
491− break;
492− case VEXP:
493− close_exp(ls, var->info, 1); /* function must return 1 value */
494− break;
495− }
496− var->k = VEXP;
497− var->info = 0; /* now this is a closed expression */
498−}
499−
500−
501−static void storevar (LexState *ls, vardesc *var) {
502− switch (var->k) {
503− case VLOCAL:
504− code_oparg(ls, SETLOCAL, var->info, -1);
505− break;
506− case VGLOBAL:
507− code_oparg(ls, SETGLOBAL, var->info, -1);
508− break;
509− case VINDEXED:
510− code_opcode(ls, SETTABLEPOP, -3);
511− break;
512− default:
513− LUA_INTERNALERROR("invalid var kind to store");
264+ 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);
514271 }
272+ luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */
515273 }
516274
517275
518−static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
519− /* jump is relative to position following jump instruction */
520− return fix_opcode(ls, pc, op, n-(pc+JMPSIZE));
521−}
522−
523−
524−static void fix_upjmp (LexState *ls, OpCode op, int pos) {
525− int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */
526− code_oparg(ls, op, delta+(codesize(delta)-2), 0);
276+static void enterbreak (FuncState *fs, Breaklabel *bl) {
277+ bl->stacklevel = fs->stacklevel;
278+ bl->breaklist = NO_JUMP;
279+ bl->previous = fs->bl;
280+ fs->bl = bl;
527281 }
528282
529283
530−static void codeIf (LexState *ls, int thenAdd, int elseAdd) {
531− FuncState *fs = ls->fs;
532− int elseinit = elseAdd+JMPSIZE;
533− if (fs->pc == elseinit) { /* no else part? */
534− fs->pc -= JMPSIZE;
535− elseinit = fs->pc;
536− }
537− else
538− elseinit += fix_jump(ls, elseAdd, JMP, fs->pc);
539− fix_jump(ls, thenAdd, IFFJMP, elseinit);
284+static void leavebreak (FuncState *fs, Breaklabel *bl) {
285+ fs->bl = bl->previous;
286+ LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels");
287+ luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
540288 }
541289
542290
543−static void func_onstack (LexState *ls, FuncState *func) {
291+static void pushclosure (LexState *ls, FuncState *func) {
544292 FuncState *fs = ls->fs;
293+ Proto *f = fs->f;
545294 int i;
546− int c = next_constant(fs);
547− ttype(&fs->f->consts[c]) = LUA_T_PROTO;
548− fs->f->consts[c].value.tf = func->f;
549− if (func->nupvalues == 0)
550− code_constant(ls, c);
551− else {
552− for (i=0; i<func->nupvalues; i++)
553− lua_pushvar(ls, &func->upvalues[i]);
554− deltastack(ls, 1); /* CLOSURE puts one extra element (before poping) */
555− code_oparg(ls, CLOSURE, c, -func->nupvalues);
556− code_byte(fs, (Byte)func->nupvalues);
557− }
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);
558301 }
559302
560303
561−static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
562− TProtoFunc *f = luaF_newproto();
304+static void open_func (LexState *ls, FuncState *fs) {
305+ Proto *f = luaF_newproto(ls->L);
563306 fs->prev = ls->fs; /* linked list of funcstates */
307+ fs->ls = ls;
308+ fs->L = ls->L;
564309 ls->fs = fs;
565− fs->stacksize = 0;
566− fs->maxstacksize = 0;
567− fs->nlocalvar = 0;
310+ fs->stacklevel = 0;
311+ fs->nactloc = 0;
568312 fs->nupvalues = 0;
569− fs->lastsetline = 0;
313+ fs->bl = NULL;
570314 fs->f = f;
571− f->source = source;
315+ f->source = ls->source;
572316 fs->pc = 0;
317+ fs->lasttarget = 0;
318+ fs->lastline = 0;
319+ fs->jlt = NO_JUMP;
573320 f->code = NULL;
574− fs->nvars = (L->debug) ? 0 : -1; /* flag no debug information? */
575− code_byte(fs, 0); /* to be filled with maxstacksize */
576− code_byte(fs, 0); /* to be filled with arg information */
577− /* push function (to avoid GC) */
578− tfvalue(L->stack.top) = f; ttype(L->stack.top) = LUA_T_PROTO;
579− incr_top;
321+ f->maxstacksize = 0;
322+ f->numparams = 0; /* default for main chunk */
323+ f->is_vararg = 0; /* default for main chunk */
580324 }
581325
582326
583327 static void close_func (LexState *ls) {
328+ lua_State *L = ls->L;
584329 FuncState *fs = ls->fs;
585− TProtoFunc *f = fs->f;
586− code_opcode(ls, ENDCODE, 0);
587− f->code[0] = (Byte)fs->maxstacksize;
588− luaM_reallocvector(f->code, fs->pc, Byte);
589− luaM_reallocvector(f->consts, f->nconsts, TObject);
590− if (fs->nvars != -1) { /* debug information? */
591− luaI_registerlocalvar(fs, NULL, -1); /* flag end of vector */
592− luaM_reallocvector(f->locvars, fs->nvars, LocVar);
593− }
330+ 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 */
594342 ls->fs = fs->prev;
595− L->stack.top--; /* pop function */
596−}
597−
598−
599−
600−static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME,
601− LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0};
602−
603−
604−static int is_in (int tok, int *toks) {
605− int *t;
606− for (t=toks; *t; t++)
607− if (*t == tok) return t-toks;
608− return -1;
609−}
610−
611−
612−static void next (LexState *ls) {
613− ls->token = luaX_lex(ls);
614−}
615−
616−
617−static void error_expected (LexState *ls, int token) {
618− char buff[100], t[TOKEN_LEN];
619− luaX_token2str(token, t);
620− sprintf(buff, "`%s' expected", t);
621− luaX_error(ls, buff);
622−}
623−
624−
625−static void error_unexpected (LexState *ls) {
626− luaX_error(ls, "unexpected token");
627−}
628−
629−
630−static void error_unmatched (LexState *ls, int what, int who, int where) {
631− if (where == ls->linenumber)
632− error_expected(ls, what);
633− else {
634− char buff[100];
635− char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
636− luaX_token2str(what, t_what);
637− luaX_token2str(who, t_who);
638− sprintf(buff, "`%s' expected (to close `%s' at line %d)",
639− t_what, t_who, where);
640− luaX_error(ls, buff);
641− }
642−}
643−
644−static void check (LexState *ls, int c) {
645− if (ls->token != c)
646− error_expected(ls, c);
647− next(ls);
648−}
649−
650−static void check_match (LexState *ls, int what, int who, int where) {
651− if (ls->token != what)
652− error_unmatched(ls, what, who, where);
653− check_debugline(ls); /* to 'mark' the 'what' */
654− next(ls);
655−}
656−
657−static int checkname (LexState *ls) {
658− int sc;
659− if (ls->token != NAME)
660− luaX_error(ls, "`NAME' expected");
661− sc = string_constant(ls->fs, ls->seminfo.ts);
662− next(ls);
663− return sc;
664−}
665−
666−
667−static TaggedString *str_checkname (LexState *ls) {
668− int i = checkname(ls); /* this call may realloc `f->consts' */
669− return tsvalue(&ls->fs->f->consts[i]);
670−}
671−
672−
673−static int optional (LexState *ls, int c) {
674− if (ls->token == c) {
675− next(ls);
676− return 1;
677− }
678− else return 0;
343+ LUA_ASSERT(fs->bl == NULL, "wrong list end");
679344 }
680345
681346
682−TProtoFunc *luaY_parser (ZIO *z) {
347+Proto *luaY_parser (lua_State *L, ZIO *z) {
683348 struct LexState lexstate;
684349 struct FuncState funcstate;
685− luaX_setinput(&lexstate, z);
686− init_state(&lexstate, &funcstate, luaS_new(zname(z)));
350+ luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
351+ open_func(&lexstate, &funcstate);
687352 next(&lexstate); /* read first token */
688353 chunk(&lexstate);
689− if (lexstate.token != EOS)
690− luaX_error(&lexstate, "<eof> expected");
354+ check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
691355 close_func(&lexstate);
356+ LUA_ASSERT(funcstate.prev == NULL, "wrong list end");
357+ LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main");
692358 return funcstate.f;
693359 }
694360
695361
696362
697363 /*============================================================*/
698−/* GRAMAR RULES */
364+/* GRAMMAR RULES */
699365 /*============================================================*/
700366
701−static void chunk (LexState *ls) {
702− /* chunk -> statlist ret */
703− statlist(ls);
704− ret(ls);
705−}
706367
707−static void statlist (LexState *ls) {
708− /* statlist -> { stat [;] } */
709− while (stat(ls)) {
710− LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar,
711− "stack size != # local vars");
712− optional(ls, ';');
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++;
713378 }
379+ luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */
380+ return n;
714381 }
715382
716−static int stat (LexState *ls) {
717− int line = ls->linenumber; /* may be needed for error messages */
718− FuncState *fs = ls->fs;
719− switch (ls->token) {
720− case IF: /* stat -> IF ifpart END */
721− ifpart(ls, line);
722− return 1;
723383
724− case WHILE: { /* stat -> WHILE cond DO block END */
725− TProtoFunc *f = fs->f;
726− int while_init = fs->pc;
727− int cond_end, cond_size;
384+static void funcargs (LexState *ls, int slf) {
385+ 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;
728391 next(ls);
729− cond_end = cond(ls);
730− check(ls, DO);
731− block(ls);
732− check_match(ls, END, WHILE, line);
733− cond_size = cond_end-while_init;
734− check_pc(fs, cond_size);
735− memcpy(f->code+fs->pc, f->code+while_init, cond_size);
736− luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init);
737− while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size);
738− fix_upjmp(ls, IFTUPJMP, while_init);
739− return 1;
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;
740402 }
741−
742− case DO: { /* stat -> DO block END */
743− next(ls);
744− block(ls);
745− check_match(ls, END, DO, line);
746− return 1;
403+ case '{': { /* funcargs -> constructor */
404+ constructor(ls);
405+ break;
747406 }
748−
749− case REPEAT: { /* stat -> REPEAT block UNTIL exp1 */
750− int repeat_init = fs->pc;
407+ case TK_STRING: { /* funcargs -> STRING */
408+ code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */
751409 next(ls);
752− block(ls);
753− check_match(ls, UNTIL, REPEAT, line);
754− exp1(ls);
755− fix_upjmp(ls, IFFUPJMP, repeat_init);
756− deltastack(ls, -1); /* pops condition */
757− return 1;
410+ break;
758411 }
759−
760− case FUNCTION: { /* stat -> FUNCTION funcname body */
761− int needself;
762− vardesc v;
763− if (ls->fs->prev) /* inside other function? */
764− return 0;
765− check_debugline(ls);
766− next(ls);
767− needself = funcname(ls, &v);
768− body(ls, needself, line);
769− storevar(ls, &v);
770− return 1;
412+ default: {
413+ luaK_error(ls, "function arguments expected");
414+ break;
771415 }
416+ }
417+ fs->stacklevel = slevel; /* call will remove function and arguments */
418+ luaK_code2(fs, OP_CALL, slevel, MULT_RET);
419+}
772420
773− case LOCAL: { /* stat -> LOCAL localnamelist decinit */
774− listdesc d;
775− int nvars;
776− check_debugline(ls);
777− next(ls);
778− nvars = localnamelist(ls);
779− decinit(ls, &d);
780− fs->nlocalvar += nvars;
781− correctvarlines(ls, nvars); /* vars will be alive only after decinit */
782− adjust_mult_assign(ls, nvars, &d);
783− return 1;
784− }
785421
786− case NAME: case '%': { /* stat -> func | ['%'] NAME assignment */
787− vardesc v;
788− check_debugline(ls);
789− var_or_func(ls, &v);
790− if (v.k == VEXP) { /* stat -> func */
791− if (v.info == 0) /* is just an upper value? */
792− luaX_error(ls, "syntax error");
793− close_exp(ls, v.info, 0);
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;
794431 }
795− else { /* stat -> ['%'] NAME assignment */
796− int left = assignment(ls, &v, 1);
797− adjuststack(ls, left); /* remove eventual 'garbage' left on stack */
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, ']');
438+ break;
798439 }
799− return 1;
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;
449+ break;
450+ }
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;
456+ break;
457+ }
458+ default: return; /* should be follow... */
800459 }
460+ }
461+}
801462
802− case RETURN: case ';': case ELSE: case ELSEIF:
803− case END: case UNTIL: case EOS: /* 'stat' follow */
804− return 0;
805463
806− default:
807− error_unexpected(ls);
808− return 0; /* to avoid warnings */
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;
809470 }
471+ else /* variable name */
472+ singlevar(ls, str_checkname(ls), v);
473+ var_or_func_tail(ls, v);
810474 }
811475
812−static int SaveWord (LexState *ls) {
813− int res = ls->fs->pc;
814− check_pc(ls->fs, JMPSIZE);
815− ls->fs->pc += JMPSIZE; /* open space */
816− return res;
817−}
818476
819−static int SaveWordPop (LexState *ls) {
820− deltastack(ls, -1); /* pop condition */
821− return SaveWord(ls);
822−}
823477
824−static int cond (LexState *ls) {
825− /* cond -> exp1 */
826− exp1(ls);
827− return SaveWordPop(ls);
828−}
478+/*
479+** {======================================================================
480+** Rules for Constructors
481+** =======================================================================
482+*/
829483
830−static void block (LexState *ls) {
831− /* block -> chunk */
832− FuncState *fs = ls->fs;
833− int nlocalvar = fs->nlocalvar;
834− chunk(ls);
835− adjuststack(ls, fs->nlocalvar - nlocalvar);
836− for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--)
837− luaI_unregisterlocalvar(fs, fs->lastsetline);
838−}
839484
840−static int funcname (LexState *ls, vardesc *v) {
841− /* funcname -> NAME [':' NAME | '.' NAME] */
842− int needself = 0;
843− singlevar(ls, str_checkname(ls), v, 0);
844− if (ls->token == ':' || ls->token == '.') {
845− needself = (ls->token == ':');
846− next(ls);
847− lua_pushvar(ls, v);
848− code_constant(ls, checkname(ls));
849− v->k = VINDEXED;
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");
850499 }
851− return needself;
852−}
853−
854−static void body (LexState *ls, int needself, int line) {
855− /* body -> '(' parlist ')' chunk END */
856− FuncState newfs;
857− init_state(ls, &newfs, ls->fs->f->source);
858− newfs.f->lineDefined = line;
859− check(ls, '(');
860− if (needself)
861− add_localvar(ls, luaS_new("self"));
862− parlist(ls);
863− check(ls, ')');
864− chunk(ls);
865− check_match(ls, END, FUNCTION, line);
866− close_func(ls);
867− func_onstack(ls, &newfs);
500+ check(ls, '=');
501+ exp1(ls);
868502 }
869503
870504
871−static void ifpart (LexState *ls, int line) {
872− /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
873− int c;
874− int e;
875− next(ls); /* skip IF or ELSEIF */
876− c = cond(ls);
877− check(ls, THEN);
878− block(ls);
879− e = SaveWord(ls);
880− if (ls->token == ELSEIF)
881− ifpart(ls, line);
882− else {
883− if (optional(ls, ELSE))
884− block(ls);
885− check_match(ls, END, IF, line);
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);
886518 }
887− codeIf(ls, c, e);
519+ luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH);
520+ return n;
888521 }
889522
890523
891−static void ret (LexState *ls) {
892− /* ret -> [RETURN explist sc] */
893− if (optional(ls, RETURN)) {
894− listdesc e;
895− check_debugline(ls);
896− explist(ls, &e);
897− if (e.pc > 0) { /* expression is an open function call? */
898− Byte *code = ls->fs->f->code;
899− code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */
900− code[e.pc-1] = (Byte)ls->fs->nlocalvar;
901− }
902− else
903− code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
904− ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
905− optional(ls, ';');
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);
534+ 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);
906539 }
540+ luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
541+ return n;
907542 }
908543
909544
910−/*
911−** For parsing expressions, we use a classic stack with priorities.
912−** Each binary operator is represented by its index in "binop" + FIRSTBIN
913−** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1.
914−*/
915−
916−#define INDNOT 0
917−#define INDMINUS 1
918−
919−/* code of first binary operator */
920−#define FIRSTBIN 2
921−
922−/* code for power operator (last operator)
923−** '^' needs special treatment because it is right associative
924−*/
925−#define POW 13
926−
927−static int binop [] = {EQ, NE, '>', '<', LE, GE, CONC,
928− '+', '-', '*', '/', '^', 0};
929−
930−static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
931−
932−static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP,
933− LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP};
934−
935−#define MAXOPS 20 /* op's stack size (arbitrary limit) */
936545
937−typedef struct stack_op {
938− int ops[MAXOPS];
939− int top;
940−} stack_op;
941−
942−
943−static void exp1 (LexState *ls) {
944− vardesc v;
945− exp0(ls, &v);
946− lua_pushvar(ls, &v);
947− if (is_in(ls->token, expfollow) < 0)
948− luaX_error(ls, "ill-formed expression");
546+static void constructor_part (LexState *ls, Constdesc *cd) {
547+ switch (ls->t.token) {
548+ case ';': case '}': { /* constructor_part -> empty */
549+ cd->n = 0;
550+ cd->k = ls->t.token;
551+ break;
552+ }
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 */
562+ break;
563+ }
564+ default: { /* constructor_part -> listfields */
565+ case_default:
566+ cd->n = listfields(ls);
567+ cd->k = 0; /* list */
568+ break;
569+ }
570+ }
949571 }
950572
951573
952−static void exp0 (LexState *ls, vardesc *v) {
953− /* exp0 -> exp2 {(AND | OR) exp2} */
954− exp2(ls, v);
955− while (ls->token == AND || ls->token == OR) {
956− int op = (ls->token == AND) ? ONFJMP : ONTJMP;
957− int pc;
958− lua_pushvar(ls, v);
959− next(ls);
960− pc = SaveWordPop(ls);
961− exp2(ls, v);
962− lua_pushvar(ls, v);
963− fix_jump(ls, pc, op, ls->fs->pc);
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;
964589 }
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 */
965593 }
966594
595+/* }====================================================================== */
967596
968−static void push (LexState *ls, stack_op *s, int op) {
969− if (s->top >= MAXOPS)
970− luaX_error(ls, "expression too complex");
971− s->ops[s->top++] = op;
972−}
973597
974598
975−static void pop_to (LexState *ls, stack_op *s, int prio) {
976− int op;
977− while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) {
978− code_opcode(ls, opcodes[op], op<FIRSTBIN?0:-1);
979− s->top--;
980− }
981−}
982599
983−static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
984− check_debugline(ls);
985− switch (ls->token) {
986− case NUMBER: { /* simpleexp -> NUMBER */
987− real r = ls->seminfo.r;
600+/*
601+** {======================================================================
602+** Expression parsing
603+** =======================================================================
604+*/
605+
606+
607+static void simpleexp (LexState *ls, expdesc *v) {
608+ FuncState *fs = ls->fs;
609+ switch (ls->t.token) {
610+ case TK_NUMBER: { /* simpleexp -> NUMBER */
611+ Number r = ls->t.seminfo.r;
988612 next(ls);
989− /* dirty trick: check whether it is a -NUMBER not followed by '^' */
990− /* (because the priority of '^' is closer than '-'...) */
991− if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') {
992− s->top--; /* remove '-' from stack */
993− r = -r;
994− }
995− code_number(ls, r);
613+ luaK_number(fs, r);
996614 break;
997615 }
998−
999− case STRING: /* simpleexp -> STRING */
1000− code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before "next" */
616+ case TK_STRING: { /* simpleexp -> STRING */
617+ code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */
1001618 next(ls);
1002619 break;
1003−
1004− case NIL: /* simpleexp -> NIL */
1005− adjuststack(ls, -1);
620+ }
621+ case TK_NIL: { /* simpleexp -> NIL */
622+ luaK_adjuststack(fs, -1);
1006623 next(ls);
1007624 break;
1008−
1009− case '{': /* simpleexp -> constructor */
625+ }
626+ case '{': { /* simpleexp -> constructor */
1010627 constructor(ls);
1011628 break;
1012−
1013− case FUNCTION: /* simpleexp -> FUNCTION body */
629+ }
630+ case TK_FUNCTION: { /* simpleexp -> FUNCTION body */
1014631 next(ls);
1015632 body(ls, 0, ls->linenumber);
1016633 break;
1017−
1018− case '(': /* simpleexp -> '(' exp0 ')' */
634+ }
635+ case '(': { /* simpleexp -> '(' expr ')' */
1019636 next(ls);
1020− exp0(ls, v);
637+ expr(ls, v);
1021638 check(ls, ')');
1022639 return;
1023−
1024− case NAME: case '%':
640+ }
641+ case TK_NAME: case '%': {
1025642 var_or_func(ls, v);
1026643 return;
1027−
1028− default:
1029− luaX_error(ls, "<expression> expected");
644+ }
645+ default: {
646+ luaK_error(ls, "<expression> expected");
1030647 return;
648+ }
1031649 }
1032− v->k = VEXP; v->info = 0;
650+ v->k = VEXP;
651+ v->u.l.t = v->u.l.f = NO_JUMP;
1033652 }
1034653
1035654
1036−static void prefixexp (LexState *ls, vardesc *v, stack_op *s) {
1037− /* prefixexp -> {NOT | '-'} simpleexp */
1038− while (ls->token == NOT || ls->token == '-') {
1039− push(ls, s, (ls->token==NOT)?INDNOT:INDMINUS);
1040− next(ls);
1041− }
1042− simpleexp(ls, v, s);
655+static void exp1 (LexState *ls) {
656+ expdesc v;
657+ expr(ls, &v);
658+ luaK_tostack(ls, &v, 1);
1043659 }
1044660
1045661
1046−static void exp2 (LexState *ls, vardesc *v) {
1047− stack_op s;
1048− int op;
1049− s.top = 0;
1050− prefixexp(ls, v, &s);
1051− while ((op = is_in(ls->token, binop)) >= 0) {
1052− op += FIRSTBIN;
1053− lua_pushvar(ls, v);
1054− /* '^' is right associative, so must 'simulate' a higher priority */
1055− pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
1056− push(ls, &s, op);
1057− next(ls);
1058− prefixexp(ls, v, &s);
1059− lua_pushvar(ls, v);
1060− }
1061− if (s.top > 0) {
1062− lua_pushvar(ls, v);
1063− pop_to(ls, &s, 0);
662+static UnOpr getunopr (int op) {
663+ switch (op) {
664+ case TK_NOT: return OPR_NOT;
665+ case '-': return OPR_MINUS;
666+ default: return OPR_NOUNOPR;
1064667 }
1065668 }
1066669
1067670
1068−static void var_or_func (LexState *ls, vardesc *v) {
1069− /* var_or_func -> ['%'] NAME var_or_func_tail */
1070− if (optional(ls, '%')) { /* upvalue? */
1071− pushupvalue(ls, str_checkname(ls));
1072− v->k = VEXP;
1073− v->info = 0; /* closed expression */
671+static BinOpr getbinopr (int op) {
672+ switch (op) {
673+ case '+': return OPR_ADD;
674+ case '-': return OPR_SUB;
675+ case '*': return OPR_MULT;
676+ case '/': return OPR_DIV;
677+ case '^': return OPR_POW;
678+ case TK_CONCAT: return OPR_CONCAT;
679+ case TK_NE: return OPR_NE;
680+ case TK_EQ: return OPR_EQ;
681+ case '<': return OPR_LT;
682+ case TK_LE: return OPR_LE;
683+ case '>': return OPR_GT;
684+ case TK_GE: return OPR_GE;
685+ case TK_AND: return OPR_AND;
686+ case TK_OR: return OPR_OR;
687+ default: return OPR_NOBINOPR;
1074688 }
1075− else /* variable name */
1076− singlevar(ls, str_checkname(ls), v, 0);
1077− var_or_func_tail(ls, v);
1078689 }
1079690
1080691
1081−static void var_or_func_tail (LexState *ls, vardesc *v) {
1082− for (;;) {
1083− switch (ls->token) {
1084− case '.': /* var_or_func_tail -> '.' NAME */
1085− next(ls);
1086− lua_pushvar(ls, v); /* 'v' must be on stack */
1087− v->k = VDOT;
1088− v->info = checkname(ls);
1089− break;
1090−
1091− case '[': /* var_or_func_tail -> '[' exp1 ']' */
1092− next(ls);
1093− lua_pushvar(ls, v); /* 'v' must be on stack */
1094− exp1(ls);
1095− check(ls, ']');
1096− v->k = VINDEXED;
1097− break;
692+static const struct {
693+ char left; /* left priority for each binary operator */
694+ char right; /* right priority */
695+} 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 */
701+};
1098702
1099− case ':': /* var_or_func_tail -> ':' NAME funcparams */
1100− next(ls);
1101− lua_pushvar(ls, v); /* 'v' must be on stack */
1102− code_oparg(ls, PUSHSELF, checkname(ls), 1);
1103− v->k = VEXP;
1104− v->info = funcparams(ls, 1);
1105− break;
703+#define UNARY_PRIORITY 7 /* priority for unary operators */
1106704
1107− case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */
1108− lua_pushvar(ls, v); /* 'v' must be on stack */
1109− v->k = VEXP;
1110− v->info = funcparams(ls, 0);
1111− break;
1112705
1113− default: return; /* should be follow... */
1114− }
706+/*
707+** subexpr -> (simplexep | unop subexpr) { binop subexpr }
708+** where `binop' is any binary operator with a priority higher than `limit'
709+*/
710+static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
711+ BinOpr op;
712+ UnOpr uop = getunopr(ls->t.token);
713+ if (uop != OPR_NOUNOPR) {
714+ next(ls);
715+ subexpr(ls, v, UNARY_PRIORITY);
716+ luaK_prefix(ls, uop, v);
1115717 }
718+ else simpleexp(ls, v);
719+ /* expand while operators have priorities higher than `limit' */
720+ op = getbinopr(ls->t.token);
721+ while (op != OPR_NOBINOPR && priority[op].left > limit) {
722+ expdesc v2;
723+ BinOpr nextop;
724+ next(ls);
725+ luaK_infix(ls, op, v);
726+ /* read sub-expression with higher priority */
727+ nextop = subexpr(ls, &v2, priority[op].right);
728+ luaK_posfix(ls, op, v, &v2);
729+ op = nextop;
730+ }
731+ return op; /* return first untreated operator */
1116732 }
1117733
1118−static int funcparams (LexState *ls, int slf) {
1119− FuncState *fs = ls->fs;
1120− int nparams = 1; /* in cases STRING and constructor */
1121− switch (ls->token) {
1122− case '(': { /* funcparams -> '(' explist ')' */
1123− int line = ls->linenumber;
1124− listdesc e;
1125− next(ls);
1126− explist(ls, &e);
1127− check_match(ls, ')', '(', line);
1128− close_exp(ls, e.pc, 1);
1129− nparams = e.n;
1130− break;
1131− }
1132734
1133− case '{': /* funcparams -> constructor */
1134− constructor(ls);
1135− break;
735+static void expr (LexState *ls, expdesc *v) {
736+ subexpr(ls, v, -1);
737+}
1136738
1137− case STRING: /* funcparams -> STRING */
1138− code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before "next" */
1139− next(ls);
1140− break;
739+/* }==================================================================== */
740+
741+
742+/*
743+** {======================================================================
744+** Rules for Statements
745+** =======================================================================
746+*/
1141747
1142− default:
1143− luaX_error(ls, "function arguments expected");
1144− break;
1145− }
1146− code_byte(fs, CALL);
1147− code_byte(fs, 0); /* save space for nresult */
1148− code_byte(fs, (Byte)(nparams+slf));
1149− return fs->pc-1;
1150−}
1151−
1152−static void explist (LexState *ls, listdesc *d) {
1153− switch (ls->token) {
1154− case ELSE: case ELSEIF: case END: case UNTIL:
1155− case EOS: case ';': case ')':
1156− d->pc = 0;
1157− d->n = 0;
1158− break;
1159748
1160− default:
1161− explist1(ls, d);
749+static int block_follow (int token) {
750+ switch (token) {
751+ case TK_ELSE: case TK_ELSEIF: case TK_END:
752+ case TK_UNTIL: case TK_EOS:
753+ return 1;
754+ default: return 0;
1162755 }
1163756 }
1164757
1165−static void explist1 (LexState *ls, listdesc *d) {
1166− vardesc v;
1167− exp0(ls, &v);
1168− d->n = 1;
1169− while (ls->token == ',') {
1170− d->n++;
1171− lua_pushvar(ls, &v);
758+
759+static void block (LexState *ls) {
760+ /* block -> chunk */
761+ FuncState *fs = ls->fs;
762+ int nactloc = fs->nactloc;
763+ chunk(ls);
764+ luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */
765+ removelocalvars(ls, fs->nactloc - nactloc);
766+}
767+
768+
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;
1172774 next(ls);
1173− exp0(ls, &v);
775+ var_or_func(ls, &nv);
776+ check_condition(ls, (nv.k != VEXP), "syntax error");
777+ left = assignment(ls, &nv, nvars+1);
778+ }
779+ else { /* assignment -> '=' explist1 */
780+ int nexps;
781+ check(ls, '=');
782+ nexps = explist1(ls);
783+ adjust_mult_assign(ls, nvars, nexps);
1174784 }
1175− if (v.k == VEXP)
1176− d->pc = v.info;
1177− else {
1178− lua_pushvar(ls, &v);
1179− d->pc = 0;
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;
1180790 }
791+ return left;
1181792 }
1182793
1183−static void parlist (LexState *ls) {
1184− int nparams = 0;
1185− int dots = 0;
1186− switch (ls->token) {
1187− case DOTS: /* parlist -> DOTS */
1188− next(ls);
1189− dots = 1;
1190− break;
1191794
1192− case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */
1193− init:
1194− store_localvar(ls, str_checkname(ls), nparams++);
1195− if (ls->token == ',') {
1196− next(ls);
1197− switch (ls->token) {
1198− case DOTS: /* tailparlist -> DOTS */
1199− next(ls);
1200− dots = 1;
1201− break;
795+static void cond (LexState *ls, expdesc *v) {
796+ /* cond -> exp */
797+ expr(ls, v); /* read condition */
798+ luaK_goiftrue(ls->fs, v, 0);
799+}
1202800
1203− case NAME: /* tailparlist -> NAME [',' tailparlist] */
1204− goto init;
1205801
1206− default: luaX_error(ls, "NAME or `...' expected");
1207− }
1208− }
1209− break;
802+static void whilestat (LexState *ls, int line) {
803+ /* whilestat -> WHILE cond DO block END */
804+ FuncState *fs = ls->fs;
805+ int while_init = luaK_getlabel(fs);
806+ expdesc v;
807+ Breaklabel bl;
808+ enterbreak(fs, &bl);
809+ next(ls);
810+ cond(ls, &v);
811+ check(ls, TK_DO);
812+ block(ls);
813+ luaK_patchlist(fs, luaK_jump(fs), while_init);
814+ luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
815+ check_match(ls, TK_END, TK_WHILE, line);
816+ leavebreak(fs, &bl);
817+}
1210818
1211− case ')': break; /* parlist -> empty */
1212819
1213− default: luaX_error(ls, "NAME or `...' expected");
1214− }
1215− code_args(ls, nparams, dots);
820+static void repeatstat (LexState *ls, int line) {
821+ /* repeatstat -> REPEAT block UNTIL cond */
822+ FuncState *fs = ls->fs;
823+ int repeat_init = luaK_getlabel(fs);
824+ expdesc v;
825+ Breaklabel bl;
826+ enterbreak(fs, &bl);
827+ next(ls);
828+ block(ls);
829+ check_match(ls, TK_UNTIL, TK_REPEAT, line);
830+ cond(ls, &v);
831+ luaK_patchlist(fs, v.u.l.f, repeat_init);
832+ leavebreak(fs, &bl);
1216833 }
1217834
1218−static int localnamelist (LexState *ls) {
1219− /* localnamelist -> NAME {',' NAME} */
1220− int i = 1;
1221− store_localvar(ls, str_checkname(ls), 0);
1222− while (ls->token == ',') {
1223− next(ls);
1224− store_localvar(ls, str_checkname(ls), i++);
835+
836+static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
837+ /* forbody -> DO block END */
838+ FuncState *fs = ls->fs;
839+ int prep = luaK_code1(fs, prepfor, NO_JUMP);
840+ int blockinit = luaK_getlabel(fs);
841+ check(ls, TK_DO);
842+ adjustlocalvars(ls, nvar); /* scope for control variables */
843+ 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);
847+}
848+
849+
850+static void fornum (LexState *ls, TString *varname) {
851+ /* fornum -> NAME = exp1,exp1[,exp1] forbody */
852+ FuncState *fs = ls->fs;
853+ check(ls, '=');
854+ exp1(ls); /* initial value */
855+ check(ls, ',');
856+ exp1(ls); /* limit */
857+ if (optional(ls, ','))
858+ 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);
865+}
866+
867+
868+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);
883+}
884+
885+
886+static void forstat (LexState *ls, int line) {
887+ /* forstat -> fornum | forlist */
888+ FuncState *fs = ls->fs;
889+ TString *varname;
890+ Breaklabel bl;
891+ enterbreak(fs, &bl);
892+ next(ls); /* skip `for' */
893+ varname = str_checkname(ls); /* first variable name */
894+ switch (ls->t.token) {
895+ case '=': fornum(ls, varname); break;
896+ case ',': forlist(ls, varname); break;
897+ default: luaK_error(ls, "`=' or `,' expected");
1225898 }
1226− return i;
899+ check_match(ls, TK_END, TK_FOR, line);
900+ leavebreak(fs, &bl);
1227901 }
1228902
1229−static void decinit (LexState *ls, listdesc *d) {
1230− /* decinit -> ['=' explist1] */
1231− if (ls->token == '=') {
1232− next(ls);
1233− explist1(ls, d);
903+
904+static void test_then_block (LexState *ls, expdesc *v) {
905+ /* test_then_block -> [IF | ELSEIF] cond THEN block */
906+ next(ls); /* skip IF or ELSEIF */
907+ cond(ls, v);
908+ check(ls, TK_THEN);
909+ block(ls); /* `then' part */
910+}
911+
912+
913+static void ifstat (LexState *ls, int line) {
914+ /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
915+ FuncState *fs = ls->fs;
916+ expdesc v;
917+ int escapelist = NO_JUMP;
918+ test_then_block(ls, &v); /* IF cond THEN block */
919+ while (ls->t.token == TK_ELSEIF) {
920+ luaK_concat(fs, &escapelist, luaK_jump(fs));
921+ luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
922+ test_then_block(ls, &v); /* ELSEIF cond THEN block */
1234923 }
1235− else {
1236− d->n = 0;
1237− d->pc = 0;
924+ if (ls->t.token == TK_ELSE) {
925+ luaK_concat(fs, &escapelist, luaK_jump(fs));
926+ luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
927+ next(ls); /* skip ELSE */
928+ block(ls); /* `else' part */
1238929 }
930+ else
931+ luaK_concat(fs, &escapelist, v.u.l.f);
932+ luaK_patchlist(fs, escapelist, luaK_getlabel(fs));
933+ check_match(ls, TK_END, TK_IF, line);
934+}
935+
936+
937+static void localstat (LexState *ls) {
938+ /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */
939+ int nvars = 0;
940+ int nexps;
941+ do {
942+ next(ls); /* skip LOCAL or ',' */
943+ new_localvar(ls, str_checkname(ls), nvars++);
944+ } while (ls->t.token == ',');
945+ if (optional(ls, '='))
946+ nexps = explist1(ls);
947+ else
948+ nexps = 0;
949+ adjust_mult_assign(ls, nvars, nexps);
950+ adjustlocalvars(ls, nvars);
1239951 }
1240952
1241953
1242−static int assignment (LexState *ls, vardesc *v, int nvars) {
1243− int left = 0;
1244− checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment");
1245− unloaddot(ls, v);
1246− if (ls->token == ',') { /* assignment -> ',' NAME assignment */
1247− vardesc nv;
954+static int funcname (LexState *ls, expdesc *v) {
955+ /* funcname -> NAME [':' NAME | '.' NAME] */
956+ int needself = 0;
957+ singlevar(ls, str_checkname(ls), v);
958+ if (ls->t.token == ':' || ls->t.token == '.') {
959+ needself = (ls->t.token == ':');
1248960 next(ls);
1249− var_or_func(ls, &nv);
1250− if (nv.k == VEXP)
1251− luaX_error(ls, "syntax error");
1252− left = assignment(ls, &nv, nvars+1);
1253− }
1254− else { /* assignment -> '=' explist1 */
1255− listdesc d;
1256− check(ls, '=');
1257− explist1(ls, &d);
1258− adjust_mult_assign(ls, nvars, &d);
961+ luaK_tostack(ls, v, 1);
962+ luaK_kstr(ls, checkname(ls));
963+ v->k = VINDEXED;
1259964 }
1260− if (v->k != VINDEXED || left+(nvars-1) == 0) {
1261− /* global/local var or indexed var without values in between */
1262− storevar(ls, v);
965+ return needself;
966+}
967+
968+
969+static void funcstat (LexState *ls, int line) {
970+ /* funcstat -> FUNCTION funcname body */
971+ int needself;
972+ expdesc v;
973+ next(ls); /* skip FUNCTION */
974+ needself = funcname(ls, &v);
975+ body(ls, needself, line);
976+ luaK_storevar(ls, &v);
977+}
978+
979+
980+static void namestat (LexState *ls) {
981+ /* stat -> func | ['%'] NAME assignment */
982+ 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 */
1263988 }
1264− else { /* indexed var with values in between*/
1265− code_oparg(ls, SETTABLE, left+(nvars-1), -1);
1266− left += 2; /* table&index are not popped, because they aren't on top */
989+ else { /* stat -> ['%'] NAME assignment */
990+ int left = assignment(ls, &v, 1);
991+ luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */
1267992 }
1268− return left;
1269993 }
1270994
1271995
1272−static void constructor (LexState *ls) {
1273− /* constructor -> '{' part [';' part] '}' */
1274− int line = ls->linenumber;
1275− int pc = SaveWord(ls);
1276− int nelems;
1277− constdesc cd;
1278− deltastack(ls, 1);
1279− check(ls, '{');
1280− part(ls, &cd);
1281− nelems = cd.n;
1282− if (ls->token == ';') {
1283− constdesc other_cd;
1284− next(ls);
1285− part(ls, &other_cd);
1286− if (cd.k == other_cd.k) /* repeated parts? */
1287− luaX_error(ls, "invalid constructor syntax");
1288− nelems += other_cd.n;
1289− }
1290− check_match(ls, '}', '{', line);
1291− fix_opcode(ls, pc, CREATEARRAY, nelems);
996+static void retstat (LexState *ls) {
997+ /* stat -> RETURN explist */
998+ FuncState *fs = ls->fs;
999+ next(ls); /* skip RETURN */
1000+ if (!block_follow(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 */
12921004 }
12931005
1294−static void part (LexState *ls, constdesc *cd) {
1295− switch (ls->token) {
1296− case ';': case '}': /* part -> empty */
1297− cd->n = 0;
1298− cd->k = ls->token;
1299− return;
13001006
1301− case NAME: {
1302− vardesc v;
1303− exp0(ls, &v);
1304− if (ls->token == '=') {
1305− switch (v.k) {
1306− case VGLOBAL:
1307− code_constant(ls, v.info);
1308− break;
1309− case VLOCAL:
1310− code_string(ls, ls->fs->localvar[v.info]);
1311− break;
1312− default:
1313− error_unexpected(ls);
1314− }
1315− next(ls);
1316− exp1(ls);
1317− cd->n = recfields(ls);
1318− cd->k = 1; /* record */
1319− }
1320− else {
1321− lua_pushvar(ls, &v);
1322− cd->n = listfields(ls);
1323− cd->k = 0; /* list */
1324− }
1325− break;
1326− }
1007+static void breakstat (LexState *ls) {
1008+ /* stat -> BREAK [NAME] */
1009+ 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");
1014+ next(ls); /* skip BREAK */
1015+ luaK_adjuststack(fs, currentlevel - bl->stacklevel);
1016+ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
1017+ /* correct stack for compiler and symbolic execution */
1018+ luaK_adjuststack(fs, bl->stacklevel - currentlevel);
1019+}
13271020
1328− case '[': /* part -> recfield recfields */
1329− recfield(ls);
1330− cd->n = recfields(ls);
1331− cd->k = 1; /* record */
1332− break;
13331021
1334− default: /* part -> exp1 listfields */
1335− exp1(ls);
1336− cd->n = listfields(ls);
1337− cd->k = 0; /* list */
1338− break;
1022+static int stat (LexState *ls) {
1023+ int line = ls->linenumber; /* may be needed for error messages */
1024+ switch (ls->t.token) {
1025+ case TK_IF: { /* stat -> ifstat */
1026+ ifstat(ls, line);
1027+ return 0;
1028+ }
1029+ case TK_WHILE: { /* stat -> whilestat */
1030+ whilestat(ls, line);
1031+ return 0;
1032+ }
1033+ case TK_DO: { /* stat -> DO block END */
1034+ next(ls); /* skip DO */
1035+ block(ls);
1036+ check_match(ls, TK_END, TK_DO, line);
1037+ return 0;
1038+ }
1039+ case TK_FOR: { /* stat -> forstat */
1040+ forstat(ls, line);
1041+ return 0;
1042+ }
1043+ case TK_REPEAT: { /* stat -> repeatstat */
1044+ repeatstat(ls, line);
1045+ return 0;
1046+ }
1047+ case TK_FUNCTION: { /* stat -> funcstat */
1048+ funcstat(ls, line);
1049+ return 0;
1050+ }
1051+ case TK_LOCAL: { /* stat -> localstat */
1052+ localstat(ls);
1053+ return 0;
1054+ }
1055+ case TK_NAME: case '%': { /* stat -> namestat */
1056+ namestat(ls);
1057+ return 0;
1058+ }
1059+ case TK_RETURN: { /* stat -> retstat */
1060+ retstat(ls);
1061+ return 1; /* must be last statement */
1062+ }
1063+ case TK_BREAK: { /* stat -> breakstat */
1064+ breakstat(ls);
1065+ return 1; /* must be last statement */
1066+ }
1067+ default: {
1068+ luaK_error(ls, "<statement> expected");
1069+ return 0; /* to avoid warnings */
1070+ }
13391071 }
13401072 }
13411073
1342−static int recfields (LexState *ls) {
1343− /* recfields -> { ',' recfield } [','] */
1344− int n = 1; /* one has been read before */
1345− while (ls->token == ',') {
1346− next(ls);
1347− if (ls->token == ';' || ls->token == '}')
1348− break;
1349− recfield(ls);
1350− n++;
1351− if (n%RFIELDS_PER_FLUSH == 0)
1352− flush_record(ls, RFIELDS_PER_FLUSH);
1074+
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, ','));
13531087 }
1354− flush_record(ls, n%RFIELDS_PER_FLUSH);
1355− return n;
1088+ code_params(ls, nparams, dots);
13561089 }
13571090
1358−static int listfields (LexState *ls) {
1359− /* listfields -> { ',' exp1 } [','] */
1360− int n = 1; /* one has been read before */
1361− while (ls->token == ',') {
1362− next(ls);
1363− if (ls->token == ';' || ls->token == '}')
1364− break;
1365− exp1(ls);
1366− n++;
1367− if (n%LFIELDS_PER_FLUSH == 0)
1368− flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
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);
13691101 }
1370− flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
1371− return n;
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);
13721108 }
13731109
1374−static void recfield (LexState *ls) {
1375− /* recfield -> (NAME | '['exp1']') = exp1 */
1376− switch (ls->token) {
1377− case NAME:
1378− code_constant(ls, checkname(ls));
1379− break;
13801110
1381− case '[':
1382− next(ls);
1383− exp1(ls);
1384− check(ls, ']');
1385− break;
1111+/* }====================================================================== */
13861112
1387− default: luaX_error(ls, "NAME or `[' expected");
1113+
1114+static void chunk (LexState *ls) {
1115+ /* chunk -> { stat [';'] } */
1116+ int islast = 0;
1117+ 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");
13881122 }
1389− check(ls, '=');
1390− exp1(ls);
13911123 }
13921124
src/lparser.h+45−5
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lparser.h,v 1.3 1999/02/25 19:13:56 roberto Exp $
2+** $Id: lparser.h,v 1.26 2000/10/09 13:47:46 roberto Exp $
33 ** LL(1) Parser and code generator for Lua
44 ** See Copyright Notice in lua.h
55 */
@@ -11,10 +11,50 @@ · 5 unmodified lines
1111 #include "lzio.h"
1212
1313
14−void luaY_codedebugline (int line);
15−TProtoFunc *luaY_parser (ZIO *z);
16−void luaY_error (char *s);
17−void luaY_syntaxerror (char *s, char *token);
14+/*
15+** Expression descriptor
16+*/
17+
18+typedef enum {
19+ VGLOBAL,
20+ VLOCAL,
21+ VINDEXED,
22+ VEXP
23+} expkind;
24+
25+typedef struct expdesc {
26+ 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;
34+} expdesc;
35+
36+
37+
38+/* state needed to generate code for a given function */
39+typedef struct FuncState {
40+ Proto *f; /* current function header */
41+ struct FuncState *prev; /* enclosing function */
42+ struct LexState *ls; /* lexical state */
43+ struct lua_State *L; /* copy of the Lua state */
44+ int pc; /* next position to code */
45+ 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 */
52+ expdesc upvalues[MAXUPVALUES]; /* upvalues */
53+ int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
54+} FuncState;
55+
56+
57+Proto *luaY_parser (lua_State *L, ZIO *z);
1858
1959
2060 #endif
src/lstate.c+94−59
@@ -1,13 +1,15 @@
11 /*
2−** $Id: lstate.c,v 1.12 1999/05/11 20:08:20 roberto Exp $
2+** $Id: lstate.c,v 1.48 2000/10/30 16:29:59 roberto Exp $
33 ** Global State
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include "lbuiltin.h"
8+#include <stdio.h>
9+
10+#include "lua.h"
11+
912 #include "ldo.h"
10−#include "lfunc.h"
1113 #include "lgc.h"
1214 #include "llex.h"
1315 #include "lmem.h"
@@ -17,70 +19,103 @@ · 3 unmodified lines
1719 #include "ltm.h"
1820
1921
20−lua_State *lua_state = NULL;
22+#ifdef LUA_DEBUG
23+static lua_State *lua_state = NULL;
24+void luaB_opentests (lua_State *L);
25+#endif
2126
2227
23−void lua_open (void)
24−{
25− if (lua_state) return;
26− lua_state = luaM_new(lua_State);
27− L->Cstack.base = 0;
28− L->Cstack.lua2C = 0;
29− L->Cstack.num = 0;
30− L->errorJmp = NULL;
28+/*
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.
32+*/
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);
37+ return 0;
38+}
39+
40+
41+/*
42+** open parts that may cause memory-allocation errors
43+*/
44+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);
54+ 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");
63+}
64+
65+
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 */
69+ 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;
3174 L->Mbuffer = NULL;
32− L->Mbuffbase = 0;
3375 L->Mbuffsize = 0;
34− L->Mbuffnext = 0;
35− L->Cblocks = NULL;
36− L->numCblocks = 0;
37− L->debug = 0;
38− L->callhook = NULL;
39− L->linehook = NULL;
40− L->rootproto.next = NULL;
41− L->rootproto.marked = 0;
42− L->rootcl.next = NULL;
43− L->rootcl.marked = 0;
44− L->rootglobal.next = NULL;
45− L->rootglobal.marked = 0;
46− L->roottable.next = NULL;
47− L->roottable.marked = 0;
48− L->IMtable = NULL;
76+ L->rootproto = NULL;
77+ L->rootcl = NULL;
78+ L->roottable = NULL;
79+ L->TMtable = NULL;
80+ L->last_tag = -1;
4981 L->refArray = NULL;
5082 L->refSize = 0;
51− L->GCthreshold = GARBAGE_BLOCK;
52− L->nblocks = 0;
53− luaD_init();
54− luaS_init();
55− luaX_init();
56− luaT_init();
57− luaB_predefine();
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;
89+ 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;
94+ }
95+ L->GCthreshold = 2*L->nblocks;
96+ return L;
5897 }
5998
6099
61−void lua_close (void)
62−{
63− TaggedString *alludata = luaS_collectudata();
64− L->GCthreshold = MAX_INT; /* to avoid GC during GC */
65− luaC_hashcallIM((Hash *)L->roottable.next); /* GC t.methods for tables */
66− luaC_strcallIM(alludata); /* GC tag methods for userdata */
67− luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
68− luaH_free((Hash *)L->roottable.next);
69− luaF_freeproto((TProtoFunc *)L->rootproto.next);
70− luaF_freeclosure((Closure *)L->rootcl.next);
71− luaS_free(alludata);
72− luaS_freeall();
73− luaM_free(L->stack.stack);
74− luaM_free(L->IMtable);
75− luaM_free(L->refArray);
76− luaM_free(L->Mbuffer);
77− luaM_free(L->Cblocks);
78− luaM_free(L);
79− L = NULL;
80−#ifdef DEBUG
81− printf("total de blocos: %ld\n", numblocks);
82− printf("total de memoria: %ld\n", totalmem);
83−#endif
100+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!");
84120 }
85121
86−
src/lstate.h+35−52
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstate.h,v 1.19 1999/05/11 20:08:20 roberto Exp $
2+** $Id: lstate.h,v 1.41 2000/10/05 13:00:17 roberto Exp $
33 ** Global State
44 ** See Copyright Notice in lua.h
55 */
@@ -7,88 +7,71 @@ · 1 unmodified line
77 #ifndef lstate_h
88 #define lstate_h
99
10−#include <setjmp.h>
11−
1210 #include "lobject.h"
1311 #include "lua.h"
1412 #include "luadebug.h"
1513
1614
17−#define GARBAGE_BLOCK 150
18−
1915
20−typedef int StkId; /* index to stack elements */
16+typedef TObject *StkId; /* index to stack elements */
2117
2218
2319 /*
24−** "jmp_buf" may be an array, so it is better to make sure it has an
25−** address (and not that it *is* an address...)
20+** marks for Reference array
2621 */
27−struct lua_longjmp {
28− jmp_buf b;
29−};
22+#define NONEXT -1 /* to end the free list */
23+#define HOLD -2
24+#define COLLECTED -3
25+#define LOCK -4
3026
3127
32−struct Stack {
33− TObject *top;
34− TObject *stack;
35− TObject *last;
28+struct Ref {
29+ TObject o;
30+ int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
3631 };
3732
38−struct C_Lua_Stack {
39− StkId base; /* when Lua calls C or C calls Lua, points to */
40− /* the first slot after the last parameter. */
41− StkId lua2C; /* points to first element of "array" lua2C */
42− int num; /* size of "array" lua2C */
43−};
33+
34+struct lua_longjmp; /* defined in ldo.c */
35+struct TM; /* defined in ltm.h */
4436
4537
4638 typedef struct stringtable {
4739 int size;
48− int nuse; /* number of elements (including EMPTYs) */
49− TaggedString **hash;
40+ lint32 nuse; /* number of elements */
41+ TString **hash;
5042 } stringtable;
5143
5244
53−enum Status {LOCK, HOLD, FREE, COLLECTED};
54−
55−struct ref {
56− TObject o;
57− enum Status status;
58−};
59−
6045
6146 struct lua_State {
6247 /* thread-specific state */
63− struct Stack stack; /* Lua stack */
64− struct C_Lua_Stack Cstack; /* C2lua struct */
48+ StkId top; /* first free slot in the stack */
49+ StkId stack; /* stack base */
50+ StkId stack_last; /* last free slot in the stack */
51+ int stacksize;
52+ StkId Cbase; /* base for current C function */
6553 struct lua_longjmp *errorJmp; /* current error recover point */
6654 char *Mbuffer; /* global buffer */
67− int Mbuffbase; /* current first position of Mbuffer */
68− int Mbuffsize; /* size of Mbuffer */
69− int Mbuffnext; /* next position to fill in Mbuffer */
70− struct C_Lua_Stack *Cblocks;
71− int numCblocks; /* number of nested Cblocks */
72− int debug;
73− lua_CHFunction callhook;
74− lua_LHFunction linehook;
55+ size_t Mbuffsize; /* size of Mbuffer */
7556 /* global state */
76− GCnode rootproto; /* list of all prototypes */
77− GCnode rootcl; /* list of all closures */
78− GCnode roottable; /* list of all tables */
79− GCnode rootglobal; /* list of strings with global values */
80− stringtable *string_root; /* array of hash tables for strings and udata */
81− struct IM *IMtable; /* table for tag methods */
82− int last_tag; /* last used tag in IMtable */
83− struct ref *refArray; /* locked objects */
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 */
8466 int refSize; /* size of refArray */
67+ int refFree; /* list of free positions in refArray */
8568 unsigned long GCthreshold;
86− unsigned long nblocks; /* number of 'blocks' currently allocated */
69+ unsigned long nblocks; /* number of `bytes' currently allocated */
70+ lua_Hook callhook;
71+ lua_Hook linehook;
72+ int allowhooks;
8773 };
8874
8975
90−#define L lua_state
91−
92−
9376 #endif
9477
src/lstring.c+96−239
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstring.c,v 1.19 1999/02/26 15:49:53 roberto Exp $
2+** $Id: lstring.c,v 1.45 2000/10/30 17:49:19 roberto Exp $
33 ** String table (keeps all strings handled by Lua)
44 ** See Copyright Notice in lua.h
55 */
@@ -7,292 +7,149 @@ · 1 unmodified line
77
88 #include <string.h>
99
10+#include "lua.h"
11+
1012 #include "lmem.h"
1113 #include "lobject.h"
1214 #include "lstate.h"
1315 #include "lstring.h"
14−#include "lua.h"
15−
16−
17−#define NUM_HASHSTR 31
18−#define NUM_HASHUDATA 31
19−#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA)
2016
2117
22−#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
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+};
2325
2426
2527
26−static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
27− {{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
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+}
2836
2937
30−void luaS_init (void) {
31− int i;
32− L->string_root = luaM_newvector(NUM_HASHS, stringtable);
33− for (i=0; i<NUM_HASHS; i++) {
34− L->string_root[i].size = 0;
35− L->string_root[i].nuse = 0;
36− L->string_root[i].hash = NULL;
37− }
38+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);
3844 }
3945
4046
41−static unsigned long hash_s (char *s, long l) {
42− unsigned long h = 0; /* seed */
43− while (l--)
44− h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
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++));
4552 return h;
4653 }
4754
48−static int newsize (stringtable *tb) {
49− int size = tb->size;
50− int realuse = 0;
51− int i;
52− /* count how many entries are really in use */
53− for (i=0; i<size; i++)
54− if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
55− realuse++;
56− return luaO_redimension((realuse+1)*2); /* +1 is the new element */
57−}
5855
59−
60−static void grow (stringtable *tb) {
61− int ns = newsize(tb);
62− TaggedString **newhash = luaM_newvector(ns, TaggedString *);
56+void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
57+ TString **newhash = luaM_newvector(L, newsize, TString *);
6358 int i;
64− for (i=0; i<ns; i++)
65− newhash[i] = NULL;
59+ for (i=0; i<newsize; i++) newhash[i] = NULL;
6660 /* rehash */
67− tb->nuse = 0;
6861 for (i=0; i<tb->size; i++) {
69− if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
70− unsigned long h = tb->hash[i]->hash;
71− int h1 = h%ns;
72− while (newhash[h1]) {
73− h1 += (h&(ns-2)) + 1; /* double hashing */
74− if (h1 >= ns) h1 -= ns;
75− }
76− newhash[h1] = tb->hash[i];
77− tb->nuse++;
62+ TString *p = tb->hash[i];
63+ 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 */
70+ newhash[h1] = p;
71+ p = next;
7872 }
7973 }
80− luaM_free(tb->hash);
81− tb->size = ns;
74+ luaM_free(L, tb->hash);
75+ L->nblocks += (newsize - tb->size)*sizeof(TString *);
76+ tb->size = newsize;
8277 tb->hash = newhash;
8378 }
8479
8580
86−static TaggedString *newone_s (char *str, long l, unsigned long h) {
87− TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l);
88− memcpy(ts->str, str, l);
89− ts->str[l] = 0; /* ending 0 */
90− ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */
91− ts->u.s.len = l;
92− ts->constindex = 0;
93− L->nblocks += gcsizestring(l);
94− ts->head.marked = 0;
95− ts->head.next = (GCnode *)ts; /* signal it is in no list */
96− ts->hash = h;
97− return ts;
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;
84+ tb->nuse++;
85+ if (tb->nuse > (lint32)tb->size && tb->size < MAX_INT/2) /* too crowded? */
86+ luaS_resize(L, tb, tb->size*2);
9887 }
9988
100−static TaggedString *newone_u (char *buff, int tag, unsigned long h) {
101− TaggedString *ts = luaM_new(TaggedString);
102− ts->u.d.v = buff;
103− ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
104− ts->constindex = -1; /* tag -> this is a userdata */
105− L->nblocks++;
106− ts->head.marked = 0;
107− ts->head.next = (GCnode *)ts; /* signal it is in no list */
108− ts->hash = h;
109− return ts;
110−}
11189
112−static TaggedString *insert_s (char *str, long l, stringtable *tb) {
113− TaggedString *ts;
90+
91+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
11492 unsigned long h = hash_s(str, l);
115− int size = tb->size;
116− int j = -1;
117− int h1;
118− if ((long)tb->nuse*3 >= (long)size*2) {
119− grow(tb);
120− size = tb->size;
121− }
122− h1 = h%size;
123− while ((ts = tb->hash[h1]) != NULL) {
124− if (ts == &EMPTY)
125− j = h1;
126− else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
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))
12797 return ts;
128− h1 += (h&(size-2)) + 1; /* double hashing */
129− if (h1 >= size) h1 -= size;
13098 }
13199 /* not found */
132− if (j != -1) /* is there an EMPTY space? */
133− h1 = j;
134− else
135− tb->nuse++;
136− ts = tb->hash[h1] = newone_s(str, l, h);
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 */
137110 return ts;
138111 }
139112
140113
141−static TaggedString *insert_u (void *buff, int tag, stringtable *tb) {
142− TaggedString *ts;
143− unsigned long h = (unsigned long)buff;
144− int size = tb->size;
145− int j = -1;
146− int h1;
147− if ((long)tb->nuse*3 >= (long)size*2) {
148− grow(tb);
149− size = tb->size;
150− }
151− h1 = h%size;
152− while ((ts = tb->hash[h1]) != NULL) {
153− if (ts == &EMPTY)
154− j = h1;
155− else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
156− return ts;
157− h1 += (h&(size-2)) + 1; /* double hashing */
158− if (h1 >= size) h1 -= size;
159− }
160− /* not found */
161− if (j != -1) /* is there an EMPTY space? */
162− h1 = j;
163− else
164− tb->nuse++;
165− ts = tb->hash[h1] = newone_u(buff, tag, h);
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 = (udata == NULL) ? 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));
166126 return ts;
167127 }
168128
169129
170−TaggedString *luaS_createudata (void *udata, int tag) {
171− int t = ((unsigned)udata%NUM_HASHUDATA)+NUM_HASHSTR;
172− return insert_u(udata, tag, &L->string_root[t]);
173−}
174−
175−TaggedString *luaS_newlstr (char *str, long l) {
176− int t = (l==0) ? 0 : ((int)((unsigned char)str[0]*l))%NUM_HASHSTR;
177− return insert_s(str, l, &L->string_root[t]);
178−}
179−
180−TaggedString *luaS_new (char *str) {
181− return luaS_newlstr(str, strlen(str));
182−}
183−
184−TaggedString *luaS_newfixedstring (char *str) {
185− TaggedString *ts = luaS_new(str);
186− if (ts->head.marked == 0)
187− ts->head.marked = 2; /* avoid GC */
188− return ts;
189−}
190−
191−
192−void luaS_free (TaggedString *l) {
193− while (l) {
194− TaggedString *next = (TaggedString *)l->head.next;
195− L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
196− luaM_free(l);
197− l = next;
198− }
199−}
200−
201−
202−/*
203−** Garbage collection functions.
204−*/
205−
206−static void remove_from_list (GCnode *l) {
207− while (l) {
208− GCnode *next = l->next;
209− while (next && !next->marked)
210− next = l->next = next->next;
211− l = next;
212− }
213−}
214−
215−
216−TaggedString *luaS_collector (void) {
217− TaggedString *frees = NULL;
218− int i;
219− remove_from_list(&(L->rootglobal));
220− for (i=0; i<NUM_HASHS; i++) {
221− stringtable *tb = &L->string_root[i];
222− int j;
223− for (j=0; j<tb->size; j++) {
224− TaggedString *t = tb->hash[j];
225− if (t == NULL) continue;
226− if (t->head.marked == 1)
227− t->head.marked = 0;
228− else if (!t->head.marked) {
229− t->head.next = (GCnode *)frees;
230− frees = t;
231− tb->hash[j] = &EMPTY;
232− }
233− }
234− }
235− return frees;
236−}
237−
238−
239−TaggedString *luaS_collectudata (void) {
240− TaggedString *frees = NULL;
241− int i;
242− L->rootglobal.next = NULL; /* empty list of globals */
243− for (i=NUM_HASHSTR; i<NUM_HASHS; i++) {
244− stringtable *tb = &L->string_root[i];
245− int j;
246− for (j=0; j<tb->size; j++) {
247− TaggedString *t = tb->hash[j];
248− if (t == NULL || t == &EMPTY)
249− continue;
250− LUA_ASSERT(t->constindex == -1, "must be userdata");
251− t->head.next = (GCnode *)frees;
252− frees = t;
253− tb->hash[j] = &EMPTY;
254− }
255− }
256− return frees;
257−}
258−
259−
260−void luaS_freeall (void) {
261− int i;
262− for (i=0; i<NUM_HASHS; i++) {
263− stringtable *tb = &L->string_root[i];
264− int j;
265− for (j=0; j<tb->size; j++) {
266− TaggedString *t = tb->hash[j];
267− if (t == &EMPTY) continue;
268− luaM_free(t);
269− }
270− luaM_free(tb->hash);
271− }
272− luaM_free(L->string_root);
273−}
274−
275−
276−void luaS_rawsetglobal (TaggedString *ts, TObject *newval) {
277− ts->u.s.globalval = *newval;
278− if (ts->head.next == (GCnode *)ts) { /* is not in list? */
279− ts->head.next = L->rootglobal.next;
280− L->rootglobal.next = (GCnode *)ts;
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))
135+ return ts;
281136 }
137+ /* not found */
138+ ts = luaS_newudata(L, 0, udata);
139+ if (tag != LUA_ANYTAG)
140+ ts->u.d.tag = tag;
141+ return ts;
282142 }
283143
284144
285−char *luaS_travsymbol (int (*fn)(TObject *)) {
286− TaggedString *g;
287− for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
288− if (fn(&g->u.s.globalval))
289− return g->str;
290− return NULL;
145+TString *luaS_new (lua_State *L, const char *str) {
146+ return luaS_newlstr(L, str, strlen(str));
291147 }
292148
293149
294−int luaS_globaldefined (char *name) {
295− TaggedString *ts = luaS_new(name);
296− return ts->u.s.globalval.ttype != LUA_T_NIL;
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;
297154 }
298155
src/lstring.h+22−13
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lstring.h,v 1.7 1998/03/06 16:54:42 roberto Exp $
2+** $Id: lstring.h,v 1.24 2000/10/30 17:49:19 roberto Exp $
33 ** String table (keep all strings handled by Lua)
44 ** See Copyright Notice in lua.h
55 */
@@ -9,20 +9,29 @@ · 3 unmodified lines
99
1010
1111 #include "lobject.h"
12+#include "lstate.h"
1213
1314
14−void luaS_init (void);
15−TaggedString *luaS_createudata (void *udata, int tag);
16−TaggedString *luaS_collector (void);
17−void luaS_free (TaggedString *l);
18−TaggedString *luaS_newlstr (char *str, long l);
19−TaggedString *luaS_new (char *str);
20−TaggedString *luaS_newfixedstring (char *str);
21−void luaS_rawsetglobal (TaggedString *ts, TObject *newval);
22−char *luaS_travsymbol (int (*fn)(TObject *));
23−int luaS_globaldefined (char *name);
24−TaggedString *luaS_collectudata (void);
25−void luaS_freeall (void);
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
21+
22+
23+#define sizestring(l) ((long)sizeof(TString) + \
24+ ((long)(l+1)-TSPACK)*(long)sizeof(char))
25+
26+
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);
31+void luaS_freeall (lua_State *L);
32+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);
2635
2736
2837 #endif
src/ltable.c+231−105
@@ -1,177 +1,303 @@
11 /*
2−** $Id: ltable.c,v 1.22 1999/05/21 19:41:49 roberto Exp $
2+** $Id: ltable.c,v 1.58 2000/10/26 12:47:05 roberto Exp $
33 ** Lua tables (hash)
44 ** See Copyright Notice in lua.h
55 */
66
7−#include <stdlib.h>
87
9−#include "lauxlib.h"
8+/*
9+** Implementation of tables (aka arrays, objects, or hash tables);
10+** uses a mix of chained scatter table with Brent's variation.
11+** A main invariant of these tables is that, if an element is not
12+** in its main position (i.e. the `original' position that its hash gives
13+** to it), then the colliding element is in its own main position.
14+** In other words, there are collisions only when two elements have the
15+** same main position (i.e. the same hash values for that table size).
16+** Because of that, the load factor of these tables can be 100% without
17+** performance penalties.
18+*/
19+
20+
21+#include "lua.h"
22+
1023 #include "lmem.h"
1124 #include "lobject.h"
1225 #include "lstate.h"
26+#include "lstring.h"
1327 #include "ltable.h"
14−#include "lua.h"
1528
1629
17−#define gcsize(n) (1+(n/16))
30+#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node))
1831
19−#define nuse(t) ((t)->nuse)
20−#define nodevector(t) ((t)->node)
2132
2233
23−#define TagDefault LUA_T_ARRAY;
34+#define TagDefault LUA_TTABLE
2435
2536
2637
27−static long int hashindex (TObject *ref) {
28− long int h;
29− switch (ttype(ref)) {
30− case LUA_T_NUMBER:
31− h = (long int)nvalue(ref);
32− break;
33− case LUA_T_STRING: case LUA_T_USERDATA:
34− h = (IntPoint)tsvalue(ref);
38+/*
39+** returns the `main' position of an element in a table (that is, the index
40+** of its hash value)
41+*/
42+Node *luaH_mainposition (const Hash *t, const TObject *key) {
43+ unsigned long h;
44+ switch (ttype(key)) {
45+ case LUA_TNUMBER:
46+ h = (unsigned long)(long)nvalue(key);
3547 break;
36− case LUA_T_ARRAY:
37− h = (IntPoint)avalue(ref);
48+ case LUA_TSTRING:
49+ h = tsvalue(key)->u.s.hash;
3850 break;
39− case LUA_T_PROTO:
40− h = (IntPoint)tfvalue(ref);
51+ case LUA_TUSERDATA:
52+ h = IntPoint(tsvalue(key));
4153 break;
42− case LUA_T_CPROTO:
43− h = (IntPoint)fvalue(ref);
54+ case LUA_TTABLE:
55+ h = IntPoint(hvalue(key));
4456 break;
45− case LUA_T_CLOSURE:
46− h = (IntPoint)clvalue(ref);
57+ case LUA_TFUNCTION:
58+ h = IntPoint(clvalue(key));
4759 break;
4860 default:
49− lua_error("unexpected type to index table");
50− h = 0; /* to avoid warnings */
61+ return NULL; /* invalid key */
5162 }
52− return (h >= 0 ? h : -(h+1));
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)];
66+}
67+
68+
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 */
80+}
81+
82+
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 */
5392 }
5493
5594
56−Node *luaH_present (Hash *t, TObject *key) {
57− int tsize = nhash(t);
58− long int h = hashindex(key);
59− int h1 = h%tsize;
60− Node *n = node(t, h1);
61− /* keep looking until an entry with "ref" equal to key or nil */
62− while ((ttype(ref(n)) == ttype(key)) ? !luaO_equalval(key, ref(n))
63− : ttype(ref(n)) != LUA_T_NIL) {
64− h1 += (h&(tsize-2)) + 1; /* double hashing */
65− if (h1 >= tsize) h1 -= tsize;
66− n = node(t, h1);
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 */
104+}
105+
106+
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);
67112 }
68− return n;
69113 }
70114
71115
72−void luaH_free (Hash *frees) {
73− while (frees) {
74− Hash *next = (Hash *)frees->head.next;
75− L->nblocks -= gcsize(frees->nhash);
76− luaM_free(nodevector(frees));
77− luaM_free(frees);
78− frees = next;
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;
126+ }
127+ for (; i<t->size; i++) {
128+ Node *n = node(t, i);
129+ if (ttype(val(n)) != LUA_TNIL)
130+ return n;
79131 }
132+ return NULL; /* no more elements */
80133 }
81134
82135
83−static Node *hashnodecreate (int nhash) {
84− Node *v = luaM_newvector(nhash, Node);
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 */
144+ 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;
153+ }
154+ ttype(key) = LUA_TNUMBER;
155+ nvalue(key) = n;
156+ LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash");
157+ }
158+}
159+
160+
161+static void setnodevector (lua_State *L, Hash *t, lint32 size) {
85162 int i;
86− for (i=0; i<nhash; i++)
87− ttype(ref(&v[i])) = ttype(val(&v[i])) = LUA_T_NIL;
88− return v;
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;
169+ }
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 */
89173 }
90174
91175
92−Hash *luaH_new (int nhash) {
93− Hash *t = luaM_new(Hash);
94− nhash = luaO_redimension(nhash*3/2);
95− nodevector(t) = hashnodecreate(nhash);
96− nhash(t) = nhash;
97− nuse(t) = 0;
176+Hash *luaH_new (lua_State *L, int size) {
177+ Hash *t = luaM_new(L, Hash);
98178 t->htag = TagDefault;
99− luaO_insertlist(&(L->roottable), (GCnode *)t);
100− L->nblocks += gcsize(nhash);
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));
101186 return t;
102187 }
103188
104189
105−static int newsize (Hash *t) {
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);
194+}
195+
196+
197+static int numuse (const Hash *t) {
106198 Node *v = t->node;
107− int size = nhash(t);
199+ int size = t->size;
108200 int realuse = 0;
109201 int i;
110202 for (i=0; i<size; i++) {
111− if (ttype(val(v+i)) != LUA_T_NIL)
203+ if (ttype(&v[i].val) != LUA_TNIL)
112204 realuse++;
113205 }
114− return luaO_redimension((realuse+1)*2); /* +1 is the new element */
206+ return realuse;
115207 }
116208
117209
118−static void rehash (Hash *t) {
119− int nold = nhash(t);
120− Node *vold = nodevector(t);
121− int nnew = newsize(t);
210+static void rehash (lua_State *L, Hash *t) {
211+ int oldsize = t->size;
212+ Node *nold = t->node;
213+ int nelems = numuse(t);
122214 int i;
123− nodevector(t) = hashnodecreate(nnew);
124− nhash(t) = nnew;
125− nuse(t) = 0;
126− for (i=0; i<nold; i++) {
127− Node *n = vold+i;
128− if (ttype(val(n)) != LUA_T_NIL) {
129− *luaH_present(t, ref(n)) = *n; /* copy old node to new hash */
130− nuse(t)++;
131− }
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;
132227 }
133− L->nblocks += gcsize(nnew)-gcsize(nold);
134− luaM_free(vold);
228+ luaM_free(L, nold); /* free old array */
135229 }
136230
137231
138−void luaH_set (Hash *t, TObject *ref, TObject *val) {
139− Node *n = luaH_present(t, ref);
140− if (ttype(ref(n)) != LUA_T_NIL)
141− *val(n) = *val;
142− else {
143− TObject buff;
144− buff = *val; /* rehash may invalidate this address */
145− if ((long)nuse(t)*3L > (long)nhash(t)*2L) {
146− rehash(t);
147− n = luaH_present(t, ref);
232+/*
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.
239+*/
240+TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
241+ 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) {
257+ /* yes; move colliding node into free position */
258+ while (othern->next != mp) othern = othern->next; /* find previous */
259+ othern->next = n; /* redo the chain with `n' in place of `mp' */
260+ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
261+ mp->next = NULL; /* now `mp' is free */
148262 }
149− nuse(t)++;
150− *ref(n) = *ref;
151− *val(n) = buff;
263+ else { /* colliding node is in its own main position */
264+ /* new node will go into free position */
265+ n->next = mp->next; /* chain new position */
266+ mp->next = n;
267+ mp = n;
268+ }
269+ }
270+ mp->key = *key;
271+ for (;;) { /* correct `firstfree' */
272+ if (ttype(&t->firstfree->key) == LUA_TNIL)
273+ return &mp->val; /* OK; table still has a free place */
274+ else if (t->firstfree == t->node) break; /* cannot decrement from here */
275+ else (t->firstfree)--;
152276 }
277+ rehash(L, t); /* no more free places */
278+ return luaH_set(L, t, key); /* `rehash' invalidates this insertion */
153279 }
154280
155281
156−int luaH_pos (Hash *t, TObject *r) {
157− Node *n = luaH_present(t, r);
158− luaL_arg_check(ttype(val(n)) != LUA_T_NIL, 2, "key not found");
159− return n-(t->node);
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);
160287 }
161288
162289
163−void luaH_setint (Hash *t, int ref, TObject *val) {
164− TObject index;
165− ttype(&index) = LUA_T_NUMBER;
166− nvalue(&index) = ref;
167− luaH_set(t, &index, val);
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;
168297 }
169298
170299
171−TObject *luaH_getint (Hash *t, int ref) {
172− TObject index;
173− ttype(&index) = LUA_T_NUMBER;
174− nvalue(&index) = ref;
175− return luaH_get(t, &index);
300+const TObject *luaH_getglobal (lua_State *L, const char *name) {
301+ return luaH_getstr(L->gt, luaS_new(L, name));
176302 }
177303
src/ltable.h+19−15
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ltable.h,v 1.11 1999/02/23 14:57:28 roberto Exp $
2+** $Id: ltable.h,v 1.24 2000/08/31 14:08:27 roberto Exp $
33 ** Lua tables (hash)
44 ** See Copyright Notice in lua.h
55 */
@@ -10,21 +10,25 @@ · 4 unmodified lines
1010 #include "lobject.h"
1111
1212
13−#define node(t,i) (&(t)->node[i])
14−#define ref(n) (&(n)->ref)
13+#define node(t,i) (&(t)->node[i])
14+#define key(n) (&(n)->key)
1515 #define val(n) (&(n)->val)
16−#define nhash(t) ((t)->nhash)
17−
18−#define luaH_get(t,ref) (val(luaH_present((t), (ref))))
19−#define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from)))
20−
21−Hash *luaH_new (int nhash);
22−void luaH_free (Hash *frees);
23−Node *luaH_present (Hash *t, TObject *key);
24−void luaH_set (Hash *t, TObject *ref, TObject *val);
25−int luaH_pos (Hash *t, TObject *r);
26−void luaH_setint (Hash *t, int ref, TObject *val);
27−TObject *luaH_getint (Hash *t, int ref);
16+
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);
29+
30+/* exported only for debugging */
31+Node *luaH_mainposition (const Hash *t, const TObject *key);
2832
2933
3034 #endif
src/ltests.c+543−0
@@ -0,0 +1,543 @@
1+/*
2+** $Id: ltests.c,v 1.54 2000/10/31 13:10:24 roberto Exp $
3+** Internal Module for Debugging of the Lua Implementation
4+** See Copyright Notice in lua.h
5+*/
6+
7+
8+#include <ctype.h>
9+#include <stdio.h>
10+#include <stdlib.h>
11+#include <string.h>
12+
13+
14+#include "lua.h"
15+
16+#include "lapi.h"
17+#include "lauxlib.h"
18+#include "lcode.h"
19+#include "ldebug.h"
20+#include "ldo.h"
21+#include "lfunc.h"
22+#include "lmem.h"
23+#include "lopcodes.h"
24+#include "lstate.h"
25+#include "lstring.h"
26+#include "ltable.h"
27+#include "luadebug.h"
28+#include "lualib.h"
29+
30+
31+void luaB_opentests (lua_State *L);
32+
33+
34+/*
35+** The whole module only makes sense with LUA_DEBUG on
36+*/
37+#ifdef LUA_DEBUG
38+
39+
40+
41+static void setnameval (lua_State *L, const char *name, int val) {
42+ lua_pushstring(L, name);
43+ lua_pushnumber(L, val);
44+ lua_settable(L, -3);
45+}
46+
47+
48+/*
49+** {======================================================
50+** Disassembler
51+** =======================================================
52+*/
53+
54+
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];
69+ Instruction i = p->code[pc];
70+ 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));
79+ break;
80+ case iS:
81+ sprintf(buff+8, "%-12s%4d", name, GETARG_S(i));
82+ break;
83+ case iAB:
84+ sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
85+ break;
86+ }
87+ lua_pushstring(L, buff);
88+ return (o != OP_END);
89+}
90+
91+
92+static int listcode (lua_State *L) {
93+ int pc;
94+ Proto *p;
95+ int res;
96+ luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
97+ 1, "Lua function expected");
98+ p = clvalue(luaA_index(L, 1))->f.l;
99+ lua_newtable(L);
100+ setnameval(L, "maxstack", p->maxstacksize);
101+ setnameval(L, "numparams", p->numparams);
102+ pc = 0;
103+ do {
104+ lua_pushnumber(L, pc+1);
105+ res = pushop(L, p, pc++);
106+ lua_settable(L, -3);
107+ } while (res);
108+ return 1;
109+}
110+
111+
112+static int liststrings (lua_State *L) {
113+ Proto *p;
114+ int i;
115+ luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
116+ 1, "Lua function expected");
117+ p = clvalue(luaA_index(L, 1))->f.l;
118+ 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);
122+ lua_settable(L, -3);
123+ }
124+ return 1;
125+}
126+
127+
128+static int listlocals (lua_State *L) {
129+ Proto *p;
130+ int pc = luaL_check_int(L, 2) - 1;
131+ int i = 0;
132+ const char *name;
133+ luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
134+ 1, "Lua function expected");
135+ p = clvalue(luaA_index(L, 1))->f.l;
136+ while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
137+ lua_pushstring(L, name);
138+ return i-1;
139+}
140+
141+/* }====================================================== */
142+
143+
144+
145+static int get_limits (lua_State *L) {
146+ lua_newtable(L);
147+ setnameval(L, "BITS_INT", BITS_INT);
148+ 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);
154+ setnameval(L, "MAXPARAMS", MAXPARAMS);
155+ setnameval(L, "MAXSTACK", MAXSTACK);
156+ 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);
163+ return 1;
164+}
165+
166+
167+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);
172+ return 3;
173+ }
174+ else {
175+ memdebug_memlimit = luaL_check_int(L, 1);
176+ return 0;
177+ }
178+}
179+
180+
181+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);
185+ }
186+ else {
187+ Hash *t;
188+ 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);
191+ }
192+ return 1;
193+}
194+
195+
196+static int table_query (lua_State *L) {
197+ const Hash *t;
198+ int i = luaL_opt_int(L, 2, -1);
199+ luaL_checktype(L, 1, LUA_TTABLE);
200+ t = hvalue(luaA_index(L, 1));
201+ if (i == -1) {
202+ lua_pushnumber(L, t->size);
203+ lua_pushnumber(L, t->firstfree - t->node);
204+ return 2;
205+ }
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;
212+ }
213+ else
214+ return 2;
215+ }
216+ return 0;
217+}
218+
219+
220+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;
223+ if (s==-1) {
224+ lua_pushnumber(L ,tb->nuse);
225+ lua_pushnumber(L ,tb->size);
226+ return 2;
227+ }
228+ else if (s < tb->size) {
229+ TString *ts;
230+ 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;
235+ n++;
236+ }
237+ return n;
238+ }
239+ return 0;
240+}
241+
242+
243+static int tref (lua_State *L) {
244+ luaL_checkany(L, 1);
245+ lua_pushvalue(L, 1);
246+ lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
247+ return 1;
248+}
249+
250+static int getref (lua_State *L) {
251+ if (lua_getref(L, luaL_check_int(L, 1)))
252+ return 1;
253+ else
254+ return 0;
255+}
256+
257+static int unref (lua_State *L) {
258+ lua_unref(L, luaL_check_int(L, 1));
259+ return 0;
260+}
261+
262+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));
267+ return 1;
268+}
269+
270+static int udataval (lua_State *L) {
271+ luaL_checktype(L, 1, LUA_TUSERDATA);
272+ lua_pushnumber(L, (int)lua_touserdata(L, 1));
273+ return 1;
274+}
275+
276+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);
280+ else
281+ lua_pushnil(L);
282+ return 1;
283+}
284+
285+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+ }
295+ return 0;
296+}
297+
298+static int closestate (lua_State *L) {
299+ luaL_checktype(L, 1, LUA_TUSERDATA);
300+ lua_close((lua_State *)lua_touserdata(L, 1));
301+ return 0;
302+}
303+
304+static int doremote (lua_State *L) {
305+ lua_State *L1;
306+ const char *code = luaL_check_string(L, 2);
307+ int status;
308+ luaL_checktype(L, 1, LUA_TUSERDATA);
309+ L1 = (lua_State *)lua_touserdata(L, 1);
310+ status = lua_dostring(L1, code);
311+ if (status != 0) {
312+ lua_pushnil(L);
313+ lua_pushnumber(L, status);
314+ return 2;
315+ }
316+ else {
317+ int i = 0;
318+ while (!lua_isnull(L1, ++i))
319+ lua_pushstring(L, lua_tostring(L1, i));
320+ return i-1;
321+ }
322+}
323+
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);
331+ return 1;
332+}
333+
334+static int pushbool (lua_State *L, int b) {
335+ if (b) lua_pushnumber(L, 1);
336+ else lua_pushnil(L);
337+ return 1;
338+}
339+
340+static int equal (lua_State *L) {
341+ return pushbool(L, lua_equal(L, 1, 2));
342+}
343+
344+
345+
346+/*
347+** {======================================================
348+** function to test the API with C. It interprets a kind of "assembler"
349+** language with calls to the API, so the test can be driven by Lua code
350+** =======================================================
351+*/
352+
353+static const char *const delimits = " \t\n,;";
354+
355+static void skip (const char **pc) {
356+ while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
357+}
358+
359+static int getnum (lua_State *L, const char **pc) {
360+ int res = 0;
361+ int sig = 1;
362+ skip(pc);
363+ if (**pc == '.') {
364+ res = (int)lua_tonumber(L, -1);
365+ lua_pop(L, 1);
366+ (*pc)++;
367+ return res;
368+ }
369+ else if (**pc == '-') {
370+ sig = -1;
371+ (*pc)++;
372+ }
373+ while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
374+ return sig*res;
375+}
376+
377+static const char *getname (char *buff, const char **pc) {
378+ int i = 0;
379+ skip(pc);
380+ while (**pc != '\0' && !strchr(delimits, **pc))
381+ buff[i++] = *(*pc)++;
382+ buff[i] = '\0';
383+ return buff;
384+}
385+
386+
387+#define EQ(s1) (strcmp(s1, inst) == 0)
388+
389+#define getnum ((getnum)(L, &pc))
390+#define getname ((getname)(buff, &pc))
391+
392+
393+static int testC (lua_State *L) {
394+ char buff[30];
395+ const char *pc = luaL_check_string(L, 1);
396+ for (;;) {
397+ const char *inst = getname;
398+ if EQ("") return 0;
399+ else if EQ("isnumber") {
400+ lua_pushnumber(L, lua_isnumber(L, getnum));
401+ }
402+ else if EQ("isstring") {
403+ lua_pushnumber(L, lua_isstring(L, getnum));
404+ }
405+ else if EQ("istable") {
406+ lua_pushnumber(L, lua_istable(L, getnum));
407+ }
408+ else if EQ("iscfunction") {
409+ lua_pushnumber(L, lua_iscfunction(L, getnum));
410+ }
411+ else if EQ("isfunction") {
412+ lua_pushnumber(L, lua_isfunction(L, getnum));
413+ }
414+ else if EQ("isuserdata") {
415+ lua_pushnumber(L, lua_isuserdata(L, getnum));
416+ }
417+ else if EQ("isnil") {
418+ lua_pushnumber(L, lua_isnil(L, getnum));
419+ }
420+ else if EQ("isnull") {
421+ lua_pushnumber(L, lua_isnull(L, getnum));
422+ }
423+ else if EQ("tonumber") {
424+ lua_pushnumber(L, lua_tonumber(L, getnum));
425+ }
426+ 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));
431+ }
432+ else if EQ("strlen") {
433+ lua_pushnumber(L, lua_strlen(L, getnum));
434+ }
435+ else if EQ("tocfunction") {
436+ lua_pushcfunction(L, lua_tocfunction(L, getnum));
437+ }
438+ else if EQ("return") {
439+ return getnum;
440+ }
441+ else if EQ("gettop") {
442+ lua_pushnumber(L, lua_gettop(L));
443+ }
444+ else if EQ("settop") {
445+ lua_settop(L, getnum);
446+ }
447+ else if EQ("pop") {
448+ lua_pop(L, getnum);
449+ }
450+ else if EQ("pushnum") {
451+ lua_pushnumber(L, getnum);
452+ }
453+ else if EQ("pushvalue") {
454+ lua_pushvalue(L, getnum);
455+ }
456+ else if EQ("remove") {
457+ lua_remove(L, getnum);
458+ }
459+ else if EQ("insert") {
460+ lua_insert(L, getnum);
461+ }
462+ else if EQ("gettable") {
463+ lua_gettable(L, getnum);
464+ }
465+ else if EQ("settable") {
466+ lua_settable(L, getnum);
467+ }
468+ else if EQ("next") {
469+ lua_next(L, -2);
470+ }
471+ else if EQ("concat") {
472+ lua_concat(L, getnum);
473+ }
474+ else if EQ("rawcall") {
475+ int narg = getnum;
476+ int nres = getnum;
477+ lua_rawcall(L, narg, nres);
478+ }
479+ else if EQ("call") {
480+ int narg = getnum;
481+ int nres = getnum;
482+ lua_call(L, narg, nres);
483+ }
484+ else if EQ("dostring") {
485+ lua_dostring(L, luaL_check_string(L, getnum));
486+ }
487+ else if EQ("settagmethod") {
488+ int tag = getnum;
489+ const char *event = getname;
490+ lua_settagmethod(L, tag, event);
491+ }
492+ else if EQ("gettagmethod") {
493+ int tag = getnum;
494+ const char *event = getname;
495+ lua_gettagmethod(L, tag, event);
496+ }
497+ else if EQ("type") {
498+ lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
499+ }
500+ else luaL_verror(L, "unknown instruction %.30s", buff);
501+ }
502+ return 0;
503+}
504+
505+/* }====================================================== */
506+
507+
508+
509+static const struct luaL_reg tests_funcs[] = {
510+ {"hash", hash_query},
511+ {"limits", get_limits},
512+ {"listcode", listcode},
513+ {"liststrings", liststrings},
514+ {"listlocals", listlocals},
515+ {"loadlib", loadlib},
516+ {"querystr", string_query},
517+ {"querytab", table_query},
518+ {"testC", testC},
519+ {"ref", tref},
520+ {"getref", getref},
521+ {"unref", unref},
522+ {"newuserdata", newuserdata},
523+ {"udataval", udataval},
524+ {"newstate", newstate},
525+ {"closestate", closestate},
526+ {"doremote", doremote},
527+ {"settagmethod", settagmethod},
528+ {"equal", equal},
529+ {"totalmem", mem_query}
530+};
531+
532+
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 */
541+}
542+
543+#endif
src/ltm.c+93−178
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ltm.c,v 1.25 1999/05/21 19:41:49 roberto Exp $
2+** $Id: ltm.c,v 1.56 2000/10/31 13:10:24 roberto Exp $
33 ** Tag methods
44 ** See Copyright Notice in lua.h
55 */
@@ -8,241 +8,156 @@ · 2 unmodified lines
88 #include <stdio.h>
99 #include <string.h>
1010
11−#include "lauxlib.h"
11+#include "lua.h"
12+
13+#include "ldo.h"
1214 #include "lmem.h"
1315 #include "lobject.h"
1416 #include "lstate.h"
1517 #include "ltm.h"
1618
1719
18−char *luaT_eventname[] = { /* ORDER IM */
19− "gettable", "settable", "index", "getglobal", "setglobal", "add",
20− "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge",
21− "concat", "gc", "function", NULL
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
2225 };
2326
2427
25−static int luaI_checkevent (char *name, char *list[]) {
26− int e = luaL_findstring(name, list);
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");
2743 if (e < 0)
28− luaL_verror("`%.50s' is not a valid event name", name);
44+ luaO_verror(L, "`%.50s' is not a valid event name", name);
2945 return e;
3046 }
3147
3248
3349
34−/* events in LUA_T_NIL are all allowed, since this is used as a
50+/* events in LUA_TNIL are all allowed, since this is used as a
3551 * 'placeholder' for "default" fallbacks
3652 */
37−static char luaT_validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
38−{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
39−{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
40−{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
41−{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
42−{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */
43−{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */
44−{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
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 */
4561 };
4662
47−static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
48− return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
63+int luaT_validevent (int t, int e) { /* ORDER LUA_T */
64+ return (t >= NUM_TAGS) ? 1 : luaT_validevents[t][e];
4965 }
5066
5167
52−static void init_entry (int tag) {
68+static void init_entry (lua_State *L, int tag) {
5369 int i;
54− for (i=0; i<IM_N; i++)
55− ttype(luaT_getim(tag, i)) = LUA_T_NIL;
70+ for (i=0; i<TM_N; i++)
71+ luaT_gettm(L, tag, i) = NULL;
72+ L->TMtable[tag].collected = NULL;
5673 }
5774
5875
59−void luaT_init (void) {
76+void luaT_init (lua_State *L) {
6077 int t;
61− L->last_tag = -(NUM_TAGS-1);
62− luaM_growvector(L->IMtable, 0, NUM_TAGS, struct IM, arrEM, MAX_INT);
63− for (t=L->last_tag; t<=0; t++)
64− init_entry(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);
6583 }
6684
6785
68−int lua_newtag (void) {
69− --L->last_tag;
70− luaM_growvector(L->IMtable, -(L->last_tag), 1, struct IM, arrEM, MAX_INT);
71− init_entry(L->last_tag);
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);
7292 return L->last_tag;
7393 }
7494
7595
76−static void checktag (int tag) {
77− if (!(L->last_tag <= tag && tag <= 0))
78− luaL_verror("%d is not a valid tag", tag);
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);
7999 }
80100
81−void luaT_realtag (int tag) {
82− if (!(L->last_tag <= tag && tag < LUA_T_NIL))
83− luaL_verror("tag %d was not created by `newtag'", tag);
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);
84104 }
85105
86106
87−int lua_copytagmethods (int tagto, int tagfrom) {
107+LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
88108 int e;
89− checktag(tagto);
90− checktag(tagfrom);
91− for (e=0; e<IM_N; e++) {
109+ checktag(L, tagto);
110+ checktag(L, tagfrom);
111+ for (e=0; e<TM_N; e++) {
92112 if (luaT_validevent(tagto, e))
93− *luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
113+ luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e);
94114 }
95115 return tagto;
96116 }
97117
98118
99−int luaT_effectivetag (TObject *o) {
100− int t;
101− switch (t = ttype(o)) {
102− case LUA_T_ARRAY:
103− return o->value.a->htag;
104− case LUA_T_USERDATA: {
105− int tag = o->value.ts->u.d.tag;
106− return (tag >= 0) ? LUA_T_USERDATA : tag;
107− }
108− case LUA_T_CLOSURE:
109− return o->value.cl->consts[0].ttype;
110−#ifdef DEBUG
111− case LUA_T_PMARK: case LUA_T_CMARK:
112− case LUA_T_CLMARK: case LUA_T_LINE:
113− LUA_INTERNALERROR("invalid type");
114−#endif
115− default:
116− return t;
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;
117125 }
118126 }
119127
120128
121−TObject *luaT_gettagmethod (int t, char *event) {
122− int e = luaI_checkevent(event, luaT_eventname);
123− checktag(t);
124− if (luaT_validevent(t, e))
125− return luaT_getim(t,e);
126− else
127− return &luaO_nilobject;
128−}
129−
130−
131−void luaT_settagmethod (int t, char *event, TObject *func) {
132− TObject temp;
133− int e = luaI_checkevent(event, luaT_eventname);
134− checktag(t);
135− if (!luaT_validevent(t, e))
136− luaL_verror("cannot change tag method `%.20s' for type `%.20s'%.20s",
137− luaT_eventname[e], luaO_typenames[-t],
138− (t == LUA_T_ARRAY || t == LUA_T_USERDATA) ? " with default tag"
139− : "");
140− temp = *func;
141− *func = *luaT_getim(t,e);
142− *luaT_getim(t, e) = temp;
143−}
144−
145−
146−char *luaT_travtagmethods (int (*fn)(TObject *)) { /* ORDER IM */
129+LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
147130 int e;
148− for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) {
149− int t;
150− for (t=0; t>=L->last_tag; t--)
151− if (fn(luaT_getim(t,e)))
152− return luaT_eventname[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;
153136 }
154− return NULL;
155−}
156−
157−
158−/*
159−* ===================================================================
160−* compatibility with old fallback system
161−*/
162−#ifdef LUA_COMPAT2_5
163−
164−#include "lapi.h"
165−#include "lstring.h"
166−
167−static void errorFB (void)
168−{
169− lua_Object o = lua_getparam(1);
170− if (lua_isstring(o))
171− fprintf(stderr, "lua: %s\n", lua_getstring(o));
172137 else
173− fprintf(stderr, "lua: unknown error\n");
174−}
175−
176−
177−static void nilFB (void) { }
178−
179−
180−static void typeFB (void) {
181− lua_error("unexpected type");
138+ ttype(L->top) = LUA_TNIL;
139+ incr_top;
182140 }
183141
184142
185−static void fillvalids (IMS e, TObject *func) {
186− int t;
187− for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
188− if (luaT_validevent(t, e))
189− *luaT_getim(t, e) = *func;
190−}
191−
192−
193−void luaT_setfallback (void) {
194− static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
195− TObject oldfunc;
196− lua_CFunction replace;
197− char *name = luaL_check_string(1);
198− lua_Object func = lua_getparam(2);
199− luaL_arg_check(lua_isfunction(func), 2, "function expected");
200− switch (luaL_findstring(name, oldnames)) {
201− case 0: { /* old error fallback */
202− TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
203− oldfunc = *em;
204− *em = *luaA_Address(func);
205− replace = errorFB;
206− break;
207− }
208− case 1: /* old getglobal fallback */
209− oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
210− *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func);
211− replace = nilFB;
212− break;
213− case 2: { /* old arith fallback */
214− int i;
215− oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW);
216− for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */
217− fillvalids(i, luaA_Address(func));
218− replace = typeFB;
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;
219154 break;
220− }
221− case 3: { /* old order fallback */
222− int i;
223− oldfunc = *luaT_getim(LUA_T_NIL, IM_LT);
224− for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */
225− fillvalids(i, luaA_Address(func));
226− replace = typeFB;
155+ case LUA_TFUNCTION:
156+ luaT_gettm(L, t, e) = clvalue(L->top - 1);
227157 break;
228− }
229− default: {
230− int e;
231− if ((e = luaL_findstring(name, luaT_eventname)) >= 0) {
232− oldfunc = *luaT_getim(LUA_T_NIL, e);
233− fillvalids(e, luaA_Address(func));
234− replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB;
235− }
236− else {
237− luaL_verror("`%.50s' is not a valid fallback name", name);
238− replace = NULL; /* to avoid warnings */
239− }
240− }
158+ default:
159+ lua_error(L, "tag method must be a function (or nil)");
241160 }
242− if (oldfunc.ttype != LUA_T_NIL)
243− luaA_pushobject(&oldfunc);
244− else
245− lua_pushcfunction(replace);
161+ L->top--;
246162 }
247−#endif
248163
src/ltm.h+34−37
@@ -1,5 +1,5 @@
11 /*
2−** $Id: ltm.h,v 1.5 1999/01/15 13:11:57 roberto Exp $
2+** $Id: ltm.h,v 1.18 2000/10/05 13:00:17 roberto Exp $
33 ** Tag methods
44 ** See Copyright Notice in lua.h
55 */
@@ -13,50 +13,47 @@ · 7 unmodified lines
1313
1414 /*
1515 * WARNING: if you change the order of this enumeration,
16−* grep "ORDER IM"
16+* grep "ORDER TM"
1717 */
1818 typedef enum {
19− IM_GETTABLE = 0,
20− IM_SETTABLE,
21− IM_INDEX,
22− IM_GETGLOBAL,
23− IM_SETGLOBAL,
24− IM_ADD,
25− IM_SUB,
26− IM_MUL,
27− IM_DIV,
28− IM_POW,
29− IM_UNM,
30− IM_LT,
31− IM_LE,
32− IM_GT,
33− IM_GE,
34− IM_CONCAT,
35− IM_GC,
36− IM_FUNCTION
37−} IMS;
38−
39−#define IM_N 18
40−
41−
42−struct IM {
43− TObject int_method[IM_N];
19+ TM_GETTABLE = 0,
20+ TM_SETTABLE,
21+ TM_INDEX,
22+ TM_GETGLOBAL,
23+ TM_SETGLOBAL,
24+ TM_ADD,
25+ TM_SUB,
26+ TM_MUL,
27+ TM_DIV,
28+ TM_POW,
29+ TM_UNM,
30+ TM_LT,
31+ TM_CONCAT,
32+ TM_GC,
33+ TM_FUNCTION,
34+ TM_N /* number of elements in the enum */
35+} TMS;
36+
37+
38+struct TM {
39+ Closure *method[TM_N];
40+ TString *collected; /* list of garbage-collected udata with this tag */
4441 };
4542
4643
47−#define luaT_getim(tag,event) (&L->IMtable[-(tag)].int_method[event])
48−#define luaT_getimbyObj(o,e) (luaT_getim(luaT_effectivetag(o),(e)))
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)))
4946
50−extern char *luaT_eventname[];
5147
48+#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag)
5249
53−void luaT_init (void);
54−void luaT_realtag (int tag);
55−int luaT_effectivetag (TObject *o);
56−void luaT_settagmethod (int t, char *event, TObject *func);
57−TObject *luaT_gettagmethod (int t, char *event);
58−char *luaT_travtagmethods (int (*fn)(TObject *));
50+extern const char *const luaT_eventname[];
51+
52+
53+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 */
5957
60−void luaT_setfallback (void); /* only if LUA_COMPAT2_5 */
6158
6259 #endif
src/lua/Makefile+2−2
@@ -1,4 +1,4 @@
1−# makefile for lua interpreter
1+# makefile for Lua interpreter
22
33 LUA= ../..
44
@@ -14,7 +14,7 @@ T= $(BIN)/lua · 9 unmodified lines
1414 all: $T
1515
1616 $T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
17− $(CC) -o $@ $(OBJS) -L$(LIB) -llua -llualib -lm
17+ $(CC) -o $@ $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS)
1818
1919 $(LIB)/liblua.a:
2020 cd ..; $(MAKE)
src/lua/README+26−24
@@ -1,38 +1,40 @@
1−This client is a sample lua interpreter.
1+This is lua, a sample Lua interpreter.
22 It can be used as a batch interpreter and also interactively.
3−
4−Here are the options it understands:
5−
3+There are man pages for it in both nroff and html in ../../doc.
4+
5+Here are the options that it understands:
6+ - execute stdin as a file
7+ -c close Lua when exiting
8+ -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)
613 -v print version information
7− -d turn debug on
8− -e stat dostring `stat'
9− -q interactive mode without prompt
10− -i interactive mode with prompt
11− - executes stdin as a file
12− a=b sets global `a' with string `b' (no need to quote b)
13− name dofile `name'
14+ a=b set global `a' to string `b'
15+ name execute file `name'
1416
1517 If no options are given, then it reads lines from stdin and executes them
16−as they are read. So, each line must contain a complete statement.
18+as they are read -- so, each line must contain a complete statement.
1719 To span a statement across several lines, end each line with a backslash '\'.
1820
1921 To change the prompt, set the global variable _PROMPT to whatever you want.
20−You can do after calling the interpreter or on the command line with
21− _PROMPT="lua: "
22−for example.
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.
2325
2426 You must be careful when using quotes on the command line because they are
2527 usually handled by the shell.
2628
2729 This interpreter is good for using Lua as a standalone language.
28−For a minimal interpreter, see etc/min.c.
30+For a minimal interpreter, see ../../etc/min.c.
2931
3032 If your application simply exports new functions to Lua (which is common),
31−then you can use this interpreter unmodified: just define a function
32−
33− void lua_userinit (void)
34−
35−in your code. In this function, you should do whatever initializations are
36−need, typically exporting your functions to Lua.
37−If you use this scheme, you must explicily open any standard libraries you need.
38−See ../lib/linit.c
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".
src/lua/lua.c+224−90
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lua.c,v 1.21 1999/07/02 18:22:38 roberto Exp $
2+** $Id: lua.c,v 1.55 2000/10/20 16:36:32 roberto Exp $
33 ** Lua stand-alone interpreter
44 ** See Copyright Notice in lua.h
55 */
@@ -11,24 +11,51 @@ · 5 unmodified lines
1111 #include <string.h>
1212
1313 #include "lua.h"
14+
1415 #include "luadebug.h"
1516 #include "lualib.h"
1617
1718
19+static lua_State *L = NULL;
20+
21+
22+#ifndef PROMPT
23+#define PROMPT "> "
24+#endif
25+
1826 #ifdef _POSIX_SOURCE
1927 #include <unistd.h>
2028 #else
21−#define isatty(x) (x==0) /* assume stdin is a tty */
29+static int isatty (int x) { return x==0; } /* assume stdin is a tty */
2230 #endif
2331
2432
33+/*
34+** global options
35+*/
36+struct Options {
37+ int toclose;
38+ int stacksize;
39+};
40+
41+
2542 typedef void (*handler)(int); /* type for signal actions */
2643
2744 static void laction (int i);
2845
2946
30−static lua_LHFunction old_linehook = NULL;
31−static lua_CHFunction old_callhook = NULL;
47+static lua_Hook old_linehook = NULL;
48+static lua_Hook old_callhook = NULL;
49+
50+
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);
57+ /* add your libraries here */
58+}
3259
3360
3461 static handler lreset (void) {
@@ -37,66 +64,125 @@ static handler lreset (void) { · 2 unmodified lines
3764
3865
3966 static void lstop (void) {
40− lua_setlinehook(old_linehook);
41− lua_setcallhook(old_callhook);
67+ lua_setlinehook(L, old_linehook);
68+ lua_setcallhook(L, old_callhook);
4269 lreset();
43− lua_error("interrupted!");
70+ lua_error(L, "interrupted!");
4471 }
4572
4673
4774 static void laction (int i) {
75+ (void)i; /* to avoid warnings */
4876 signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
4977 terminate process (default action) */
50− old_linehook = lua_setlinehook((lua_LHFunction)lstop);
51− old_callhook = lua_setcallhook((lua_CHFunction)lstop);
78+ old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
79+ old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
5280 }
5381
5482
55−static int ldo (int (*f)(char *), char *name) {
83+static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
5684 int res;
5785 handler h = lreset();
58− res = f(name); /* dostring | dofile */
86+ int top = lua_gettop(L);
87+ res = f(L, name); /* dostring | dofile */
88+ lua_settop(L, top); /* remove eventual results */
5989 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");
6096 return res;
6197 }
6298
6399
64100 static void print_message (void) {
65101 fprintf(stderr,
66−"Lua: command line options:\n"
67−" -v print version information\n"
68−" -d turn debug on\n"
69−" -e stat dostring `stat'\n"
70−" -q interactive mode without prompt\n"
71−" -i interactive mode with prompt\n"
72−" - executes stdin as a file\n"
73−" a=b sets global `a' with string `b'\n"
74−" name dofile `name'\n\n");
102+ "usage: lua [options]. Available options are:\n"
103+ " - execute stdin as a file\n"
104+ " -c close Lua when exiting\n"
105+ " -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+);
114+}
115+
116+
117+static void print_version (void) {
118+ printf("%.80s %.80s\n", LUA_VERSION, LUA_COPYRIGHT);
75119 }
76120
77121
78122 static void assign (char *arg) {
79− if (strlen(arg) >= 500)
80− fprintf(stderr, "lua: shell argument too long");
81− else {
82− char buffer[500];
83− char *eq = strchr(arg, '=');
84− lua_pushstring(eq+1);
85− strncpy(buffer, arg, eq-arg);
86− buffer[eq-arg] = 0;
87− lua_setglobal(buffer);
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);
127+}
128+
129+
130+static void getargs (char *argv[]) {
131+ int i;
132+ lua_newtable(L);
133+ for (i=0; argv[i]; i++) {
134+ /* arg[i] = argv[i] */
135+ lua_pushnumber(L, i);
136+ lua_pushstring(L, argv[i]);
137+ lua_settable(L, -3);
138+ }
139+ /* arg.n = maximum index in table `arg' */
140+ lua_pushstring(L, "n");
141+ lua_pushnumber(L, i-1);
142+ lua_settable(L, -3);
143+}
144+
145+
146+static int l_getargs (lua_State *l) {
147+ char **argv = (char **)lua_touserdata(l, -1);
148+ getargs(argv);
149+ return 1;
150+}
151+
152+
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;
88161 }
162+ else
163+ return EXIT_SUCCESS;
89164 }
90165
91166
92−static void manual_input (int prompt) {
167+/* maximum length of an input string */
168+#ifndef MAXINPUT
169+#define MAXINPUT BUFSIZ
170+#endif
171+
172+static void manual_input (int version, int prompt) {
93173 int cont = 1;
174+ if (version) print_version();
94175 while (cont) {
95− char buffer[BUFSIZ];
176+ char buffer[MAXINPUT];
96177 int i = 0;
97− lua_beginblock();
98− if (prompt)
99− printf("%s", lua_getstring(lua_getglobal("_PROMPT")));
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+ }
100186 for(;;) {
101187 int c = getchar();
102188 if (c == EOF) {
@@ -108,81 +194,129 @@ static void manual_input (int prompt) { · 5 unmodified lines
108194 buffer[i-1] = '\n';
109195 else break;
110196 }
111− else if (i >= BUFSIZ-1) {
112− fprintf(stderr, "lua: argument line too long\n");
197+ else if (i >= MAXINPUT-1) {
198+ fprintf(stderr, "lua: input line too long\n");
113199 break;
114200 }
115201 else buffer[i++] = (char)c;
116202 }
117203 buffer[i] = '\0';
118204 ldo(lua_dostring, buffer);
119− lua_endblock();
205+ lua_settop(L, 0); /* remove eventual results */
120206 }
121207 printf("\n");
122208 }
123209
124210
125−int main (int argc, char *argv[])
126−{
127− int i;
128− lua_open();
129− lua_pushstring("> "); lua_setglobal("_PROMPT");
130− lua_userinit();
131− if (argc < 2) { /* no arguments? */
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? */
132214 if (isatty(0)) {
133− printf("%s %s\n", LUA_VERSION, LUA_COPYRIGHT);
134− manual_input(1);
215+ manual_input(1, 1);
135216 }
136217 else
137218 ldo(lua_dofile, NULL); /* executes stdin as a file */
138219 }
139− else for (i=1; i<argc; i++) {
140− if (argv[i][0] == '-') { /* option? */
141− switch (argv[i][1]) {
142− case 0:
143− ldo(lua_dofile, NULL); /* executes stdin as a file */
144− break;
145− case 'i':
146− manual_input(1);
147− break;
148− case 'q':
149− manual_input(0);
150− break;
151− case 'd':
152− lua_setdebug(1);
153− break;
154− case 'v':
155− printf("%s %s\n(written by %s)\n\n",
156− LUA_VERSION, LUA_COPYRIGHT, LUA_AUTHORS);
157− break;
158− case 'e':
159− i++;
160− if (ldo(lua_dostring, argv[i]) != 0) {
161− fprintf(stderr, "lua: error running argument `%s'\n", argv[i]);
162− return 1;
220+ else { /* other arguments; loop over them */
221+ 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;
246+ }
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;
276+ }
277+ default: {
278+ print_message();
279+ return EXIT_FAILURE;
163280 }
164− break;
165− default:
166− print_message();
167− exit(1);
168− }
169− }
170− else if (strchr(argv[i], '='))
171− assign(argv[i]);
172− else {
173− int result = ldo(lua_dofile, argv[i]);
174− if (result) {
175− if (result == 2) {
176− fprintf(stderr, "lua: cannot execute file ");
177− perror(argv[i]);
178281 }
179− exit(1);
180− }
181282 }
182283 }
183−#ifdef DEBUG
184− lua_close();
185−#endif
186− return 0;
284+ return EXIT_SUCCESS;
285+}
286+
287+
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;
296+ }
297+ else
298+ opt->stacksize = 0; /* no stack size */
299+}
300+
301+
302+static void register_getargs (char *argv[]) {
303+ lua_pushuserdata(L, argv);
304+ lua_pushcclosure(L, l_getargs, 1);
305+ lua_setglobal(L, "getargs");
306+}
307+
308+
309+int main (int argc, char *argv[]) {
310+ struct Options opt;
311+ 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;
187321 }
188322
src/luac/Makefile+3−3
@@ -1,12 +1,12 @@
1−# makefile for lua compiler
1+# makefile for Lua compiler
22
33 LUA= ../..
44
55 include $(LUA)/config
66
77 INCS= -I$(INC) $(EXTRA_INCS) -I..
8−OBJS= dump.o luac.o opcode.o opt.o print.o stubs.o test.o
9−SRCS= dump.c luac.c opcode.c opt.c print.c stubs.c test.c luac.h opcode.h
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
1010
1111 T= $(BIN)/luac
1212
src/luac/README+14−20
@@ -1,28 +1,22 @@
1+This is luac, the Lua compiler.
2+There are man pages for it in both nroff and html in ../../doc.
3+
14 luac translates Lua programs into binary files that can be loaded and executed
25 with lua_dofile in C or with dofile in Lua.
3−The main advantages of pre-compiling chunks are: faster loading,
4−protecting source code from user changes, off-line syntax error detection.
6+The main advantages of pre-compiling chunks are: faster loading, protecting
7+source code from user changes, and off-line syntax error detection.
58 luac can also be used to learn about the Lua virtual machine.
69
710 Here are the options that luac understands:
811
9− -c compile (default)
10− -d generate debugging information
11− -D name predefine 'name' for conditional compilation
12− -l list (default for -u)
13− -n save numbers in native format (file may not be portable)
14− -o file output file for -c (default is "luac.out")
15− -O optimize
16− -p parse only
17− -q quiet (default for -c)
18− -t test code integrity
19− -u undump
20− -U name undefine 'name' for conditional compilation
21− -v show version information
22− -V verbose
23− - compile "stdin"
12+ - process stdin
13+ -l list
14+ -o file output file (default is "luac.out")
15+ -p parse only
16+ -s strip debug information
17+ -t test code integrity
18+ -v show version information
2419
25−Finally, luac is an example of how to use the internals of Lua (politely).
26−Also, luac does not need the runtime code and stubs.c makes sure it is not
20+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
2722 linked into luac. This file also shows how to avoid linking the parser.
28−
src/luac/dump.c+70−103
@@ -1,154 +1,121 @@
11 /*
2−** $Id: dump.c,v 1.20 1999/07/02 19:34:26 lhf Exp $
2+** $Id: dump.c,v 1.30 2000/10/31 16:57:23 lhf Exp $
33 ** save bytecodes to file
44 ** See Copyright Notice in lua.h
55 */
66
7−#include <errno.h>
87 #include <stdio.h>
98 #include <stdlib.h>
10−#include "luac.h"
9+#include <string.h>
1110
12−#ifdef OLD_ANSI
13−#define strerror(e) "(no error message provided by operating system)"
14−#endif
11+#include "luac.h"
1512
13+#define DumpVector(b,n,size,D) fwrite(b,size,n,D)
1614 #define DumpBlock(b,size,D) fwrite(b,size,1,D)
17−#define DumpInt DumpLong
15+#define DumpByte fputc
1816
19−static void DumpWord(int i, FILE* D)
17+static void DumpInt(int x, FILE* D)
2018 {
21− int hi= 0x0000FF & (i>>8);
22− int lo= 0x0000FF & i;
23− fputc(hi,D);
24− fputc(lo,D);
19+ DumpBlock(&x,sizeof(x),D);
2520 }
2621
27−static void DumpLong(long i, FILE* D)
22+static void DumpSize(size_t x, FILE* D)
2823 {
29− int hi= 0x00FFFF & (i>>16);
30− int lo= 0x00FFFF & i;
31− DumpWord(hi,D);
32− DumpWord(lo,D);
24+ DumpBlock(&x,sizeof(x),D);
3325 }
3426
35−static void DumpNumber(real x, FILE* D, int native, TProtoFunc* tf)
27+static void DumpNumber(Number x, FILE* D)
3628 {
37− if (native)
38− DumpBlock(&x,sizeof(x),D);
39− else
40− {
41− char b[256];
42− int n;
43− sprintf(b,NUMBER_FMT"%n",x,&n);
44− luaU_str2d(b,tf->source->str); /* help lundump not to fail */
45− fputc(n,D);
46− DumpBlock(b,n,D);
47− }
29+ DumpBlock(&x,sizeof(x),D);
4830 }
4931
50−static void DumpCode(TProtoFunc* tf, FILE* D)
32+static void DumpString(const TString* s, FILE* D)
5133 {
52− int size=luaU_codesize(tf);
53− DumpLong(size,D);
54− DumpBlock(tf->code,size,D);
55−}
56−
57−static void DumpString(char* s, int size, FILE* D)
58−{
59− if (s==NULL)
60− DumpLong(0,D);
34+ if (s==NULL || s->str==NULL)
35+ DumpSize(0,D);
6136 else
6237 {
63− DumpLong(size,D);
64− DumpBlock(s,size,D);
38+ size_t size=s->len+1; /* include trailing '\0' */
39+ DumpSize(size,D);
40+ DumpBlock(s->str,size,D);
6541 }
6642 }
6743
68−static void DumpTString(TaggedString* s, FILE* D)
44+static void DumpCode(const Proto* tf, FILE* D)
6945 {
70− if (s==NULL)
71− DumpString(NULL,0,D);
72− else
73− DumpString(s->str,s->u.s.len+1,D);
46+ DumpInt(tf->ncode,D);
47+ DumpVector(tf->code,tf->ncode,sizeof(*tf->code),D);
7448 }
7549
76−static void DumpLocals(TProtoFunc* tf, FILE* D)
50+static void DumpLocals(const Proto* tf, FILE* D)
7751 {
78− if (tf->locvars==NULL)
79− DumpInt(0,D);
80− else
52+ int i,n=tf->nlocvars;
53+ DumpInt(n,D);
54+ for (i=0; i<n; i++)
8155 {
82− LocVar* v;
83− int n=0;
84− for (v=tf->locvars; v->line>=0; v++)
85− ++n;
86− DumpInt(n,D);
87− for (v=tf->locvars; v->line>=0; v++)
88− {
89− DumpInt(v->line,D);
90− DumpTString(v->varname,D);
91− }
56+ DumpString(tf->locvars[i].varname,D);
57+ DumpInt(tf->locvars[i].startpc,D);
58+ DumpInt(tf->locvars[i].endpc,D);
9259 }
9360 }
9461
95−static void DumpFunction(TProtoFunc* tf, FILE* D, int native);
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);
9669
97−static void DumpConstants(TProtoFunc* tf, FILE* D, int native)
70+static void DumpConstants(const Proto* tf, FILE* D)
9871 {
99− int i,n=tf->nconsts;
100− DumpInt(n,D);
72+ int i,n;
73+ DumpInt(n=tf->nkstr,D);
10174 for (i=0; i<n; i++)
102− {
103− TObject* o=tf->consts+i;
104− fputc(-ttype(o),D); /* ttype(o) is negative - ORDER LUA_T */
105− switch (ttype(o))
106− {
107− case LUA_T_NUMBER:
108− DumpNumber(nvalue(o),D,native,tf);
109− break;
110− case LUA_T_STRING:
111− DumpTString(tsvalue(o),D);
112− break;
113− case LUA_T_PROTO:
114− DumpFunction(tfvalue(o),D,native);
115− break;
116− case LUA_T_NIL:
117− break;
118− default: /* cannot happen */
119− luaU_badconstant("dump",i,o,tf);
120− break;
121− }
122− }
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);
12381 }
12482
125−static void DumpFunction(TProtoFunc* tf, FILE* D, int native)
83+static void DumpFunction(const Proto* tf, FILE* D)
12684 {
85+ DumpString(tf->source,D);
12786 DumpInt(tf->lineDefined,D);
128− DumpTString(tf->source,D);
129− DumpCode(tf,D);
87+ DumpInt(tf->numparams,D);
88+ DumpByte(tf->is_vararg,D);
89+ DumpInt(tf->maxstacksize,D);
13090 DumpLocals(tf,D);
131− DumpConstants(tf,D,native);
91+ DumpLines(tf,D);
92+ DumpConstants(tf,D);
93+ DumpCode(tf,D);
13294 if (ferror(D))
133− luaL_verror("write error" IN ": %s (errno=%d)",INLOC,strerror(errno),errno);
95+ {
96+ perror("luac: write error");
97+ exit(1);
98+ }
13499 }
135100
136−static void DumpHeader(TProtoFunc* Main, FILE* D, int native)
101+static void DumpHeader(FILE* D)
137102 {
138− fputc(ID_CHUNK,D);
103+ DumpByte(ID_CHUNK,D);
139104 fputs(SIGNATURE,D);
140− fputc(VERSION,D);
141− if (native)
142− {
143− fputc(sizeof(real),D);
144− DumpNumber(TEST_NUMBER,D,native,Main);
145− }
146− else
147− fputc(0,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);
148115 }
149116
150−void luaU_dumpchunk(TProtoFunc* Main, FILE* D, int native)
117+void luaU_dumpchunk(const Proto* Main, FILE* D)
151118 {
152− DumpHeader(Main,D,native);
153− DumpFunction(Main,D,native);
119+ DumpHeader(D);
120+ DumpFunction(Main,D);
154121 }
src/luac/luac.c+134−118
@@ -1,5 +1,5 @@
11 /*
2−** $Id: luac.c,v 1.17 1999/07/02 19:34:26 lhf Exp $
2+** $Id: luac.c,v 1.28 2000/11/06 20:06:27 lhf Exp $
33 ** lua compiler (saves bytecodes to files; also list binary files)
44 ** See Copyright Notice in lua.h
55 */
@@ -7,181 +7,197 @@ · 1 unmodified line
77 #include <stdio.h>
88 #include <stdlib.h>
99 #include <string.h>
10−#include "luac.h"
10+
1111 #include "lparser.h"
1212 #include "lstate.h"
1313 #include "lzio.h"
14+#include "luac.h"
1415
1516 #define OUTPUT "luac.out" /* default output file */
1617
17−static FILE* efopen(char* name, char* mode);
18−static void doit(int undump, char* filename);
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);
24+
25+lua_State* lua_state=NULL; /* lazy! */
1926
2027 static int listing=0; /* list bytecodes? */
21−static int debugging=0; /* emit debug information? */
2228 static int dumping=1; /* dump bytecodes? */
23−static int undumping=0; /* undump bytecodes? */
24−static int optimizing=0; /* optimize? */
25−static int parsing=0; /* parse only? */
29+static int stripping=0; /* strip debug information? */
2630 static int testing=0; /* test integrity? */
27−static int verbose=0; /* tell user what is done */
28−static int native=0; /* save numbers in native format? */
29−static FILE* D; /* output file */
31+static const char* output=OUTPUT; /* output file name */
3032
31−static void usage(char* op)
33+#define IS(s) (strcmp(argv[i],s)==0)
34+
35+int main(int argc, const char* argv[])
3236 {
33− if (op) fprintf(stderr,"luac: unrecognized option '%s'\n",op);
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;
55+}
56+
57+static void usage(const char* message, const char* arg)
58+{
59+ if (message!=NULL)
60+ {
61+ fprintf(stderr,"luac: "); fprintf(stderr,message,arg); fprintf(stderr,"\n");
62+ }
3463 fprintf(stderr,
3564 "usage: luac [options] [filenames]. Available options are:\n"
36− " -c\t\tcompile (default)\n"
37− " -d\t\tgenerate debugging information\n"
38− " -D name\tpredefine 'name' for conditional compilation\n"
39− " -l\t\tlist (default for -u)\n"
40− " -n\t\tsave numbers in native format (file may not be portable)\n"
41− " -o file\toutput file for -c (default is \"" OUTPUT "\")\n"
42− " -O\t\toptimize\n"
43− " -p\t\tparse only\n"
44− " -q\t\tquiet (default for -c)\n"
45− " -t\t\ttest code integrity\n"
46− " -u\t\tundump\n"
47− " -U name\tundefine 'name' for conditional compilation\n"
48− " -v\t\tshow version information\n"
49− " -V\t\tverbose\n"
50− " -\t\tcompile \"stdin\"\n"
65+ " - process stdin\n"
66+ " -l list\n"
67+ " -o file output file (default is \"" OUTPUT "\")\n"
68+ " -p parse only\n"
69+ " -s strip debug information\n"
70+ " -t test code integrity\n"
71+ " -v show version information\n"
5172 );
5273 exit(1);
5374 }
5475
55−#define IS(s) (strcmp(argv[i],s)==0)
56−
57−int main(int argc, char* argv[])
76+static int doargs(int argc, const char* argv[])
5877 {
59− char* d=OUTPUT; /* output file name */
6078 int i;
61− lua_open();
6279 for (i=1; i<argc; i++)
6380 {
64− if (argv[i][0]!='-') /* end of options */
81+ if (*argv[i]!='-') /* end of options */
6582 break;
6683 else if (IS("-")) /* end of options; use stdin */
67− break;
68− else if (IS("-c")) /* compile (and dump) */
69− {
70− dumping=1;
71− undumping=0;
72− }
73− else if (IS("-D")) /* $define */
74− {
75− TaggedString* s=luaS_new(argv[++i]);
76− s->u.s.globalval.ttype=LUA_T_NUMBER;
77− s->u.s.globalval.value.n=1;
78− }
79− else if (IS("-d")) /* debug */
80− debugging=1;
84+ return i;
8185 else if (IS("-l")) /* list */
8286 listing=1;
83− else if (IS("-n")) /* native */
84− native=1;
8587 else if (IS("-o")) /* output file */
86− d=argv[++i];
87− else if (IS("-O")) /* optimize */
88− optimizing=1;
89− else if (IS("-p")) /* parse only */
9088 {
91− dumping=0;
92− parsing=1;
89+ output=argv[++i];
90+ if (output==NULL) usage(NULL,NULL);
9391 }
94− else if (IS("-q")) /* quiet */
95− listing=0;
92+ else if (IS("-p")) /* parse only */
93+ dumping=0;
94+ else if (IS("-s")) /* strip debug information */
95+ stripping=1;
9696 else if (IS("-t")) /* test */
97− testing=1;
98− else if (IS("-u")) /* undump */
9997 {
98+ testing=1;
10099 dumping=0;
101− undumping=1;
102− listing=1;
103− }
104− else if (IS("-U")) /* undefine */
105− {
106− TaggedString* s=luaS_new(argv[++i]);
107− s->u.s.globalval.ttype=LUA_T_NIL;
108100 }
109101 else if (IS("-v")) /* show version */
110− printf("%s %s\n(written by %s)\n\n",LUA_VERSION,LUA_COPYRIGHT,LUA_AUTHORS);
111− else if (IS("-V")) /* verbose */
112− verbose=1;
113− else /* unknown option */
114− usage(argv[i]);
115− }
116− --i; /* fake new argv[0] */
117− argc-=i;
118− argv+=i;
119− if (dumping || parsing)
120− {
121− if (argc<2) usage(NULL);
122− if (dumping)
123102 {
124− for (i=1; i<argc; i++) /* play safe with output file */
125− if (IS(d)) luaL_verror("will not overwrite input file \"%s\"",d);
126− D=efopen(d,"wb"); /* must open in binary mode */
103+ printf("%s %s\n",LUA_VERSION,LUA_COPYRIGHT);
104+ if (argc==2) exit(0);
127105 }
128− for (i=1; i<argc; i++) doit(0,IS("-")? NULL : argv[i]);
129− if (dumping) fclose(D);
106+ else /* unknown option */
107+ usage("unrecognized option `%s'",argv[i]);
130108 }
131− if (undumping)
109+ if (i==argc && (listing || testing))
132110 {
133− if (argc<2)
134− doit(1,OUTPUT);
135− else
136− for (i=1; i<argc; i++) doit(1,IS("-")? NULL : argv[i]);
111+ dumping=0;
112+ argv[--i]=OUTPUT;
137113 }
138− return 0;
114+ return i;
139115 }
140116
141−static void do_compile(ZIO* z)
117+static Proto* load(const char* filename)
142118 {
143− TProtoFunc* Main;
144− if (optimizing) L->debug=0;
145− if (debugging) L->debug=1;
146− Main=luaY_parser(z);
147− if (optimizing) luaU_optchunk(Main);
148− if (listing) luaU_printchunk(Main);
149− if (testing) luaU_testchunk(Main);
150− if (dumping) luaU_dumpchunk(Main,D,native);
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;
151149 }
152150
153−static void do_undump(ZIO* z)
151+static Proto* combine(Proto** P, int n)
154152 {
155− for (;;)
153+ if (n==1)
154+ return P[0];
155+ else
156156 {
157− TProtoFunc* Main=luaU_undump1(z);
158− if (Main==NULL) break;
159− if (optimizing) luaU_optchunk(Main);
160− if (listing) luaU_printchunk(Main);
161− if (testing) luaU_testchunk(Main);
157+ 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);
165+ for (i=0; i<n; i++)
166+ {
167+ tf->code[pc++]=CREATE_AB(OP_CLOSURE,i,0);
168+ tf->code[pc++]=CREATE_AB(OP_CALL,0,0);
169+ }
170+ tf->code[pc++]=OP_END;
171+ return tf;
162172 }
163173 }
164174
165−static void doit(int undump, char* filename)
175+static void strip(Proto* tf)
166176 {
167− FILE* f= (filename==NULL) ? stdin : efopen(filename, undump ? "rb" : "r");
168− ZIO z;
169− char source[255+2]; /* +2 for '@' and '\0' */
170− luaL_filesource(source,filename,sizeof(source));
171− zFopen(&z,f,source);
172− if (verbose) fprintf(stderr,"%s\n",source+1);
173− if (undump) do_undump(&z); else do_compile(&z);
174− if (f!=stdin) fclose(f);
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]);
175184 }
176185
177−static FILE* efopen(char* name, char* mode)
186+static FILE* efopen(const char* name, const char* mode)
178187 {
179188 FILE* f=fopen(name,mode);
180189 if (f==NULL)
181190 {
182− fprintf(stderr,"luac: cannot open %sput file ",mode[0]=='r' ? "in" : "out");
191+ fprintf(stderr,"luac: cannot open %sput file ",*mode=='r' ? "in" : "out");
183192 perror(name);
184193 exit(1);
185194 }
186195 return f;
187196 }
197+
198+void luaU_testchunk(const Proto* Main)
199+{
200+ UNUSED(Main);
201+ fprintf(stderr,"luac: -t not operational in this version\n");
202+ exit(1);
203+}
src/luac/luac.h+10−27
@@ -1,48 +1,31 @@
11 /*
2−** $Id: luac.h,v 1.11 1999/07/02 19:34:26 lhf Exp $
2+** $Id: luac.h,v 1.18 2000/10/31 16:57:23 lhf Exp $
33 ** definitions for luac
44 ** See Copyright Notice in lua.h
55 */
66
7−#include "lauxlib.h"
7+#include "ldebug.h"
88 #include "lfunc.h"
99 #include "lmem.h"
1010 #include "lobject.h"
1111 #include "lopcodes.h"
1212 #include "lstring.h"
13+#include "ltable.h"
1314 #include "lundump.h"
1415
15−typedef struct
16−{
17− char* name; /* name of opcode */
18− int op; /* value of opcode */
19− int class; /* class of opcode (byte variant) */
20− int args; /* types of arguments (operands) */
21− int arg; /* arg #1 */
22− int arg2; /* arg #2 */
23−} Opcode;
16+extern lua_State *lua_state;
17+#define L lua_state /* lazy! */
2418
2519 /* from dump.c */
26−void luaU_dumpchunk(TProtoFunc* Main, FILE* D, int native);
27−
28−/* from opcode.c */
29−int luaU_opcodeinfo(TProtoFunc* tf, Byte* p, Opcode* I, char* xFILE, int xLINE);
30−int luaU_codesize(TProtoFunc* tf);
20+void luaU_dumpchunk(const Proto* Main, FILE* D);
3121
3222 /* from opt.c */
33−void luaU_optchunk(TProtoFunc* Main);
23+void luaU_optchunk(Proto* Main);
3424
3525 /* from print.c */
36−void luaU_printchunk(TProtoFunc* Main);
26+void luaU_printchunk(const Proto* Main);
3727
3828 /* from test.c */
39−void luaU_testchunk(TProtoFunc* Main);
40−TObject* luaU_getconstant(TProtoFunc* tf, int i, int at);
41−
42−#define INFO(tf,p,I) luaU_opcodeinfo(tf,p,I,__FILE__,__LINE__)
29+void luaU_testchunk(const Proto* Main);
4330
44−/* fake (but convenient) opcodes */
45−#define NOP 255
46−#define STACK (-1)
47−#define ARGS (-2)
48−#define VARARGS (-3)
31+#define Sizeof(x) ((int)sizeof(x))
src/luac/opcode.c+0−102
@@ -1,102 +0,0 @@
1−/*
2−** $Id: opcode.c,v 1.9 1999/05/25 19:58:55 lhf Exp $
3−** opcode information
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include "luac.h"
8−
9−enum { /* for Opcode.args */
10− ARGS_NONE,
11− ARGS_B,
12− ARGS_W,
13− ARGS_BB,
14− ARGS_WB
15−};
16−
17−static Opcode Info[]= /* ORDER lopcodes.h */
18−{
19−#include "opcode.h"
20−};
21−
22−static Opcode Fake[]= /* ORDER luac.h */
23−{
24−{ "NOP", NOP, NOP, ARGS_NONE, -1, -1 },
25−{ "STACK", STACK, STACK, ARGS_B, -1, -1 },
26−{ "ARGS", ARGS, ARGS, ARGS_B, -1, -1 },
27−{ "VARARGS", VARARGS, VARARGS, ARGS_B, -1, -1 },
28−};
29−
30−#define NOPCODES (sizeof(Info)/sizeof(Info[0]))
31−
32−int luaU_opcodeinfo(TProtoFunc* tf, Byte* p, Opcode* I, char* xFILE, int xLINE)
33−{
34− Opcode OP;
35− Byte* code=tf->code;
36− int op=*p;
37− int size=1;
38− if (p==code) /* first byte is STACK */
39− {
40− OP=Fake[-STACK];
41− OP.arg=op;
42− }
43− else if (p==code+1) /* second byte is ARGS or VARARGS */
44− {
45− if (op<ZEROVARARG)
46− {
47− OP=Fake[-ARGS];
48− OP.arg=op;
49− }
50− else
51− {
52− OP=Fake[-VARARGS];
53− OP.arg=op-ZEROVARARG;
54− }
55− }
56− else if (op==NOP) /* NOP is fake */
57− {
58− OP=Fake[0];
59− }
60− else if (op>=NOPCODES) /* cannot happen */
61− {
62− luaL_verror("[%s:%d] bad opcode %d at pc=%d" IN,
63− xFILE,xLINE,op,(int)(p-code),INLOC);
64− return 0;
65− }
66− else /* ordinary opcode */
67− {
68− OP=Info[op];
69− switch (OP.args)
70− {
71− case ARGS_NONE: size=1;
72− break;
73− case ARGS_B: size=2; OP.arg=p[1];
74− break;
75− case ARGS_W: size=3; OP.arg=(p[1]<<8)+p[2];
76− break;
77− case ARGS_BB: size=3; OP.arg=p[1]; OP.arg2=p[2];
78− break;
79− case ARGS_WB: size=4; OP.arg=(p[1]<<8)+p[2]; OP.arg2=p[3];
80− break;
81− default: /* cannot happen */
82− luaL_verror("[%s:%d] bad args %d for %s at pc=%d" IN,
83− __FILE__,__LINE__,OP.args,OP.name,(int)(p-code),INLOC);
84− break;
85− }
86− }
87− *I=OP;
88− return size;
89−}
90−
91−int luaU_codesize(TProtoFunc* tf)
92−{
93− Byte* code=tf->code;
94− Byte* p=code;
95− for (;;)
96− {
97− Opcode OP;
98− p+=INFO(tf,p,&OP);
99− if (OP.op==ENDCODE) break;
100− }
101− return p-code;
102−}
src/luac/opcode.h+0−70
@@ -1,70 +0,0 @@
1−/*
2−** $Id: opcode.h,v 1.1 1999/03/25 13:43:05 lhf Exp $
3−** opcode info to be #included into opcode.c
4−** extracted automatically from lopcodes.h by mkopcodeh -- DO NOT EDIT
5−** See Copyright Notice in lua.h
6−*/
7−{ "ENDCODE", ENDCODE, ENDCODE, ARGS_NONE, -1, -1 },
8−{ "RETCODE", RETCODE, RETCODE, ARGS_B, -1, -1 },
9−{ "CALL", CALL, CALL, ARGS_BB, -1, -1 },
10−{ "TAILCALL", TAILCALL, TAILCALL, ARGS_BB, -1, -1 },
11−{ "PUSHNIL", PUSHNIL, PUSHNIL, ARGS_B, -1, -1 },
12−{ "POP", POP, POP, ARGS_B, -1, -1 },
13−{ "PUSHNUMBERW", PUSHNUMBERW, PUSHNUMBER, ARGS_W, -1, -1 },
14−{ "PUSHNUMBER", PUSHNUMBER, PUSHNUMBER, ARGS_B, -1, -1 },
15−{ "PUSHNUMBERNEGW", PUSHNUMBERNEGW, PUSHNUMBERNEG, ARGS_W, -1, -1 },
16−{ "PUSHNUMBERNEG", PUSHNUMBERNEG, PUSHNUMBERNEG, ARGS_B, -1, -1 },
17−{ "PUSHCONSTANTW", PUSHCONSTANTW, PUSHCONSTANT, ARGS_W, -1, -1 },
18−{ "PUSHCONSTANT", PUSHCONSTANT, PUSHCONSTANT, ARGS_B, -1, -1 },
19−{ "PUSHUPVALUE", PUSHUPVALUE, PUSHUPVALUE, ARGS_B, -1, -1 },
20−{ "PUSHLOCAL", PUSHLOCAL, PUSHLOCAL, ARGS_B, -1, -1 },
21−{ "GETGLOBALW", GETGLOBALW, GETGLOBAL, ARGS_W, -1, -1 },
22−{ "GETGLOBAL", GETGLOBAL, GETGLOBAL, ARGS_B, -1, -1 },
23−{ "GETTABLE", GETTABLE, GETTABLE, ARGS_NONE, -1, -1 },
24−{ "GETDOTTEDW", GETDOTTEDW, GETDOTTED, ARGS_W, -1, -1 },
25−{ "GETDOTTED", GETDOTTED, GETDOTTED, ARGS_B, -1, -1 },
26−{ "PUSHSELFW", PUSHSELFW, PUSHSELF, ARGS_W, -1, -1 },
27−{ "PUSHSELF", PUSHSELF, PUSHSELF, ARGS_B, -1, -1 },
28−{ "CREATEARRAYW", CREATEARRAYW, CREATEARRAY, ARGS_W, -1, -1 },
29−{ "CREATEARRAY", CREATEARRAY, CREATEARRAY, ARGS_B, -1, -1 },
30−{ "SETLOCAL", SETLOCAL, SETLOCAL, ARGS_B, -1, -1 },
31−{ "SETGLOBALW", SETGLOBALW, SETGLOBAL, ARGS_W, -1, -1 },
32−{ "SETGLOBAL", SETGLOBAL, SETGLOBAL, ARGS_B, -1, -1 },
33−{ "SETTABLEPOP", SETTABLEPOP, SETTABLEPOP, ARGS_NONE, -1, -1 },
34−{ "SETTABLE", SETTABLE, SETTABLE, ARGS_B, -1, -1 },
35−{ "SETLISTW", SETLISTW, SETLIST, ARGS_WB, -1, -1 },
36−{ "SETLIST", SETLIST, SETLIST, ARGS_BB, -1, -1 },
37−{ "SETMAP", SETMAP, SETMAP, ARGS_B, -1, -1 },
38−{ "NEQOP", NEQOP, NEQOP, ARGS_NONE, -1, -1 },
39−{ "EQOP", EQOP, EQOP, ARGS_NONE, -1, -1 },
40−{ "LTOP", LTOP, LTOP, ARGS_NONE, -1, -1 },
41−{ "LEOP", LEOP, LEOP, ARGS_NONE, -1, -1 },
42−{ "GTOP", GTOP, GTOP, ARGS_NONE, -1, -1 },
43−{ "GEOP", GEOP, GEOP, ARGS_NONE, -1, -1 },
44−{ "ADDOP", ADDOP, ADDOP, ARGS_NONE, -1, -1 },
45−{ "SUBOP", SUBOP, SUBOP, ARGS_NONE, -1, -1 },
46−{ "MULTOP", MULTOP, MULTOP, ARGS_NONE, -1, -1 },
47−{ "DIVOP", DIVOP, DIVOP, ARGS_NONE, -1, -1 },
48−{ "POWOP", POWOP, POWOP, ARGS_NONE, -1, -1 },
49−{ "CONCOP", CONCOP, CONCOP, ARGS_NONE, -1, -1 },
50−{ "MINUSOP", MINUSOP, MINUSOP, ARGS_NONE, -1, -1 },
51−{ "NOTOP", NOTOP, NOTOP, ARGS_NONE, -1, -1 },
52−{ "ONTJMPW", ONTJMPW, ONTJMP, ARGS_W, -1, -1 },
53−{ "ONTJMP", ONTJMP, ONTJMP, ARGS_B, -1, -1 },
54−{ "ONFJMPW", ONFJMPW, ONFJMP, ARGS_W, -1, -1 },
55−{ "ONFJMP", ONFJMP, ONFJMP, ARGS_B, -1, -1 },
56−{ "JMPW", JMPW, JMP, ARGS_W, -1, -1 },
57−{ "JMP", JMP, JMP, ARGS_B, -1, -1 },
58−{ "IFFJMPW", IFFJMPW, IFFJMP, ARGS_W, -1, -1 },
59−{ "IFFJMP", IFFJMP, IFFJMP, ARGS_B, -1, -1 },
60−{ "IFTUPJMPW", IFTUPJMPW, IFTUPJMP, ARGS_W, -1, -1 },
61−{ "IFTUPJMP", IFTUPJMP, IFTUPJMP, ARGS_B, -1, -1 },
62−{ "IFFUPJMPW", IFFUPJMPW, IFFUPJMP, ARGS_W, -1, -1 },
63−{ "IFFUPJMP", IFFUPJMP, IFFUPJMP, ARGS_B, -1, -1 },
64−{ "CLOSUREW", CLOSUREW, CLOSURE, ARGS_WB, -1, -1 },
65−{ "CLOSURE", CLOSURE, CLOSURE, ARGS_BB, -1, -1 },
66−{ "SETLINEW", SETLINEW, SETLINE, ARGS_W, -1, -1 },
67−{ "SETLINE", SETLINE, SETLINE, ARGS_B, -1, -1 },
68−{ "LONGARGW", LONGARGW, LONGARG, ARGS_W, -1, -1 },
69−{ "LONGARG", LONGARG, LONGARG, ARGS_B, -1, -1 },
70−{ "CHECKSTACK", CHECKSTACK, CHECKSTACK, ARGS_B, -1, -1 },
src/luac/opt.c+86−240
@@ -1,5 +1,5 @@
11 /*
2−** $Id: opt.c,v 1.12 1999/07/02 19:34:26 lhf Exp $
2+** $Id: opt.c,v 1.22 2000/10/31 16:57:23 lhf Exp $
33 ** optimize bytecodes
44 ** See Copyright Notice in lua.h
55 */
@@ -7,275 +7,121 @@ · 1 unmodified line
77 #include <stdio.h>
88 #include <stdlib.h>
99 #include <string.h>
10−#include "luac.h"
1110
12−static void FixArg(Byte* p, int i, int j, int isconst)
13−{
14− if (j==i)
15− ;
16− else if (i<=MAX_BYTE) /* j<i, so j fits where i did */
17− p[1]=j;
18− else if (i<=MAX_WORD)
19− {
20− if (isconst && j<=MAX_BYTE) /* may use byte variant instead */
21− {
22− p[0]++; /* byte variant follows word variant */
23− p[1]=j;
24− p[2]=NOP;
25− }
26− else /* stuck with word variant */
27− {
28− p[1]=j>>8;
29− p[2]=j;
30− }
31− }
32− else /* previous instruction must've been LONGARG */
33− {
34− if (isconst && j<=MAX_WORD) p[-2]=p[-1]=NOP; else p[-1]=j>>16;
35− p[1]=j>>8;
36− p[2]=j;
37− }
38−}
11+#include "luac.h"
3912
40−static void FixConstants(TProtoFunc* tf, int* C)
13+static int MapConstant(Hash* t, int j, const TObject* key)
4114 {
42− Byte* code=tf->code;
43− Byte* p=code;
44− int longarg=0;
45− for (;;)
15+ const TObject* o=luaH_get(L,t,key);
16+ if (ttype(o)==LUA_TNUMBER)
17+ return (int) nvalue(o);
18+ else
4619 {
47− Opcode OP;
48− int n=INFO(tf,p,&OP);
49− int op=OP.class;
50− int i=OP.arg+longarg;
51− longarg=0;
52− if (op==PUSHCONSTANT || op==GETGLOBAL || op==GETDOTTED ||
53− op==PUSHSELF || op==SETGLOBAL || op==CLOSURE)
54− FixArg(p,i,C[i],1);
55− else if (op==LONGARG) longarg=i<<16;
56− else if (op==ENDCODE) break;
57− p+=n;
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;
5826 }
5927 }
6028
61−#define UNREF 1 /* "type" of unused constants */
62−#define BIAS 128 /* mark for used constants */
63−
64−static void NoUnrefs(TProtoFunc* tf)
29+static int MapConstants(Proto* tf, Hash* map)
6530 {
66− int i,n=tf->nconsts;
67− Byte* code=tf->code;
68− Byte* p=code;
69− int longarg=0;
70− for (;;) /* mark all used constants */
71− {
72− Opcode OP;
73− int n=INFO(tf,p,&OP);
74− int op=OP.class;
75− int i=OP.arg+longarg;
76− longarg=0;
77− if (op==PUSHCONSTANT || op==GETGLOBAL || op==GETDOTTED ||
78− op==PUSHSELF || op==SETGLOBAL || op==CLOSURE)
79− {
80− TObject* o=tf->consts+i;
81− if (ttype(o)<=0) ttype(o)+=BIAS; /* mark as used */
82− }
83− else if (op==LONGARG) longarg=i<<16;
84− else if (op==ENDCODE) break;
85− p+=n;
86− }
87− for (i=0; i<n; i++) /* mark all unused constants */
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++)
8835 {
89− TObject* o=tf->consts+i;
90− if (ttype(o)<=0)
91− ttype(o)=UNREF; /* mark as unused */
92− else
93− ttype(o)-=BIAS; /* unmark used constant */
36+ nvalue(&o)=tf->knum[i];
37+ k=MapConstant(map,j,&o);
38+ if (k==j) j++;
9439 }
95−}
96−
97−#define CMP(oa,ob,f) memcmp(&f(oa),&f(ob),sizeof(f(oa)))
98−
99−static int compare(TProtoFunc* tf, int ia, int ib)
100−{
101− TObject* oa=tf->consts+ia;
102− TObject* ob=tf->consts+ib;
103− int t=ttype(oa)-ttype(ob);
104− if (t) return t;
105− switch (ttype(oa))
40+ m=j;
41+ j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
42+ for (i=0; i<n; i++)
10643 {
107− case LUA_T_NUMBER: return CMP(oa,ob,nvalue);
108− case LUA_T_STRING: return CMP(oa,ob,tsvalue);
109− case LUA_T_PROTO: return CMP(oa,ob,tfvalue);
110− case LUA_T_NIL: return 0;
111− case UNREF: return 0;
112− default: return ia-ib; /* cannot happen */
44+ tsvalue(&o)=tf->kstr[i];
45+ k=MapConstant(map,j,&o);
46+ if (k==j) j++;
11347 }
48+ return m+j;
11449 }
11550
116−static TProtoFunc* TF; /* for sort */
117−
118−static int compare1(const void* a, const void* b)
119−{
120− int ia=*(int*)a;
121− int ib=*(int*)b;
122− int t=compare(TF,ia,ib);
123− return (t) ? t : ia-ib;
124−}
125−
126−static void OptConstants(TProtoFunc* tf)
51+static void PackConstants(Proto* tf, Hash* map)
12752 {
128− static int* C=NULL;
129− static int* D=NULL;
130− int i,k;
131− int n=tf->nconsts;
132− if (n==0) return;
133− luaM_reallocvector(C,n,int);
134− luaM_reallocvector(D,n,int);
135− NoUnrefs(tf);
136− for (i=0; i<n; i++) C[i]=D[i]=i; /* group duplicates */
137− TF=tf; qsort(C,n,sizeof(C[0]),compare1);
138− k=C[0]; /* build duplicate table */
139− for (i=1; i<n; i++)
140− {
141− int j=C[i];
142− if (compare(tf,k,j)==0) D[j]=k; else k=j;
143− }
144− k=0; /* build rename map & pack constants */
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;
14559 for (i=0; i<n; i++)
14660 {
147− if (D[i]==i) /* new value */
148− {
149− TObject* o=tf->consts+i;
150− if (ttype(o)!=UNREF)
151− {
152− tf->consts[k]=tf->consts[i];
153− C[i]=k++;
154− }
155− }
156− else C[i]=C[D[i]];
61+ nvalue(&o)=tf->knum[i];
62+ k=MapConstant(map,-1,&o);
63+ if (k==j) tf->knum[j++]=tf->knum[i];
15764 }
158− if (k<n)
65+ tf->nknum=j;
66+ j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
67+ for (i=0; i<n; i++)
15968 {
160−printf("\t" SOURCE " reduced constants from %d to %d\n",
161− tf->source->str,tf->lineDefined,n,k);
162− FixConstants(tf,C);
163− tf->nconsts=k;
69+ tsvalue(&o)=tf->kstr[i];
70+ k=MapConstant(map,-1,&o);
71+ if (k==j) tf->kstr[j++]=tf->kstr[i];
16472 }
73+ tf->nkstr=j;
74+#ifdef DEBUG
75+ printf("%p after pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
76+#endif
16577 }
16678
167−static int NoDebug(TProtoFunc* tf)
79+static void OptConstants(Proto* tf)
16880 {
169− Byte* code=tf->code;
170− Byte* p=code;
171− int lop=NOP; /* last opcode */
172− int nop=0;
173− for (;;) /* change SETLINE to NOP */
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++)
17490 {
175− Opcode OP;
176− int n=INFO(tf,p,&OP);
177− int op=OP.class;
178− if (op==NOP) ++nop;
179− else if (op==SETLINE)
91+ Instruction i=*p;
92+ int op=GET_OPCODE(i);
93+ switch (op)
18094 {
181− int m;
182− if (lop==LONGARG) m=2; else if (lop==LONGARGW) m=3; else m=0;
183− nop+=n+m; memset(p-m,NOP,n+m);
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;
184116 }
185− else if (op==ENDCODE) break;
186− lop=OP.op;
187− p+=n;
188117 }
189− return nop;
190118 }
191119
192−static int FixJump(TProtoFunc* tf, Byte* a, Byte* b)
193−{
194− Byte* p;
195− int nop=0;
196− for (p=a; p<b; )
197− {
198− Opcode OP;
199− int n=INFO(tf,p,&OP);
200− int op=OP.class;
201− if (op==NOP) ++nop;
202− else if (op==ENDCODE) break;
203− p+=n;
204− }
205− return nop;
206−}
120+#define OptFunction luaU_optchunk
207121
208−static void FixJumps(TProtoFunc* tf)
209−{
210− Byte* code=tf->code;
211− Byte* p=code;
212− int longarg=0;
213− for (;;)
214− {
215− Opcode OP;
216− int n=INFO(tf,p,&OP);
217− int op=OP.class;
218− int i=OP.arg+longarg;
219− int nop=0;
220− longarg=0;
221− if (op==ENDCODE) break;
222− else if (op==IFTUPJMP || op==IFFUPJMP)
223− nop=FixJump(tf,p-i+n,p);
224− else if (op==ONTJMP || op==ONFJMP || op==JMP || op==IFFJMP)
225− nop=FixJump(tf,p,p+i+n);
226− else if (op==LONGARG) longarg=i<<16;
227− if (nop>0) FixArg(p,i,i-nop,0);
228− p+=n;
229− }
230−}
231−
232−static void PackCode(TProtoFunc* tf)
233−{
234− Byte* code=tf->code;
235− Byte* p=code;
236− Byte* q=code;
237− for (;;)
238− {
239− Opcode OP;
240− int n=INFO(tf,p,&OP);
241− int op=OP.class;
242− if (op!=NOP) { memcpy(q,p,n); q+=n; }
243− p+=n;
244− if (op==ENDCODE) break;
245− }
246−printf("\t" SOURCE " reduced code from %d to %d\n",
247− tf->source->str,tf->lineDefined,(int)(p-code),(int)(q-code));
248−}
249−
250−static void OptCode(TProtoFunc* tf)
251−{
252− if (NoDebug(tf)==0) return; /* cannot improve code */
253− FixJumps(tf);
254− PackCode(tf);
255−}
256−
257−static void OptFunction(TProtoFunc* tf);
258−
259−static void OptFunctions(TProtoFunc* tf)
260−{
261− int i,n=tf->nconsts;
262− for (i=0; i<n; i++)
263− {
264− TObject* o=tf->consts+i;
265− if (ttype(o)==LUA_T_PROTO) OptFunction(tfvalue(o));
266− }
267−}
268−
269−static void OptFunction(TProtoFunc* tf)
122+void OptFunction(Proto* tf)
270123 {
124+ int i,n=tf->nkproto;
271125 OptConstants(tf);
272− OptCode(tf);
273− OptFunctions(tf);
274− tf->source=luaS_new("");
275− tf->locvars=NULL;
276−}
277−
278−void luaU_optchunk(TProtoFunc* Main)
279−{
280− OptFunction(Main);
126+ for (i=0; i<n; i++) OptFunction(tf->kproto[i]);
281127 }
src/luac/print.c+64−188
@@ -1,223 +1,99 @@
11 /*
2−** $Id: print.c,v 1.21 1999/05/25 19:58:55 lhf Exp $
2+** $Id: print.c,v 1.32 2000/11/06 20:04:36 lhf Exp $
33 ** print bytecodes
44 ** See Copyright Notice in lua.h
55 */
66
77 #include <stdio.h>
88 #include <stdlib.h>
9+
910 #include "luac.h"
1011
11−#ifdef DEBUG
12−static void PrintConstants(TProtoFunc* tf)
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)
1326 {
14− int i,n=tf->nconsts;
15− printf("constants (%d) for %p:\n",n,tf);
16− for (i=0; i<n; i++)
27+ const char* s=tf->kstr[n]->str;
28+ printf("%d\t; ",n);
29+ putchar('"');
30+ for (; *s; s++)
1731 {
18− TObject* o=tf->consts+i;
19− printf("%6d ",i);
20− switch (ttype(o))
32+ switch (*s)
2133 {
22− case LUA_T_NUMBER:
23− printf("N " NUMBER_FMT "\n",(double)nvalue(o));
24− break;
25− case LUA_T_STRING:
26− printf("S %p\t\"%s\"\n",tsvalue(o),svalue(o));
27− break;
28− case LUA_T_PROTO:
29− printf("F %p\n",tfvalue(o));
30− break;
31− case LUA_T_NIL:
32− printf("nil\n");
33− break;
34− default: /* cannot happen */
35− printf("? type=%d\n",ttype(o));
36− break;
34+ case '"': printf("\\\""); break;
35+ case '\a': printf("\\a"); break;
36+ case '\b': printf("\\b"); break;
37+ case '\f': printf("\\f"); break;
38+ case '\n': printf("\\n"); break;
39+ case '\r': printf("\\r"); break;
40+ case '\t': printf("\\t"); break;
41+ case '\v': printf("\\v"); break;
42+ default: putchar(*s); break;
3743 }
3844 }
45+ putchar('"');
3946 }
40−#endif
4147
42−static void PrintConstant(TProtoFunc* tf, int i, int at)
48+static void PrintLocal(const Proto* tf, int n, int pc)
4349 {
44− TObject* o=luaU_getconstant(tf,i,at);
45− switch (ttype(o))
46− {
47− case LUA_T_NUMBER:
48− printf(NUMBER_FMT,(double)nvalue(o));
49− break;
50− case LUA_T_STRING:
51− printf("\"%s\"",svalue(o));
52− break;
53− case LUA_T_PROTO:
54− printf("function at %p",(void*)tfvalue(o));
55− break;
56− case LUA_T_NIL:
57− printf("(nil)");
58− break;
59− default: /* cannot happen */
60− luaU_badconstant("print",i,o,tf);
61− break;
62− }
50+ const char* s=luaF_getlocalname(tf,n+1,pc);
51+ printf("%u",n);
52+ if (s!=NULL) printf("\t; %s",s);
6353 }
6454
65−static void PrintCode(TProtoFunc* tf)
55+static void PrintCode(const Proto* tf)
6656 {
67− Byte* code=tf->code;
68− Byte* p=code;
69− int line=0;
70− int longarg=0;
57+ const Instruction* code=tf->code;
58+ const Instruction* p=code;
7159 for (;;)
7260 {
73− Opcode OP;
74− int n=INFO(tf,p,&OP);
75− int i=OP.arg+longarg;
76− int at=p-code;
77− longarg=0;
78− printf("%6d ",at);
79− {
80− Byte* q=p;
81− int j=n;
82− while (j--) printf("%02X",*q++);
83− }
84− printf("%*s%-14s ",2*(5-n),"",OP.name);
85− if (OP.arg >=0) printf("%d",i);
86− if (OP.arg2>=0) printf(" %d",OP.arg2);
87−
88− switch (OP.class)
89− {
90−
91− case ENDCODE:
92− printf("\n");
93− return;
94−
95− case PUSHCONSTANT:
96− case GETGLOBAL:
97− case SETGLOBAL:
98− case GETDOTTED:
99− case PUSHSELF:
100− case CLOSURE:
101− printf("\t; ");
102− PrintConstant(tf,i,at);
103− break;
104−
105− case PUSHLOCAL:
106− case SETLOCAL:
107− {
108− char* s=luaF_getlocalname(tf,i+1,line);
109− if (s) printf("\t; %s",s);
110− break;
111− }
112−
113− case SETLINE:
114− printf("\t; " SOURCE,tf->source->str,line=i);
115− break;
116−
117− case LONGARG:
118− longarg=i<<16;
119− break;
120−
121−/* suggested by Norman Ramsey <nr@cs.virginia.edu> */
122− case ONTJMP:
123− case ONFJMP:
124− case JMP:
125− case IFFJMP:
126− printf("\t; to %d",at+i+n);
127− break;
128− case IFTUPJMP:
129− case IFFUPJMP:
130− printf("\t; to %d",at-i+n);
131− break;
132−
133− }
134− printf("\n");
135− p+=n;
136− }
137−}
138−
139−static void PrintLocals(TProtoFunc* tf)
140−{
141− LocVar* v=tf->locvars;
142− int n,i;
143− if (v==NULL || v->line<0) return;
144− n=tf->code[1]; if (n>=ZEROVARARG) n-=ZEROVARARG;
145− printf("locals:");
146− for (i=0; i<n; v++,i++) /* arguments */
147− printf(" %s",v->varname->str);
148− for (; v->line>=0; v++)
149− {
150− if (v->varname==NULL)
151− {
152− --i; if (i<0) luaL_verror("bad locvars[%d]",v-tf->locvars); else printf(")");
153− }
154− else
155− {
156− ++i; printf(" (%s",v->varname->str);
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"
15768 }
69+ printf("\n");
70+ if (i==OP_END) break;
71+ p++;
15872 }
159− i-=n;
160− while (i--) printf(")");
161− printf("\n");
16273 }
16374
16475 #define IsMain(tf) (tf->lineDefined==0)
16576
166−static void PrintHeader(TProtoFunc* tf, TProtoFunc* Main, int at)
167−{
168− int size=luaU_codesize(tf);
169− if (IsMain(tf))
170− printf("\nmain " SOURCE " (%d bytes at %p)\n",
171− tf->source->str,tf->lineDefined,size,tf);
172− else
173− {
174− printf("\nfunction " SOURCE " (%d bytes at %p); used at ",
175− tf->source->str,tf->lineDefined,size,tf);
176− if (Main && IsMain(Main))
177− printf("main");
178− else
179− printf("%p",Main);
180− printf("+%d\n",at);
181− }
182−}
183−
184−static void PrintFunction(TProtoFunc* tf, TProtoFunc* Main, int at);
77+#define SS(x) (x==1)?"":"s"
78+#define S(x) x,SS(x)
18579
186−static void PrintFunctions(TProtoFunc* Main)
80+static void PrintHeader(const Proto* tf)
18781 {
188− Byte* code=Main->code;
189− Byte* p=code;
190− int longarg=0;
191− for (;;)
192− {
193− Opcode OP;
194− int n=INFO(Main,p,&OP);
195− int op=OP.class;
196− int i=OP.arg+longarg;
197− longarg=0;
198− if (op==PUSHCONSTANT || op==CLOSURE)
199− {
200− TObject* o=Main->consts+i;
201− if (ttype(o)==LUA_T_PROTO) PrintFunction(tfvalue(o),Main,(int)(p-code));
202− }
203− else if (op==LONGARG) longarg=i<<16;
204− else if (op==ENDCODE) break;
205− p+=n;
206− }
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));
20789 }
20890
209−static void PrintFunction(TProtoFunc* tf, TProtoFunc* Main, int at)
210−{
211− PrintHeader(tf,Main,at);
212− PrintLocals(tf);
213− PrintCode(tf);
214−#ifdef DEBUG
215− PrintConstants(tf);
216−#endif
217− PrintFunctions(tf);
218−}
91+#define PrintFunction luaU_printchunk
21992
220−void luaU_printchunk(TProtoFunc* Main)
93+void PrintFunction(const Proto* tf)
22194 {
222− PrintFunction(Main,0,0);
95+ int i,n=tf->nkproto;
96+ PrintHeader(tf);
97+ PrintCode(tf);
98+ for (i=0; i<n; i++) PrintFunction(tf->kproto[i]);
22399 }
src/luac/print.h+55−0
@@ -0,0 +1,55 @@
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+91−85
@@ -1,68 +1,109 @@
11 /*
2−** $Id: stubs.c,v 1.11 1999/03/11 17:09:10 lhf Exp $
2+** $Id: stubs.c,v 1.20 2000/10/31 16:57:23 lhf Exp $
33 ** avoid runtime modules in luac
44 ** See Copyright Notice in lua.h
55 */
66
7−#ifdef NOSTUBS
8−
9−/* according to gcc, ANSI C forbids an empty source file */
10−void luaU_dummy(void);
11−void luaU_dummy(void){}
12−
13−#else
14−
15−#include <stdarg.h>
167 #include <stdio.h>
178 #include <stdlib.h>
9+
10+#include "ldo.h"
11+#include "llex.h"
1812 #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 " $";
1919
2020 /*
21−* avoid lapi lauxlib lbuiltin ldo lgc ltable ltm lvm
22−* use only lbuffer lfunc llex lmem lobject lparser lstate lstring lzio
21+* avoid lapi ldebug ldo lgc lstate ltm lvm
22+* use only lcode lfunc llex lmem lobject lparser lstring ltable lzio
2323 */
2424
2525 /* simplified from ldo.c */
26−void lua_error(char* s)
27−{
28− if (s) fprintf(stderr,"luac: %s\n",s);
29− exit(1);
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);
3030 }
3131
32−/* copied from lauxlib.c */
33−void luaL_verror (char *fmt, ...)
34−{
35− char buff[500];
36− va_list argp;
37− va_start(argp, fmt);
38− vsprintf(buff, fmt, argp);
39− va_end(argp);
40− lua_error(buff);
32+/* simplified from ldo.c */
33+void luaD_breakrun (lua_State *L, int errcode) {
34+ UNUSED(errcode);
35+ lua_error(L,"memory allocation error");
4136 }
4237
43−/* copied from lauxlib.c */
44−void luaL_filesource (char *out, char *filename, int len) {
45− if (filename == NULL) filename = "(stdin)";
46− sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
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;
4772 }
4873
49−/* avoid runtime modules in lstate.c */
50−
51−#include "lbuiltin.h"
52−#include "ldo.h"
53−#include "lgc.h"
54−#include "ltable.h"
55−#include "ltm.h"
56−
57−void luaB_predefine(void){}
58−void luaC_hashcallIM(Hash *l){}
59−void luaC_strcallIM(TaggedString *l){}
60−void luaD_gcIM(TObject *o){}
61−void luaH_free(Hash *frees){}
62−void luaT_init(void){}
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+}
63104
64105 /*
65−* the code below avoids the lexer and the parser (llex lparser).
106+* the code below avoids the lexer and the parser (llex lparser lcode).
66107 * it is useful if you only want to load binary files.
67108 * this works for interpreters like lua.c too.
68109 */
@@ -72,49 +113,14 @@ void luaT_init(void){} · 3 unmodified lines
72113 #include "llex.h"
73114 #include "lparser.h"
74115
75−void luaX_init(void){}
76−void luaD_init(void){}
77−
78−TProtoFunc* luaY_parser(ZIO *z) {
79− lua_error("parser not loaded");
80− return NULL;
81−}
82−
83−#else
84−
85−/* copied from lauxlib.c */
86−int luaL_findstring (char *name, char *list[]) {
87− int i;
88− for (i=0; list[i]; i++)
89− if (strcmp(list[i], name) == 0)
90− return i;
91− return -1; /* name not found */
92−}
93−
94−/* copied from lauxlib.c */
95−void luaL_chunkid (char *out, char *source, int len) {
96− len -= 13; /* 13 = strlen("string ''...\0") */
97− if (*source == '@')
98− sprintf(out, "file `%.*s'", len, source+1);
99− else if (*source == '(')
100− strcpy(out, "(C code)");
101− else {
102− char *b = strchr(source , '\n'); /* stop string at first new line */
103− int lim = (b && (b-source)<len) ? b-source : len;
104− sprintf(out, "string `%.*s'", lim, source);
105− strcpy(out+lim+(13-5), "...'"); /* 5 = strlen("...'\0") */
106− }
116+void luaX_init(lua_State *L) {
117+ UNUSED(L);
107118 }
108119
109−void luaD_checkstack(int n){}
110−
111−#define STACK_UNIT 128
112−
113−/* copied from ldo.c */
114−void luaD_init (void) {
115− L->stack.stack = luaM_newvector(STACK_UNIT, TObject);
116− L->stack.top = L->stack.stack;
117− L->stack.last = L->stack.stack+(STACK_UNIT-1);
120+Proto *luaY_parser(lua_State *L, ZIO *z) {
121+ UNUSED(z);
122+ lua_error(L,"parser not loaded");
123+ return NULL;
118124 }
119125
120126 #endif
src/luac/test.c+0−253
@@ -1,253 +0,0 @@
1−/*
2−** $Id: test.c,v 1.10 1999/07/02 19:34:26 lhf Exp $
3−** test integrity
4−** See Copyright Notice in lua.h
5−*/
6−
7−#include <stdio.h>
8−#include <stdlib.h>
9−#include <string.h>
10−#include "luac.h"
11−
12−#define AT "pc=%d"
13−#define ATLOC 0)
14−#define UNSAFE(s) \
15− luaL_verror("unsafe code at " AT IN "\n " s,at,INLOC
16−
17−TObject* luaU_getconstant(TProtoFunc* tf, int i, int at)
18−{
19− if (i>=tf->nconsts) UNSAFE("bad constant #%d (max=%d)"),i,tf->nconsts-1,ATLOC;
20− return tf->consts+i;
21−}
22−
23−static int check(int n, TProtoFunc* tf, int at, int sp, int ss)
24−{
25− if (n==0) return sp;
26− sp+=n;
27− if (sp<00) UNSAFE("stack underflow (sp=%d)"),sp,ATLOC;
28− if (sp>ss) UNSAFE("stack overflow (sp=%d ss=%d)"),sp,ss,ATLOC;
29− return sp;
30−}
31−
32−#define CHECK(before,after) \
33− sp=check(-(before),tf,at,sp,ss), sp=check(after,tf,at,sp,ss)
34−
35−static int jmpok(TProtoFunc* tf, int size, int at, int d)
36−{
37− int to=at+d;
38− if (to<2 || to>=size)
39− UNSAFE("invalid jump to %d (valid range is 2..%d)"),to,size-1,ATLOC;
40− return to;
41−}
42−
43−static void TestStack(TProtoFunc* tf, int size, int* SP, int* JP)
44−{
45− Byte* code=tf->code;
46− Byte* p=code;
47− int longarg=0;
48− int ss=0;
49− int sp=0;
50− for (;;)
51− {
52− Opcode OP;
53− int n=INFO(tf,p,&OP);
54− int op=OP.class;
55− int i=OP.arg+longarg;
56− int at=p-code;
57− longarg=0;
58− switch (op) /* test sanity of operands */
59− {
60− case PUSHCONSTANT:
61− case GETGLOBAL:
62− case GETDOTTED:
63− case PUSHSELF:
64− case SETGLOBAL:
65− case CLOSURE:
66− {
67− TObject* o=luaU_getconstant(tf,i,at);
68− if ((op==CLOSURE && ttype(o)!=LUA_T_PROTO)
69− || (op==GETGLOBAL && ttype(o)!=LUA_T_STRING)
70− || (op==SETGLOBAL && ttype(o)!=LUA_T_STRING))
71− UNSAFE("bad operand to %s"),OP.name,ATLOC;
72− break;
73− }
74− case PUSHLOCAL:
75− if (i>=sp) UNSAFE("bad local #%d (max=%d)"),i,sp-1,ATLOC;
76− break;
77− case SETLOCAL:
78− if (i>=(sp-1)) UNSAFE("bad local #%d (max=%d)"),i,sp-2,ATLOC;
79− break;
80− case ONTJMP:
81− case ONFJMP: /* negate to remember ON?JMP */
82− JP[at]=-jmpok(tf,size,at,i+n);
83− break;
84− case JMP: /* remember JMP targets */
85− case IFFJMP:
86− JP[at]= jmpok(tf,size,at,i+n);
87− break;
88− case IFTUPJMP:
89− case IFFUPJMP:
90− JP[at]= jmpok(tf,size,at,-i+n);
91− break;
92− }
93−
94− SP[at]=sp; /* remember depth before instruction */
95−
96− switch (op)
97− {
98− case STACK: ss=i; break;
99− case ARGS: CHECK(0,i); break;
100− case VARARGS: break;
101− case ENDCODE: return;
102− case RETCODE: CHECK(i,0); sp=i; break;
103− case CALL: CHECK(OP.arg2+1,i); break;
104− case TAILCALL: CHECK(OP.arg2,0); sp=i; break;
105− case PUSHNIL: CHECK(0,i+1); break;
106− case POP: CHECK(0,-i); break;
107− case PUSHNUMBER:
108− case PUSHNUMBERNEG:
109− case PUSHCONSTANT:
110− case PUSHUPVALUE:
111− case PUSHLOCAL:
112− case GETGLOBAL: CHECK(0,1); break;
113− case GETTABLE: CHECK(2,1); break;
114− case GETDOTTED: CHECK(1,1); break;
115− case PUSHSELF: CHECK(1,2); break;
116− case CREATEARRAY: CHECK(0,1); break;
117− case SETLOCAL: CHECK(1,0); break;
118− case SETGLOBAL: CHECK(1,0); break;
119− case SETTABLEPOP: CHECK(3,0); break;
120− case SETTABLE: CHECK(i+3,i+2); break;
121− case SETLIST: CHECK(OP.arg2+1,1); break;
122− case SETMAP: CHECK(2*(i+1)+1,1); break;
123− case NEQOP:
124− case EQOP:
125− case LTOP:
126− case LEOP:
127− case GTOP:
128− case GEOP:
129− case ADDOP:
130− case SUBOP:
131− case MULTOP:
132− case DIVOP:
133− case POWOP:
134− case CONCOP: CHECK(2,1); break;
135− case MINUSOP:
136− case NOTOP: CHECK(1,1); break;
137− case ONTJMP:
138− case ONFJMP:
139− case IFFJMP:
140− case IFTUPJMP:
141− case IFFUPJMP: CHECK(1,0); break;
142− case JMP: break;
143− case CLOSURE: CHECK(OP.arg2,1); break;
144− case SETLINE: break;
145− case LONGARG:
146− longarg=i<<16;
147− if (longarg<0) UNSAFE("longarg overflow"),ATLOC;
148− break;
149− case CHECKSTACK: break;
150− default: /* cannot happen */
151− UNSAFE("cannot test opcode %d [%s]"),OP.op,OP.name,ATLOC;
152− break;
153− }
154− p+=n;
155− }
156−}
157−
158−static void TestJumps(TProtoFunc* tf, int size, int* SP, int* JP)
159−{
160− int i;
161− for (i=0; i<size; i++)
162− {
163− int to=JP[i];
164− if (to!=0)
165− {
166− int at=i; /* for ATLOC */
167− int a,b,j;
168− int on=(to<0); /* ON?JMP */
169− if (on) to=-to;
170− a=SP[to];
171− if (a<0)
172− UNSAFE("invalid jump to %d (not an instruction)"),to,ATLOC;
173− for (j=i; SP[++j]<0; ) /* find next instruction */
174− ;
175− b=SP[j]+on;
176− if (a!=b)
177− UNSAFE("stack inconsistency in jump to %d (expected %d, found %d)"),
178− to,a,b,ATLOC;
179− }
180− }
181−}
182−
183−static void TestCode(TProtoFunc* tf)
184−{
185− static int* SP=NULL;
186− static int* JP=NULL;
187− int size=luaU_codesize(tf);
188− luaM_reallocvector(SP,size,int); memset(SP,-1,size*sizeof(int));
189− luaM_reallocvector(JP,size,int); memset(JP, 0,size*sizeof(int));
190− TestStack(tf,size,SP,JP);
191− TestJumps(tf,size,SP,JP);
192−}
193−
194−#undef AT
195−#define AT "locvars[%d]"
196−static void TestLocals(TProtoFunc* tf)
197−{
198− LocVar* v;
199− int l=1;
200− int d=0;
201− if (tf->locvars==NULL) return;
202− for (v=tf->locvars; v->line>=0; v++)
203− {
204− int at=v-tf->locvars; /* for ATLOC */
205− if (l>v->line)
206− UNSAFE("bad line number %d; expected at least %d"),v->line,l,ATLOC;
207− l=v->line;
208− if (v->varname==NULL)
209− {
210− if (--d<0) UNSAFE("no scope to close"),ATLOC;
211− }
212− else
213− ++d;
214− }
215−}
216−
217−static void TestFunction(TProtoFunc* tf);
218−
219−static void TestConstants(TProtoFunc* tf)
220−{
221− int i,n=tf->nconsts;
222− for (i=0; i<n; i++)
223− {
224− TObject* o=tf->consts+i;
225− switch (ttype(o))
226− {
227− case LUA_T_NUMBER:
228− break;
229− case LUA_T_STRING:
230− break;
231− case LUA_T_PROTO:
232− TestFunction(tfvalue(o));
233− break;
234− case LUA_T_NIL:
235− break;
236− default: /* cannot happen */
237− luaU_badconstant("print",i,o,tf);
238− break;
239− }
240− }
241−}
242−
243−static void TestFunction(TProtoFunc* tf)
244−{
245− TestCode(tf);
246− TestLocals(tf);
247− TestConstants(tf);
248−}
249−
250−void luaU_testchunk(TProtoFunc* Main)
251−{
252− TestFunction(Main);
253−}
src/lundump.c+154−149
@@ -1,239 +1,244 @@
11 /*
2−** $Id: lundump.c,v 1.21 1999/07/02 19:34:26 lhf Exp $
2+** $Id: lundump.c,v 1.33 2000/10/31 16:57:23 lhf Exp $
33 ** load bytecodes from files
44 ** See Copyright Notice in lua.h
55 */
66
77 #include <stdio.h>
88 #include <string.h>
9−#include "lauxlib.h"
9+
1010 #include "lfunc.h"
1111 #include "lmem.h"
1212 #include "lopcodes.h"
1313 #include "lstring.h"
1414 #include "lundump.h"
1515
16−#define LoadBlock(b,size,Z) ezread(Z,b,size)
16+#define LoadByte ezgetc
1717
18−static void unexpectedEOZ (ZIO* Z)
18+static const char* ZNAME (ZIO* Z)
1919 {
20− luaL_verror("unexpected end of file in %s",zname(Z));
20+ const char* s=zname(Z);
21+ return (*s=='@') ? s+1 : s;
2122 }
2223
23−static int ezgetc (ZIO* Z)
24+static void unexpectedEOZ (lua_State* L, ZIO* Z)
2425 {
25− int c=zgetc(Z);
26− if (c==EOZ) unexpectedEOZ(Z);
27− return c;
26+ luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z));
2827 }
2928
30−static void ezread (ZIO* Z, void* b, int n)
29+static int ezgetc (lua_State* L, ZIO* Z)
3130 {
32− int r=zread(Z,b,n);
33− if (r!=0) unexpectedEOZ(Z);
31+ int c=zgetc(Z);
32+ if (c==EOZ) unexpectedEOZ(L,Z);
33+ return c;
3434 }
3535
36−static unsigned int LoadWord (ZIO* Z)
36+static void ezread (lua_State* L, ZIO* Z, void* b, int n)
3737 {
38− unsigned int hi=ezgetc(Z);
39− unsigned int lo=ezgetc(Z);
40− return (hi<<8)|lo;
38+ int r=zread(Z,b,n);
39+ if (r!=0) unexpectedEOZ(L,Z);
4140 }
4241
43−static unsigned long LoadLong (ZIO* Z)
42+static void LoadBlock (lua_State* L, void* b, size_t size, ZIO* Z, int swap)
4443 {
45− unsigned long hi=LoadWord(Z);
46− unsigned long lo=LoadWord(Z);
47− return (hi<<16)|lo;
48−}
49−
50−/*
51−* convert number from text
52−*/
53−double luaU_str2d (char* b, char* where)
54−{
55− int negative=(b[0]=='-');
56− double x=luaO_str2d(b+negative);
57− if (x<0) luaL_verror("cannot convert number '%s' in %s",b,where);
58− return negative ? -x : x;
44+ if (swap)
45+ {
46+ char *p=(char *) b+size-1;
47+ int n=size;
48+ while (n--) *p--=(char)ezgetc(L,Z);
49+ }
50+ else
51+ ezread(L,Z,b,size);
5952 }
6053
61−static real LoadNumber (ZIO* Z, int native)
54+static void LoadVector (lua_State* L, void* b, int m, size_t size, ZIO* Z, int swap)
6255 {
63− real x;
64− if (native)
56+ if (swap)
6557 {
66− LoadBlock(&x,sizeof(x),Z);
67− return x;
58+ char *q=(char *) b;
59+ while (m--)
60+ {
61+ char *p=q+size-1;
62+ int n=size;
63+ while (n--) *p--=(char)ezgetc(L,Z);
64+ q+=size;
65+ }
6866 }
6967 else
70− {
71− char b[256];
72− int size=ezgetc(Z);
73− LoadBlock(b,size,Z);
74− b[size]=0;
75− return luaU_str2d(b,zname(Z));
76− }
68+ ezread(L,Z,b,m*size);
7769 }
7870
79−static int LoadInt (ZIO* Z, char* message)
71+static int LoadInt (lua_State* L, ZIO* Z, int swap)
8072 {
81− unsigned long l=LoadLong(Z);
82− unsigned int i=l;
83− if (i!=l) luaL_verror(message,l,zname(Z));
84− return i;
73+ int x;
74+ LoadBlock(L,&x,sizeof(x),Z,swap);
75+ return x;
8576 }
8677
87−#define PAD 5 /* two word operands plus opcode */
78+static size_t LoadSize (lua_State* L, ZIO* Z, int swap)
79+{
80+ size_t x;
81+ LoadBlock(L,&x,sizeof(x),Z,swap);
82+ return x;
83+}
8884
89−static Byte* LoadCode (ZIO* Z)
85+static Number LoadNumber (lua_State* L, ZIO* Z, int swap)
9086 {
91− int size=LoadInt(Z,"code too long (%ld bytes) in %s");
92− Byte* b=luaM_malloc(size+PAD);
93− LoadBlock(b,size,Z);
94− if (b[size-1]!=ENDCODE) luaL_verror("bad code in %s",zname(Z));
95− memset(b+size,ENDCODE,PAD); /* pad code for safety */
96− return b;
87+ Number x;
88+ LoadBlock(L,&x,sizeof(x),Z,swap);
89+ return x;
9790 }
9891
99−static TaggedString* LoadTString (ZIO* Z)
92+static TString* LoadString (lua_State* L, ZIO* Z, int swap)
10093 {
101− long size=LoadLong(Z);
94+ size_t size=LoadSize(L,Z,swap);
10295 if (size==0)
10396 return NULL;
10497 else
10598 {
106− char* s=luaL_openspace(size);
107− LoadBlock(s,size,Z);
108− return luaS_newlstr(s,size-1);
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' */
109102 }
110103 }
111104
112−static void LoadLocals (TProtoFunc* tf, ZIO* Z)
105+static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
113106 {
114− int i,n=LoadInt(Z,"too many locals (%ld) in %s");
115− if (n==0) return;
116− tf->locvars=luaM_newvector(n+1,LocVar);
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);
112+}
113+
114+static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
115+{
116+ int i,n;
117+ tf->nlocvars=n=LoadInt(L,Z,swap);
118+ tf->locvars=luaM_newvector(L,n,LocVar);
117119 for (i=0; i<n; i++)
118120 {
119− tf->locvars[i].line=LoadInt(Z,"too many lines (%ld) in %s");
120− tf->locvars[i].varname=LoadTString(Z);
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);
121124 }
122− tf->locvars[i].line=-1; /* flag end of vector */
123− tf->locvars[i].varname=NULL;
124125 }
125126
126−static TProtoFunc* LoadFunction (ZIO* Z, int native);
127+static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
128+{
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);
133+}
134+
135+static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);
127136
128−static void LoadConstants (TProtoFunc* tf, ZIO* Z, int native)
137+static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
129138 {
130− int i,n=LoadInt(Z,"too many constants (%ld) in %s");
131− tf->nconsts=n;
132− if (n==0) return;
133− tf->consts=luaM_newvector(n,TObject);
139+ int i,n;
140+ tf->nkstr=n=LoadInt(L,Z,swap);
141+ tf->kstr=luaM_newvector(L,n,TString*);
134142 for (i=0; i<n; i++)
135− {
136− TObject* o=tf->consts+i;
137− ttype(o)=-ezgetc(Z); /* ttype(o) is negative - ORDER LUA_T */
138− switch (ttype(o))
139− {
140− case LUA_T_NUMBER:
141− nvalue(o)=LoadNumber(Z,native);
142− break;
143− case LUA_T_STRING:
144− tsvalue(o)=LoadTString(Z);
145− break;
146− case LUA_T_PROTO:
147− tfvalue(o)=LoadFunction(Z,native);
148− break;
149− case LUA_T_NIL:
150− break;
151− default: /* cannot happen */
152− luaU_badconstant("load",i,o,tf);
153− break;
154− }
155− }
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*);
149+ for (i=0; i<n; i++)
150+ tf->kproto[i]=LoadFunction(L,Z,swap);
156151 }
157152
158−static TProtoFunc* LoadFunction (ZIO* Z, int native)
153+static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap)
159154 {
160− TProtoFunc* tf=luaF_newproto();
161− tf->lineDefined=LoadInt(Z,"lineDefined too large (%ld) in %s");
162− tf->source=LoadTString(Z);
163− if (tf->source==NULL) tf->source=luaS_new(zname(Z));
164− tf->code=LoadCode(Z);
165− LoadLocals(tf,Z);
166− LoadConstants(tf,Z,native);
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);
167165 return tf;
168166 }
169167
170−static void LoadSignature (ZIO* Z)
168+static void LoadSignature (lua_State* L, ZIO* Z)
171169 {
172− char* s=SIGNATURE;
173− while (*s!=0 && ezgetc(Z)==*s)
170+ const char* s=SIGNATURE;
171+ while (*s!=0 && ezgetc(L,Z)==*s)
174172 ++s;
175− if (*s!=0) luaL_verror("bad signature in %s",zname(Z));
173+ if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z));
176174 }
177175
178−static int LoadHeader (ZIO* Z)
176+static void TestSize (lua_State* L, int s, const char* what, ZIO* Z)
177+{
178+ int r=ezgetc(L,Z);
179+ 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);
182+}
183+
184+#define TESTSIZE(s) TestSize(L,s,#s,Z)
185+#define V(v) v/16,v%16
186+
187+static int LoadHeader (lua_State* L, ZIO* Z)
179188 {
180− int version,sizeofR;
181− int native;
182− LoadSignature(Z);
183− version=ezgetc(Z);
189+ int version,swap;
190+ Number f=0,tf=TEST_NUMBER;
191+ LoadSignature(L,Z);
192+ version=ezgetc(L,Z);
184193 if (version>VERSION)
185− luaL_verror(
186− "%s too new: version=0x%02x; expected at most 0x%02x",
187− zname(Z),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));
188197 if (version<VERSION0) /* check last major change */
189− luaL_verror(
190− "%s too old: version=0x%02x; expected at least 0x%02x",
191− zname(Z),version,VERSION0);
192− sizeofR=ezgetc(Z);
193− native=(sizeofR!=0);
194− if (native) /* test number representation */
195− {
196− if (sizeofR!=sizeof(real))
197− luaL_verror("unknown number size in %s: read %d; expected %d",
198− zname(Z),sizeofR,sizeof(real));
199− else
200− {
201− real tf=TEST_NUMBER;
202− real f=LoadNumber(Z,native);
203− if ((long)f!=(long)tf)
204− luaL_verror("unknown number format in %s: "
205− "read " NUMBER_FMT "; expected " NUMBER_FMT,
206− zname(Z),f,tf);
207− }
208− }
209− return native;
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;
210214 }
211215
212−static TProtoFunc* LoadChunk (ZIO* Z)
216+static Proto* LoadChunk (lua_State* L, ZIO* Z)
213217 {
214− return LoadFunction(Z,LoadHeader(Z));
218+ return LoadFunction(L,Z,LoadHeader(L,Z));
215219 }
216220
217221 /*
218222 ** load one chunk from a file or buffer
219223 ** return main if ok and NULL at EOF
220224 */
221−TProtoFunc* luaU_undump1 (ZIO* Z)
225+Proto* luaU_undump (lua_State* L, ZIO* Z)
222226 {
227+ Proto* tf=NULL;
223228 int c=zgetc(Z);
224229 if (c==ID_CHUNK)
225− return LoadChunk(Z);
226− else if (c!=EOZ)
227− luaL_verror("%s is not a Lua binary file",zname(Z));
228− return NULL;
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;
229235 }
230236
231237 /*
232−* handle constants that cannot happen
238+** find byte order
233239 */
234−void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf)
240+int luaU_endianess (void)
235241 {
236− int t=ttype(o);
237− char* name= (t>0 || t<LUA_T_LINE) ? "?" : luaO_typenames[-t];
238− luaL_verror("cannot %s constant #%d: type=%d [%s]" IN,s,i,t,name,INLOC);
242+ int x=1;
243+ return *(char*)&x;
239244 }
src/lundump.h+12−16
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lundump.h,v 1.15 1999/07/02 19:34:26 lhf Exp $
2+** $Id: lundump.h,v 1.21 2000/10/31 16:57:23 lhf Exp $
33 ** load pre-compiled Lua chunks
44 ** See Copyright Notice in lua.h
55 */
@@ -10,27 +10,23 @@ · 4 unmodified lines
1010 #include "lobject.h"
1111 #include "lzio.h"
1212
13−TProtoFunc* luaU_undump1 (ZIO* Z); /* load one chunk */
14−void luaU_badconstant (char* s, int i, TObject* o, TProtoFunc* tf);
15− /* handle cases that cannot happen */
16−double luaU_str2d (char* b, char* where);
17− /* convert number from text */
13+/* load one chunk */
14+Proto* luaU_undump (lua_State* L, ZIO* Z);
15+
16+/* find byte order */
17+int luaU_endianess (void);
1818
1919 /* definitions for headers of binary files */
20−#define VERSION 0x32 /* last format change was in 3.2 */
21−#define VERSION0 0x32 /* last major change was in 3.2 */
20+#define VERSION 0x40 /* last format change was in 4.0 */
21+#define VERSION0 0x40 /* last major change was in 4.0 */
2222 #define ID_CHUNK 27 /* binary files start with ESC... */
2323 #define SIGNATURE "Lua" /* ...followed by this signature */
2424
2525 /* formats for error messages */
26−#define SOURCE "<%s:%d>"
27−#define IN " in %p " SOURCE
28−#define INLOC tf,tf->source->str,tf->lineDefined
29−
30−/* format for numbers in listings and error messages */
31−#ifndef NUMBER_FMT
32−#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
33−#endif
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
3430
3531 /* a multiple of PI for testing native format */
3632 /* multiplying by 1E8 gives non-trivial integer values */
src/lvm.c+549−474
@@ -1,28 +1,27 @@
11 /*
2−** $Id: lvm.c,v 1.58 1999/06/22 20:37:23 roberto Exp $
2+** $Id: lvm.c,v 1.146 2000/10/26 12:47:05 roberto Exp $
33 ** Lua virtual machine
44 ** See Copyright Notice in lua.h
55 */
66
77
8−#include <ctype.h>
9−#include <limits.h>
108 #include <stdio.h>
119 #include <stdlib.h>
1210 #include <string.h>
1311
14−#include "lauxlib.h"
12+#include "lua.h"
13+
14+#include "lapi.h"
15+#include "ldebug.h"
1516 #include "ldo.h"
1617 #include "lfunc.h"
1718 #include "lgc.h"
18−#include "lmem.h"
1919 #include "lobject.h"
2020 #include "lopcodes.h"
2121 #include "lstate.h"
2222 #include "lstring.h"
2323 #include "ltable.h"
2424 #include "ltm.h"
25−#include "luadebug.h"
2625 #include "lvm.h"
2726
2827
@@ -31,605 +30,681 @@ · 2 unmodified lines
3130 #endif
3231
3332
34−#define highbyte(x) ((x)<<8)
35−
36−
37−/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
38−#define EXTRA_STACK 5
39−
4033
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
4139
42−static TaggedString *strconc (TaggedString *l, TaggedString *r) {
43− long nl = l->u.s.len;
44− long nr = r->u.s.len;
45− char *buffer = luaL_openspace(nl+nr);
46− memcpy(buffer, l->str, nl);
47− memcpy(buffer+nl, r->str, nr);
48− return luaS_newlstr(buffer, nl+nr);
49−}
5040
5141
52−int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
53− if (ttype(obj) != LUA_T_STRING)
42+int luaV_tonumber (TObject *obj) {
43+ if (ttype(obj) != LUA_TSTRING)
5444 return 1;
5545 else {
56− double t;
57− char *e = svalue(obj);
58− int sig = 1;
59− while (isspace((unsigned char)*e)) e++;
60− if (*e == '-') {
61− e++;
62− sig = -1;
63− }
64− else if (*e == '+') e++;
65− /* no digit before or after decimal point? */
66− if (!isdigit((unsigned char)*e) && !isdigit((unsigned char)*(e+1)))
46+ if (!luaO_str2d(svalue(obj), &nvalue(obj)))
6747 return 2;
68− t = luaO_str2d(e);
69− if (t<0) return 2;
70− nvalue(obj) = (real)t*sig;
71− ttype(obj) = LUA_T_NUMBER;
48+ ttype(obj) = LUA_TNUMBER;
7249 return 0;
7350 }
7451 }
7552
7653
77−int luaV_tostring (TObject *obj) { /* LUA_NUMBER */
78− if (ttype(obj) != LUA_T_NUMBER)
54+int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
55+ if (ttype(obj) != LUA_TNUMBER)
7956 return 1;
8057 else {
81− char s[32]; /* 16 digits, signal, point and \0 (+ some extra...) */
82− sprintf(s, "%.16g", (double)nvalue(obj));
83− tsvalue(obj) = luaS_new(s);
84− ttype(obj) = LUA_T_STRING;
58+ 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;
8562 return 0;
8663 }
8764 }
8865
8966
90−void luaV_setn (Hash *t, int val) {
91− TObject index, value;
92− ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new("n");
93− ttype(&value) = LUA_T_NUMBER; nvalue(&value) = val;
94− luaH_set(t, &index, &value);
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 */
76+ }
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-2, newline, linehook);
83+ }
84+ ci->lastpc = pc;
85+}
86+
87+
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;
9597 }
9698
9799
98−void luaV_closure (int nelems) {
99− if (nelems > 0) {
100− struct Stack *S = &L->stack;
101− Closure *c = luaF_newclosure(nelems);
102− c->consts[0] = *(S->top-1);
103− memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
104− S->top -= nelems;
105− ttype(S->top-1) = LUA_T_CLOSURE;
106− (S->top-1)->value.cl = c;
107− }
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;
104+}
105+
106+
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;
108111 }
109112
110113
111114 /*
112115 ** Function to index a table.
113−** Receives the table at top-2 and the index at top-1.
116+** Receives the table at `t' and the key at top.
114117 */
115−void luaV_gettable (void) {
116− TObject *table = L->stack.top-2;
117− TObject *im;
118− if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
119− im = luaT_getimbyObj(table, IM_GETTABLE);
120− if (ttype(im) == LUA_T_NIL)
121− lua_error("indexed expression not a table");
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 */
122130 }
123− else { /* object is a table... */
124− int tg = table->value.a->htag;
125− im = luaT_getim(tg, IM_GETTABLE);
126− if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
127− TObject *h = luaH_get(avalue(table), table+1);
128− if (ttype(h) == LUA_T_NIL &&
129− (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
130− /* result is nil and there is an "index" tag method */
131− luaD_callTM(im, 2, 1); /* calls it */
132− }
133− else {
134− L->stack.top--;
135− *table = *h; /* "push" result into table position */
136− }
137− return;
138− }
139− /* else it has a "gettable" method, go through to next command */
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 */
140147 }
141− /* object is not a table, or it has a "gettable" method */
142− luaD_callTM(im, 2, 1);
143148 }
144149
145150
146151 /*
147−** Receives table at *t, index at *(t+1) and value at top.
152+** Receives table at `t', key at `key' and value at top.
148153 */
149−void luaV_settable (TObject *t) {
150− struct Stack *S = &L->stack;
151− TObject *im;
152− if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
153− im = luaT_getimbyObj(t, IM_SETTABLE);
154− if (ttype(im) == LUA_T_NIL)
155− lua_error("indexed expression not a table");
156− }
157− else { /* object is a table... */
158− im = luaT_getim(avalue(t)->htag, IM_SETTABLE);
159− if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
160− luaH_set(avalue(t), t+1, S->top-1);
161− S->top--; /* pop value */
162− return;
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 */
163171 }
164− /* else it has a "settable" method, go through to next command */
172+ else /* no tag method... */
173+ luaG_typeerror(L, t, "index");
165174 }
166− /* object is not a table, or it has a "settable" method */
167− /* prepare arguments and call the tag method */
168− *(S->top+1) = *(L->stack.top-1);
169− *(S->top) = *(t+1);
170− *(S->top-1) = *t;
171− S->top += 2; /* WARNING: caller must assure stack space */
172− luaD_callTM(im, 3, 0);
173175 }
174176
175177
176−void luaV_rawsettable (TObject *t) {
177− if (ttype(t) != LUA_T_ARRAY)
178− lua_error("indexed expression not a table");
179− else {
180− struct Stack *S = &L->stack;
181− luaH_set(avalue(t), t+1, S->top-1);
182− S->top -= 3;
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;
183193 }
184194 }
185195
186196
187−void luaV_getglobal (TaggedString *ts) {
188− /* WARNING: caller must assure stack space */
189− /* only userdata, tables and nil can have getglobal tag methods */
190− static char valid_getglobals[] = {1, 0, 0, 1, 0, 0, 1, 0}; /* ORDER LUA_T */
191− TObject *value = &ts->u.s.globalval;
192− if (valid_getglobals[-ttype(value)]) {
193− TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
194− if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
195− struct Stack *S = &L->stack;
196− ttype(S->top) = LUA_T_STRING;
197− tsvalue(S->top) = ts;
198− S->top++;
199− *S->top++ = *value;
200− luaD_callTM(im, 2, 1);
201− return;
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);
202210 }
203− /* else no tag method: go through to default behavior */
204211 }
205− *L->stack.top++ = *value; /* default behavior */
206−}
207−
208−
209−void luaV_setglobal (TaggedString *ts) {
210− TObject *oldvalue = &ts->u.s.globalval;
211− TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
212− if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
213− luaS_rawsetglobal(ts, --L->stack.top);
214212 else {
215− /* WARNING: caller must assure stack space */
216− struct Stack *S = &L->stack;
217− TObject newvalue;
218− newvalue = *(S->top-1);
219− ttype(S->top-1) = LUA_T_STRING;
220− tsvalue(S->top-1) = ts;
221− *S->top++ = *oldvalue;
222− *S->top++ = newvalue;
223− luaD_callTM(im, 3, 0);
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);
224222 }
225223 }
226224
227225
228−static void call_binTM (IMS event, char *msg)
229−{
230− TObject *im = luaT_getimbyObj(L->stack.top-2, event);/* try first operand */
231− if (ttype(im) == LUA_T_NIL) {
232− im = luaT_getimbyObj(L->stack.top-1, event); /* try second operand */
233− if (ttype(im) == LUA_T_NIL) {
234− im = luaT_getim(0, event); /* try a 'global' i.m. */
235− if (ttype(im) == LUA_T_NIL)
236− lua_error(msg);
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) {
233+ tm = luaT_gettm(L, 0, event); /* try a `global' method */
234+ if (tm == NULL)
235+ return 0; /* error */
237236 }
238237 }
239− lua_pushstring(luaT_eventname[event]);
240− luaD_callTM(im, 3, 1);
238+ lua_pushstring(L, luaT_eventname[event]);
239+ luaD_callTM(L, tm, 3, 1);
240+ return 1;
241241 }
242242
243243
244−static void call_arith (IMS event)
245−{
246− call_binTM(event, "unexpected type in arithmetic operation");
244+static void call_arith (lua_State *L, StkId top, TMS event) {
245+ if (!call_binTM(L, top, event))
246+ luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on");
247247 }
248248
249249
250−static int luaV_strcomp (char *l, long ll, char *r, long lr)
251−{
250+static int luaV_strcomp (const TString *ls, const TString *rs) {
251+ const char *l = ls->str;
252+ size_t ll = ls->len;
253+ const char *r = rs->str;
254+ size_t lr = rs->len;
252255 for (;;) {
253− long temp = strcoll(l, r);
256+ int temp = strcoll(l, r);
254257 if (temp != 0) return temp;
255− /* strings are equal up to a '\0' */
256− temp = strlen(l); /* index of first '\0' in both strings */
257− if (temp == ll) /* l is finished? */
258− return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */
259− else if (temp == lr) /* r is finished? */
260− return 1; /* l is greater than r (because l is not finished) */
261− /* both strings longer than temp; go on comparing (after the '\0') */
262− temp++;
263− l += temp; ll -= temp; r += temp; lr -= temp;
258+ else { /* strings are equal up to a '\0' */
259+ size_t len = strlen(l); /* index of first '\0' in both strings */
260+ if (len == ll) /* l is finished? */
261+ return (len == lr) ? 0 : -1; /* l is equal or smaller than r */
262+ else if (len == lr) /* r is finished? */
263+ return 1; /* l is greater than r (because l is not finished) */
264+ /* both strings longer than `len'; go on comparing (after the '\0') */
265+ len++;
266+ l += len; ll -= len; r += len; lr -= len;
267+ }
264268 }
265269 }
266270
267−void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
268− lua_Type ttype_great, IMS op) {
269− struct Stack *S = &L->stack;
270− TObject *l = S->top-2;
271− TObject *r = S->top-1;
272− real result;
273− if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
274− result = nvalue(l)-nvalue(r);
275− else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
276− result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
277− svalue(r), tsvalue(r)->u.s.len);
278− else {
279− call_binTM(op, "unexpected type in comparison");
280− return;
271+
272+int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
273+ if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER)
274+ return (nvalue(l) < nvalue(r));
275+ else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING)
276+ return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
277+ else { /* call TM */
278+ luaD_checkstack(L, 2);
279+ *top++ = *l;
280+ *top++ = *r;
281+ if (!call_binTM(L, top, TM_LT))
282+ luaG_ordererror(L, top-2);
283+ L->top--;
284+ return (ttype(L->top) != LUA_TNIL);
281285 }
282− S->top--;
283− nvalue(S->top-1) = 1;
284− ttype(S->top-1) = (result < 0) ? ttype_less :
285− (result == 0) ? ttype_equal : ttype_great;
286286 }
287287
288288
289−void luaV_pack (StkId firstel, int nvararg, TObject *tab) {
290− TObject *firstelem = L->stack.stack+firstel;
289+void luaV_strconc (lua_State *L, int total, StkId top) {
290+ do {
291+ int n = 2; /* number of elements handled in this pass (at least 2) */
292+ if (tostring(L, top-2) || tostring(L, top-1)) {
293+ if (!call_binTM(L, top, TM_CONCAT))
294+ luaG_binerror(L, top-2, LUA_TSTRING, "concat");
295+ }
296+ else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
297+ /* at least two string values; get as many as possible */
298+ lint32 tl = (lint32)tsvalue(top-1)->len +
299+ (lint32)tsvalue(top-2)->len;
300+ char *buffer;
301+ int i;
302+ while (n < total && !tostring(L, top-n-1)) { /* collect total length */
303+ tl += tsvalue(top-n-1)->len;
304+ n++;
305+ }
306+ if (tl > MAX_SIZET) lua_error(L, "string size overflow");
307+ buffer = luaO_openspace(L, tl);
308+ tl = 0;
309+ for (i=n; i>0; i--) { /* concat all strings */
310+ size_t l = tsvalue(top-i)->len;
311+ memcpy(buffer+tl, tsvalue(top-i)->str, l);
312+ tl += l;
313+ }
314+ tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
315+ }
316+ total -= n-1; /* got `n' strings to create 1 new */
317+ top -= n-1;
318+ } while (total > 1); /* repeat until only 1 result left */
319+}
320+
321+
322+static void luaV_pack (lua_State *L, StkId firstelem) {
291323 int i;
292− Hash *htab;
293− if (nvararg < 0) nvararg = 0;
294− htab = avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
295− ttype(tab) = LUA_T_ARRAY;
296− for (i=0; i<nvararg; i++)
297− luaH_setint(htab, i+1, firstelem+i);
298− luaV_setn(htab, nvararg); /* store counter in field "n" */
324+ Hash *htab = luaH_new(L, 0);
325+ for (i=0; firstelem+i<L->top; i++)
326+ *luaH_setint(L, htab, i+1) = *(firstelem+i);
327+ /* store counter in field `n' */
328+ luaH_setstrnum(L, htab, luaS_new(L, "n"), i);
329+ L->top = firstelem; /* remove elements from the stack */
330+ ttype(L->top) = LUA_TTABLE;
331+ hvalue(L->top) = htab;
332+ incr_top;
299333 }
300334
301335
302−static void adjust_varargs (StkId first_extra_arg)
303−{
304− TObject arg;
305− luaV_pack(first_extra_arg,
306− (L->stack.top-L->stack.stack)-first_extra_arg, &arg);
307− luaD_adjusttop(first_extra_arg);
308− *L->stack.top++ = arg;
336+static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
337+ int nvararg = (L->top-base) - nfixargs;
338+ if (nvararg < 0)
339+ luaD_adjusttop(L, base, nfixargs);
340+ luaV_pack(L, base+nfixargs);
309341 }
310342
311343
312344
345+#define dojump(pc, i) { int d = GETARG_S(i); pc += d; }
346+
313347 /*
314−** Execute the given opcode, until a RET. Parameters are between
315−** [stack+base,top). Returns n such that the the results are between
316−** [stack+n,top).
348+** Executes the given Lua function. Parameters are between [base,top).
349+** Returns n such that the the results are between [n,top).
317350 */
318−StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
319− struct Stack *S = &L->stack; /* to optimize */
320− register Byte *pc = tf->code;
321− TObject *consts = tf->consts;
322− if (L->callhook)
323− luaD_callHook(base, tf, 0);
324− luaD_checkstack((*pc++)+EXTRA_STACK);
325− if (*pc < ZEROVARARG)
326− luaD_adjusttop(base+*(pc++));
327− else { /* varargs */
328− luaC_checkGC();
329− adjust_varargs(base+(*pc++)-ZEROVARARG);
330− }
351+StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
352+ const Proto *const tf = cl->f.l;
353+ StkId top; /* keep top local, for performance */
354+ const Instruction *pc = tf->code;
355+ TString **const kstr = tf->kstr;
356+ const lua_Hook linehook = L->linehook;
357+ infovalue(base-1)->pc = &pc;
358+ luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
359+ if (tf->is_vararg) /* varargs? */
360+ adjust_varargs(L, base, tf->numparams);
361+ else
362+ luaD_adjusttop(L, base, tf->numparams);
363+ top = L->top;
364+ /* main loop of interpreter */
331365 for (;;) {
332− register int aux = 0;
333− switchentry:
334− switch ((OpCode)*pc++) {
335−
336− case ENDCODE:
337− S->top = S->stack + base;
338− goto ret;
339−
340− case RETCODE:
341− base += *pc++;
342− goto ret;
343−
344− case CALL: aux = *pc++;
345− luaD_calln(*pc++, aux);
366+ const Instruction i = *pc++;
367+ if (linehook)
368+ traceexec(L, base, top, linehook);
369+ switch (GET_OPCODE(i)) {
370+ case OP_END: {
371+ L->top = top;
372+ return top;
373+ }
374+ case OP_RETURN: {
375+ L->top = top;
376+ return base+GETARG_U(i);
377+ }
378+ case OP_CALL: {
379+ int nres = GETARG_B(i);
380+ if (nres == MULT_RET) nres = LUA_MULTRET;
381+ L->top = top;
382+ luaD_call(L, base+GETARG_A(i), nres);
383+ top = L->top;
346384 break;
347−
348− case TAILCALL: aux = *pc++;
349− luaD_calln(*pc++, MULT_RET);
350− base += aux;
351− goto ret;
352−
353− case PUSHNIL: aux = *pc++;
385+ }
386+ case OP_TAILCALL: {
387+ L->top = top;
388+ luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
389+ return base+GETARG_B(i);
390+ }
391+ case OP_PUSHNIL: {
392+ int n = GETARG_U(i);
393+ LUA_ASSERT(n>0, "invalid argument");
354394 do {
355− ttype(S->top++) = LUA_T_NIL;
356− } while (aux--);
395+ ttype(top++) = LUA_TNIL;
396+ } while (--n > 0);
357397 break;
358−
359− case POP: aux = *pc++;
360− S->top -= aux;
398+ }
399+ case OP_POP: {
400+ top -= GETARG_U(i);
361401 break;
362−
363− case PUSHNUMBERW: aux += highbyte(*pc++);
364− case PUSHNUMBER: aux += *pc++;
365− ttype(S->top) = LUA_T_NUMBER;
366− nvalue(S->top) = aux;
367− S->top++;
402+ }
403+ case OP_PUSHINT: {
404+ ttype(top) = LUA_TNUMBER;
405+ nvalue(top) = (Number)GETARG_S(i);
406+ top++;
368407 break;
369−
370− case PUSHNUMBERNEGW: aux += highbyte(*pc++);
371− case PUSHNUMBERNEG: aux += *pc++;
372− ttype(S->top) = LUA_T_NUMBER;
373− nvalue(S->top) = -aux;
374− S->top++;
408+ }
409+ case OP_PUSHSTRING: {
410+ ttype(top) = LUA_TSTRING;
411+ tsvalue(top) = kstr[GETARG_U(i)];
412+ top++;
375413 break;
376−
377− case PUSHCONSTANTW: aux += highbyte(*pc++);
378− case PUSHCONSTANT: aux += *pc++;
379− *S->top++ = consts[aux];
414+ }
415+ case OP_PUSHNUM: {
416+ ttype(top) = LUA_TNUMBER;
417+ nvalue(top) = tf->knum[GETARG_U(i)];
418+ top++;
380419 break;
381−
382− case PUSHUPVALUE: aux = *pc++;
383− *S->top++ = cl->consts[aux+1];
420+ }
421+ case OP_PUSHNEGNUM: {
422+ ttype(top) = LUA_TNUMBER;
423+ nvalue(top) = -tf->knum[GETARG_U(i)];
424+ top++;
384425 break;
385−
386− case PUSHLOCAL: aux = *pc++;
387− *S->top++ = *((S->stack+base) + aux);
426+ }
427+ case OP_PUSHUPVALUE: {
428+ *top++ = cl->upvalue[GETARG_U(i)];
388429 break;
389−
390− case GETGLOBALW: aux += highbyte(*pc++);
391− case GETGLOBAL: aux += *pc++;
392− luaV_getglobal(tsvalue(&consts[aux]));
430+ }
431+ case OP_GETLOCAL: {
432+ *top++ = *(base+GETARG_U(i));
393433 break;
394−
395− case GETTABLE:
396− luaV_gettable();
434+ }
435+ case OP_GETGLOBAL: {
436+ L->top = top;
437+ *top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
438+ top++;
397439 break;
398−
399− case GETDOTTEDW: aux += highbyte(*pc++);
400− case GETDOTTED: aux += *pc++;
401− *S->top++ = consts[aux];
402− luaV_gettable();
440+ }
441+ case OP_GETTABLE: {
442+ L->top = top;
443+ top--;
444+ *(top-1) = *luaV_gettable(L, top-1);
403445 break;
404−
405− case PUSHSELFW: aux += highbyte(*pc++);
406− case PUSHSELF: aux += *pc++; {
407− TObject receiver;
408− receiver = *(S->top-1);
409− *S->top++ = consts[aux];
410− luaV_gettable();
411− *S->top++ = receiver;
446+ }
447+ case OP_GETDOTTED: {
448+ ttype(top) = LUA_TSTRING;
449+ tsvalue(top) = kstr[GETARG_U(i)];
450+ L->top = top+1;
451+ *(top-1) = *luaV_gettable(L, top-1);
412452 break;
413453 }
414−
415− case CREATEARRAYW: aux += highbyte(*pc++);
416− case CREATEARRAY: aux += *pc++;
417− luaC_checkGC();
418− avalue(S->top) = luaH_new(aux);
419− ttype(S->top) = LUA_T_ARRAY;
420− S->top++;
454+ case OP_GETINDEXED: {
455+ *top = *(base+GETARG_U(i));
456+ L->top = top+1;
457+ *(top-1) = *luaV_gettable(L, top-1);
421458 break;
422−
423− case SETLOCAL: aux = *pc++;
424− *((S->stack+base) + aux) = *(--S->top);
459+ }
460+ case OP_PUSHSELF: {
461+ TObject receiver;
462+ receiver = *(top-1);
463+ ttype(top) = LUA_TSTRING;
464+ tsvalue(top++) = kstr[GETARG_U(i)];
465+ L->top = top;
466+ *(top-2) = *luaV_gettable(L, top-2);
467+ *(top-1) = receiver;
425468 break;
426−
427− case SETGLOBALW: aux += highbyte(*pc++);
428− case SETGLOBAL: aux += *pc++;
429− luaV_setglobal(tsvalue(&consts[aux]));
469+ }
470+ case OP_CREATETABLE: {
471+ L->top = top;
472+ luaC_checkGC(L);
473+ hvalue(top) = luaH_new(L, GETARG_U(i));
474+ ttype(top) = LUA_TTABLE;
475+ top++;
430476 break;
431−
432− case SETTABLEPOP:
433− luaV_settable(S->top-3);
434− S->top -= 2; /* pop table and index */
477+ }
478+ case OP_SETLOCAL: {
479+ *(base+GETARG_U(i)) = *(--top);
435480 break;
436−
437− case SETTABLE:
438− luaV_settable(S->top-3-(*pc++));
481+ }
482+ case OP_SETGLOBAL: {
483+ L->top = top;
484+ luaV_setglobal(L, kstr[GETARG_U(i)]);
485+ top--;
439486 break;
440−
441− case SETLISTW: aux += highbyte(*pc++);
442− case SETLIST: aux += *pc++; {
443− int n = *(pc++);
444− Hash *arr = avalue(S->top-n-1);
445− aux *= LFIELDS_PER_FLUSH;
487+ }
488+ case OP_SETTABLE: {
489+ StkId t = top-GETARG_A(i);
490+ L->top = top;
491+ luaV_settable(L, t, t+1);
492+ top -= GETARG_B(i); /* pop values */
493+ break;
494+ }
495+ case OP_SETLIST: {
496+ int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
497+ int n = GETARG_B(i);
498+ Hash *arr = hvalue(top-n-1);
499+ L->top = top-n; /* final value of `top' (in case of errors) */
446500 for (; n; n--)
447− luaH_setint(arr, n+aux, --S->top);
501+ *luaH_setint(L, arr, n+aux) = *(--top);
448502 break;
449503 }
450−
451− case SETMAP: aux = *pc++; {
452− Hash *arr = avalue(S->top-(2*aux)-3);
453− do {
454− luaH_set(arr, S->top-2, S->top-1);
455− S->top-=2;
456− } while (aux--);
504+ case OP_SETMAP: {
505+ int n = GETARG_U(i);
506+ StkId finaltop = top-2*n;
507+ Hash *arr = hvalue(finaltop-1);
508+ L->top = finaltop; /* final value of `top' (in case of errors) */
509+ for (; n; n--) {
510+ top-=2;
511+ *luaH_set(L, arr, top) = *(top+1);
512+ }
457513 break;
458514 }
459−
460− case NEQOP: aux = 1;
461− case EQOP: {
462− int res = luaO_equalObj(S->top-2, S->top-1);
463− if (aux) res = !res;
464− S->top--;
465− ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
466− nvalue(S->top-1) = 1;
515+ case OP_ADD: {
516+ if (tonumber(top-2) || tonumber(top-1))
517+ call_arith(L, top, TM_ADD);
518+ else
519+ nvalue(top-2) += nvalue(top-1);
520+ top--;
467521 break;
468522 }
469−
470− case LTOP:
471− luaV_comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
472− break;
473−
474− case LEOP:
475− luaV_comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
523+ case OP_ADDI: {
524+ if (tonumber(top-1)) {
525+ ttype(top) = LUA_TNUMBER;
526+ nvalue(top) = (Number)GETARG_S(i);
527+ call_arith(L, top+1, TM_ADD);
528+ }
529+ else
530+ nvalue(top-1) += (Number)GETARG_S(i);
476531 break;
477−
478− case GTOP:
479− luaV_comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
532+ }
533+ case OP_SUB: {
534+ if (tonumber(top-2) || tonumber(top-1))
535+ call_arith(L, top, TM_SUB);
536+ else
537+ nvalue(top-2) -= nvalue(top-1);
538+ top--;
480539 break;
481−
482− case GEOP:
483− luaV_comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
540+ }
541+ case OP_MULT: {
542+ if (tonumber(top-2) || tonumber(top-1))
543+ call_arith(L, top, TM_MUL);
544+ else
545+ nvalue(top-2) *= nvalue(top-1);
546+ top--;
484547 break;
485−
486− case ADDOP: {
487− TObject *l = S->top-2;
488− TObject *r = S->top-1;
489− if (tonumber(r) || tonumber(l))
490− call_arith(IM_ADD);
491− else {
492− nvalue(l) += nvalue(r);
493− --S->top;
494− }
548+ }
549+ case OP_DIV: {
550+ if (tonumber(top-2) || tonumber(top-1))
551+ call_arith(L, top, TM_DIV);
552+ else
553+ nvalue(top-2) /= nvalue(top-1);
554+ top--;
495555 break;
496556 }
497−
498− case SUBOP: {
499− TObject *l = S->top-2;
500− TObject *r = S->top-1;
501− if (tonumber(r) || tonumber(l))
502− call_arith(IM_SUB);
503− else {
504− nvalue(l) -= nvalue(r);
505− --S->top;
506− }
557+ case OP_POW: {
558+ if (!call_binTM(L, top, TM_POW))
559+ lua_error(L, "undefined operation");
560+ top--;
507561 break;
508562 }
509−
510− case MULTOP: {
511− TObject *l = S->top-2;
512− TObject *r = S->top-1;
513− if (tonumber(r) || tonumber(l))
514− call_arith(IM_MUL);
515− else {
516− nvalue(l) *= nvalue(r);
517− --S->top;
518− }
563+ case OP_CONCAT: {
564+ int n = GETARG_U(i);
565+ luaV_strconc(L, n, top);
566+ top -= n-1;
567+ L->top = top;
568+ luaC_checkGC(L);
519569 break;
520570 }
521−
522− case DIVOP: {
523− TObject *l = S->top-2;
524− TObject *r = S->top-1;
525− if (tonumber(r) || tonumber(l))
526− call_arith(IM_DIV);
527− else {
528− nvalue(l) /= nvalue(r);
529− --S->top;
571+ case OP_MINUS: {
572+ if (tonumber(top-1)) {
573+ ttype(top) = LUA_TNIL;
574+ call_arith(L, top+1, TM_UNM);
530575 }
576+ else
577+ nvalue(top-1) = -nvalue(top-1);
531578 break;
532579 }
533−
534− case POWOP:
535− call_binTM(IM_POW, "undefined operation");
580+ case OP_NOT: {
581+ ttype(top-1) =
582+ (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
583+ nvalue(top-1) = 1;
536584 break;
537−
538− case CONCOP: {
539− TObject *l = S->top-2;
540− TObject *r = S->top-1;
541− if (tostring(l) || tostring(r))
542− call_binTM(IM_CONCAT, "unexpected type for concatenation");
543− else {
544− tsvalue(l) = strconc(tsvalue(l), tsvalue(r));
545− --S->top;
546− }
547− luaC_checkGC();
585+ }
586+ case OP_JMPNE: {
587+ top -= 2;
588+ if (!luaO_equalObj(top, top+1)) dojump(pc, i);
548589 break;
549590 }
550−
551− case MINUSOP:
552− if (tonumber(S->top-1)) {
553− ttype(S->top) = LUA_T_NIL;
554− S->top++;
555− call_arith(IM_UNM);
556− }
557− else
558− nvalue(S->top-1) = - nvalue(S->top-1);
591+ case OP_JMPEQ: {
592+ top -= 2;
593+ if (luaO_equalObj(top, top+1)) dojump(pc, i);
559594 break;
560−
561− case NOTOP:
562− ttype(S->top-1) =
563− (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
564− nvalue(S->top-1) = 1;
595+ }
596+ case OP_JMPLT: {
597+ top -= 2;
598+ if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
565599 break;
566−
567− case ONTJMPW: aux += highbyte(*pc++);
568− case ONTJMP: aux += *pc++;
569− if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
570− else S->top--;
600+ }
601+ case OP_JMPLE: { /* a <= b === !(b<a) */
602+ top -= 2;
603+ if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
571604 break;
572−
573− case ONFJMPW: aux += highbyte(*pc++);
574− case ONFJMP: aux += *pc++;
575− if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
576− else S->top--;
605+ }
606+ case OP_JMPGT: { /* a > b === (b<a) */
607+ top -= 2;
608+ if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
577609 break;
578−
579− case JMPW: aux += highbyte(*pc++);
580− case JMP: aux += *pc++;
581− pc += aux;
610+ }
611+ case OP_JMPGE: { /* a >= b === !(a<b) */
612+ top -= 2;
613+ if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
582614 break;
583−
584− case IFFJMPW: aux += highbyte(*pc++);
585− case IFFJMP: aux += *pc++;
586− if (ttype(--S->top) == LUA_T_NIL) pc += aux;
615+ }
616+ case OP_JMPT: {
617+ if (ttype(--top) != LUA_TNIL) dojump(pc, i);
587618 break;
588−
589− case IFTUPJMPW: aux += highbyte(*pc++);
590− case IFTUPJMP: aux += *pc++;
591− if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
619+ }
620+ case OP_JMPF: {
621+ if (ttype(--top) == LUA_TNIL) dojump(pc, i);
592622 break;
593−
594− case IFFUPJMPW: aux += highbyte(*pc++);
595− case IFFUPJMP: aux += *pc++;
596− if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
623+ }
624+ case OP_JMPONT: {
625+ if (ttype(top-1) == LUA_TNIL) top--;
626+ else dojump(pc, i);
597627 break;
598−
599− case CLOSUREW: aux += highbyte(*pc++);
600− case CLOSURE: aux += *pc++;
601− *S->top++ = consts[aux];
602− luaV_closure(*pc++);
603− luaC_checkGC();
628+ }
629+ case OP_JMPONF: {
630+ if (ttype(top-1) != LUA_TNIL) top--;
631+ else dojump(pc, i);
604632 break;
605−
606− case SETLINEW: aux += highbyte(*pc++);
607− case SETLINE: aux += *pc++;
608− if ((S->stack+base-1)->ttype != LUA_T_LINE) {
609− /* open space for LINE value */
610− luaD_openstack((S->top-S->stack)-base);
611− base++;
612− (S->stack+base-1)->ttype = LUA_T_LINE;
633+ }
634+ case OP_JMP: {
635+ dojump(pc, i);
636+ break;
637+ }
638+ case OP_PUSHNILJMP: {
639+ ttype(top++) = LUA_TNIL;
640+ pc++;
641+ break;
642+ }
643+ case OP_FORPREP: {
644+ if (tonumber(top-1))
645+ lua_error(L, "`for' step must be a number");
646+ if (tonumber(top-2))
647+ lua_error(L, "`for' limit must be a number");
648+ if (tonumber(top-3))
649+ lua_error(L, "`for' initial value must be a number");
650+ if (nvalue(top-1) > 0 ?
651+ nvalue(top-3) > nvalue(top-2) :
652+ nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
653+ top -= 3; /* remove control variables */
654+ dojump(pc, i); /* jump to loop end */
613655 }
614− (S->stack+base-1)->value.i = aux;
615− if (L->linehook)
616− luaD_lineHook(aux);
617656 break;
618−
619− case LONGARGW: aux += highbyte(*pc++);
620− case LONGARG: aux += *pc++;
621− aux = highbyte(highbyte(aux));
622− goto switchentry; /* do not reset "aux" */
623−
624− case CHECKSTACK: aux = *pc++;
625− LUA_ASSERT((S->top-S->stack)-base == aux && S->last >= S->top,
626− "wrong stack size");
657+ }
658+ case OP_FORLOOP: {
659+ LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
660+ LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
661+ if (ttype(top-3) != LUA_TNUMBER)
662+ lua_error(L, "`for' index must be a number");
663+ nvalue(top-3) += nvalue(top-1); /* increment index */
664+ if (nvalue(top-1) > 0 ?
665+ nvalue(top-3) > nvalue(top-2) :
666+ nvalue(top-3) < nvalue(top-2))
667+ top -= 3; /* end loop: remove control variables */
668+ else
669+ dojump(pc, i); /* repeat loop */
627670 break;
628−
671+ }
672+ case OP_LFORPREP: {
673+ Node *node;
674+ if (ttype(top-1) != LUA_TTABLE)
675+ lua_error(L, "`for' table must be a table");
676+ node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
677+ if (node == NULL) { /* `empty' loop? */
678+ top--; /* remove table */
679+ dojump(pc, i); /* jump to loop end */
680+ }
681+ else {
682+ top += 2; /* index,value */
683+ *(top-2) = *key(node);
684+ *(top-1) = *val(node);
685+ }
686+ break;
687+ }
688+ case OP_LFORLOOP: {
689+ Node *node;
690+ LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
691+ node = luaH_next(L, hvalue(top-3), top-2);
692+ if (node == NULL) /* end loop? */
693+ top -= 3; /* remove table, key, and value */
694+ else {
695+ *(top-2) = *key(node);
696+ *(top-1) = *val(node);
697+ dojump(pc, i); /* repeat loop */
698+ }
699+ break;
700+ }
701+ case OP_CLOSURE: {
702+ L->top = top;
703+ luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
704+ top = L->top;
705+ luaC_checkGC(L);
706+ break;
707+ }
629708 }
630− } ret:
631− if (L->callhook)
632− luaD_callHook(0, NULL, 1);
633− return base;
709+ }
634710 }
635−
src/lvm.h+13−15
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lvm.h,v 1.8 1999/02/08 17:07:59 roberto Exp $
2+** $Id: lvm.h,v 1.27 2000/10/05 12:14:08 roberto Exp $
33 ** Lua virtual machine
44 ** See Copyright Notice in lua.h
55 */
@@ -13,22 +13,20 @@ · 7 unmodified lines
1313 #include "ltm.h"
1414
1515
16−#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0))
17−#define tostring(o) ((ttype(o) != LUA_T_STRING) && (luaV_tostring(o) != 0))
16+#define tonumber(o) ((ttype(o) != LUA_TNUMBER) && (luaV_tonumber(o) != 0))
17+#define tostring(L,o) ((ttype(o) != LUA_TSTRING) && (luaV_tostring(L, o) != 0))
1818
1919
20−void luaV_pack (StkId firstel, int nvararg, TObject *tab);
2120 int luaV_tonumber (TObject *obj);
22−int luaV_tostring (TObject *obj);
23−void luaV_setn (Hash *t, int val);
24−void luaV_gettable (void);
25−void luaV_settable (TObject *t);
26−void luaV_rawsettable (TObject *t);
27−void luaV_getglobal (TaggedString *ts);
28−void luaV_setglobal (TaggedString *ts);
29−StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base);
30−void luaV_closure (int nelems);
31−void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
32− lua_Type ttype_great, IMS op);
21+int luaV_tostring (lua_State *L, TObject *obj);
22+const TObject *luaV_gettable (lua_State *L, StkId t);
23+void luaV_settable (lua_State *L, StkId t, StkId key);
24+const TObject *luaV_getglobal (lua_State *L, TString *s);
25+void luaV_setglobal (lua_State *L, TString *s);
26+StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
27+void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
28+void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
29+int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
30+void luaV_strconc (lua_State *L, int total, StkId top);
3331
3432 #endif
src/lzio.c+34−34
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lzio.c,v 1.7 1999/03/05 13:15:50 roberto Exp $
2+** $Id: lzio.c,v 1.13 2000/06/12 13:52:05 roberto Exp $
33 ** a generic input stream interface
44 ** See Copyright Notice in lua.h
55 */
@@ -9,6 +9,8 @@ · 3 unmodified lines
99 #include <stdio.h>
1010 #include <string.h>
1111
12+#include "lua.h"
13+
1214 #include "lzio.h"
1315
1416
@@ -16,62 +18,60 @@ · 1 unmodified line
1618 /* ----------------------------------------------------- memory buffers --- */
1719
1820 static int zmfilbuf (ZIO* z) {
19− return EOZ;
21+ (void)z; /* to avoid warnings */
22+ return EOZ;
2023 }
2124
2225
23−ZIO* zmopen (ZIO* z, char* b, int size, char *name)
24−{
25− if (b==NULL) return NULL;
26− z->n=size;
27− z->p= (unsigned char *)b;
28− z->filbuf=zmfilbuf;
29− z->u=NULL;
30− z->name=name;
31− return z;
26+ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name) {
27+ if (b==NULL) return NULL;
28+ z->n = size;
29+ z->p = (const unsigned char *)b;
30+ z->filbuf = zmfilbuf;
31+ z->u = NULL;
32+ z->name = name;
33+ return z;
3234 }
3335
3436 /* ------------------------------------------------------------ strings --- */
3537
36−ZIO* zsopen (ZIO* z, char* s, char *name)
37−{
38− if (s==NULL) return NULL;
39− return zmopen(z,s,strlen(s),name);
38+ZIO* zsopen (ZIO* z, const char* s, const char *name) {
39+ if (s==NULL) return NULL;
40+ return zmopen(z, s, strlen(s), name);
4041 }
4142
4243 /* -------------------------------------------------------------- FILEs --- */
4344
4445 static int zffilbuf (ZIO* z) {
45− int n;
46− if (feof((FILE *)z->u)) return EOZ;
47− n=fread(z->buffer,1,ZBSIZE,z->u);
48− if (n==0) return EOZ;
49− z->n=n-1;
50− z->p=z->buffer;
51− return *(z->p++);
46+ size_t n;
47+ if (feof((FILE *)z->u)) return EOZ;
48+ n = fread(z->buffer, 1, ZBSIZE, (FILE *)z->u);
49+ if (n==0) return EOZ;
50+ z->n = n-1;
51+ z->p = z->buffer;
52+ return *(z->p++);
5253 }
5354
5455
55−ZIO* zFopen (ZIO* z, FILE* f, char *name)
56−{
57− if (f==NULL) return NULL;
58− z->n=0;
59− z->p=z->buffer;
60− z->filbuf=zffilbuf;
61− z->u=f;
62− z->name=name;
63− return z;
56+ZIO* zFopen (ZIO* z, FILE* f, const char *name) {
57+ if (f==NULL) return NULL;
58+ z->n = 0;
59+ z->p = z->buffer;
60+ z->filbuf = zffilbuf;
61+ z->u = f;
62+ z->name = name;
63+ return z;
6464 }
6565
6666
6767 /* --------------------------------------------------------------- read --- */
68−int zread (ZIO *z, void *b, int n) {
68+size_t zread (ZIO *z, void *b, size_t n) {
6969 while (n) {
70− int m;
70+ size_t m;
7171 if (z->n == 0) {
7272 if (z->filbuf(z) == EOZ)
7373 return n; /* return number of missing bytes */
74− zungetc(z); /* put result from 'filbuf' in the buffer */
74+ zungetc(z); /* put result from `filbuf' in the buffer */
7575 }
7676 m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
7777 memcpy(b, z->p, m);
src/lzio.h+15−12
@@ -1,5 +1,5 @@
11 /*
2−** $Id: lzio.h,v 1.4 1998/01/09 14:57:43 roberto Exp $
2+** $Id: lzio.h,v 1.7 2000/10/20 16:36:32 roberto Exp $
33 ** Buffered streams
44 ** See Copyright Notice in lua.h
55 */
@@ -22,28 +22,31 @@ · 16 unmodified lines
2222
2323 typedef struct zio ZIO;
2424
25−ZIO* zFopen (ZIO* z, FILE* f, char *name); /* open FILEs */
26−ZIO* zsopen (ZIO* z, char* s, char *name); /* string */
27−ZIO* zmopen (ZIO* z, char* b, int size, char *name); /* memory */
25+ZIO* zFopen (ZIO* z, FILE* f, const char *name); /* open FILEs */
26+ZIO* zsopen (ZIO* z, const char* s, const char *name); /* string */
27+ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name); /* memory */
2828
29−int zread (ZIO* z, void* b, int n); /* read next n bytes */
29+size_t zread (ZIO* z, void* b, size_t n); /* read next n bytes */
3030
31−#define zgetc(z) (--(z)->n>=0 ? ((int)*(z)->p++): (z)->filbuf(z))
31+#define zgetc(z) (((z)->n--)>0 ? ((int)*(z)->p++): (z)->filbuf(z))
3232 #define zungetc(z) (++(z)->n,--(z)->p)
3333 #define zname(z) ((z)->name)
3434
3535
36+
3637 /* --------- Private Part ------------------ */
3738
39+#ifndef ZBSIZE
3840 #define ZBSIZE 256 /* buffer size */
41+#endif
3942
4043 struct zio {
41− int n; /* bytes still unread */
42− unsigned char* p; /* current position in buffer */
43− int (*filbuf)(ZIO* z);
44− void* u; /* additional data */
45− char *name;
46− unsigned char buffer[ZBSIZE]; /* buffer */
44+ size_t n; /* bytes still unread */
45+ const unsigned char* p; /* current position in buffer */
46+ int (*filbuf)(ZIO* z);
47+ void* u; /* additional data */
48+ const char *name;
49+ unsigned char buffer[ZBSIZE]; /* buffer */
4750 };
4851
4952

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