summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2007-12-27 11:02:25 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2007-12-27 11:02:25 -0200
commitf5ae26ec6c2eb69f03f316e59c1e1977c52c7c23 (patch)
treeb4c761dac7648caea2cc20f8ebc2dd5b27a3fa1e
parent98194db4295726069137d13b8d24fca8cbf892b6 (diff)
downloadlua-f5ae26ec6c2eb69f03f316e59c1e1977c52c7c23.tar.gz
lua-f5ae26ec6c2eb69f03f316e59c1e1977c52c7c23.tar.bz2
lua-f5ae26ec6c2eb69f03f316e59c1e1977c52c7c23.zip
official branch for Lua 5.1
-rw-r--r--bugs1015
-rw-r--r--lapi.c1080
-rw-r--r--lapi.h16
-rw-r--r--lauxlib.c653
-rw-r--r--lauxlib.h174
-rw-r--r--lbaselib.c643
-rw-r--r--lcode.c823
-rw-r--r--lcode.h76
-rw-r--r--ldblib.c397
-rw-r--r--ldebug.c620
-rw-r--r--ldebug.h33
-rw-r--r--ldo.c516
-rw-r--r--ldo.h57
-rw-r--r--ldump.c164
-rw-r--r--lfunc.c174
-rw-r--r--lfunc.h34
-rw-r--r--lgc.c711
-rw-r--r--lgc.h110
-rw-r--r--linit.c38
-rw-r--r--liolib.c532
-rw-r--r--llex.c461
-rw-r--r--llex.h81
-rw-r--r--llimits.h128
-rw-r--r--lmathlib.c263
-rw-r--r--lmem.c86
-rw-r--r--lmem.h49
-rw-r--r--loadlib.c663
-rw-r--r--lobject.c214
-rw-r--r--lobject.h381
-rw-r--r--lopcodes.c102
-rw-r--r--lopcodes.h268
-rw-r--r--loslib.c233
-rw-r--r--lparser.c1337
-rw-r--r--lparser.h82
-rw-r--r--lstate.c214
-rw-r--r--lstate.h168
-rw-r--r--lstring.c111
-rw-r--r--lstring.h31
-rw-r--r--lstrlib.c868
-rw-r--r--ltable.c588
-rw-r--r--ltable.h40
-rw-r--r--ltablib.c278
-rw-r--r--ltests.c1145
-rw-r--r--ltests.h86
-rw-r--r--ltm.c75
-rw-r--r--ltm.h54
-rw-r--r--lua.c390
-rw-r--r--lua.h385
-rw-r--r--luaconf.h762
-rw-r--r--lualib.h53
-rw-r--r--lundump.c223
-rw-r--r--lundump.h36
-rw-r--r--lvm.c763
-rw-r--r--lvm.h36
-rw-r--r--lzio.c82
-rw-r--r--lzio.h67
56 files changed, 0 insertions, 18669 deletions
diff --git a/bugs b/bugs
deleted file mode 100644
index a9f53823..00000000
--- a/bugs
+++ /dev/null
@@ -1,1015 +0,0 @@
1--[=[
2** lua.stx / llex.c
3Tue Dec 2 10:45:48 EDT 1997
4>> BUG: "lastline" was not reset on function entry, so debug information
5>> started only in the 2nd line of a function.
6
7
8
9=================================================================
10--- Version 3.1 alpha
11
12** lua.c
13Thu Jan 15 14:34:58 EDT 1998
14>> must include "stdlib.h" (for "exit()").
15
16** lbuiltin.c / lobject.h
17Thu Jan 15 14:34:58 EDT 1998
18>> MAX_WORD may be bigger than MAX_INT
19(by lhf)
20
21** llex.c
22Mon Jan 19 18:17:18 EDT 1998
23>> wrong line number (+1) in error report when file starts with "#..."
24
25** lstrlib.c
26Tue Jan 27 15:27:49 EDT 1998
27>> formats like "%020d" were considered too big (3 digits); moreover,
28>> some sistems limit printf to at most 500 chars, so we can limit sizes
29>> to 2 digits (99).
30
31** lapi.c
32Tue Jan 27 17:12:36 EDT 1998
33>> "lua_getstring" may create a new string, so should check GC
34
35** lstring.c / ltable.c
36Wed Jan 28 14:48:12 EDT 1998
37>> tables can become full of "empty" slots, and keep growing without limits.
38
39** lstrlib.c
40Mon Mar 9 15:26:09 EST 1998
41>> gsub('a', '(b?)%1*' ...) loops (because the capture is empty).
42
43** lstrlib.c
44Mon May 18 19:20:00 EST 1998
45>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int.
46
47
48
49=================================================================
50--- Version 3.1
51
52** liolib.c / lauxlib.c
53Mon Sep 7 15:57:02 EST 1998
54>> function "luaL_argerror" prints wrong argument number (from a user's point
55of view) when functions have upvalues.
56
57** lstrlib.c
58Tue Nov 10 17:29:36 EDT 1998
59>> gsub/strfind do not check whether captures are properly finished.
60(by roberto/tomas)
61
62** lbuiltin.c
63Fri Dec 18 11:22:55 EDT 1998
64>> "tonumber" goes crazy with negative numbers in other bases (not 10),
65because "strtol" returns long, not unsigned long.
66(by Visual C++)
67
68** lstrlib.c
69Mon Jan 4 10:41:40 EDT 1999
70>> "format" does not check size of format item (such as "%00000...00000d").
71
72** lapi.c
73Wed Feb 3 14:40:21 EDT 1999
74>> getlocal cannot return the local itself, since lua_isstring and
75lua_isnumber can modify it.
76
77** lstrlib.c
78Thu Feb 4 17:08:50 EDT 1999
79>> format "%s" may break limit of "sprintf" on some machines.
80(by Marcelo Sales)
81
82** lzio.c
83Thu Mar 4 11:49:37 EST 1999
84>> file stream cannot call fread after EOF.
85(by lhf)
86
87
88
89=================================================================
90--- Version 3.2 (beta)
91
92** lstrlib.c
93Fri Apr 30 11:10:20 EST 1999
94>> '$' at end of pattern was matching regular '$', too.
95(by anna; since 2.5)
96
97** lbuiltin.c
98Fri May 21 17:15:11 EST 1999
99>> foreach, foreachi, foreachvar points to function in stack when stack
100can be reallocated.
101(by tomas; since 3.2 beta)
102
103** lparser.c
104Wed Jun 16 10:32:46 EST 1999
105>> cannot assign to unlimited variables, because it causes overflow in
106the number of returns of a function.
107(since 3.1)
108
109
110
111=================================================================
112--- Version 3.2
113
114** lmathlib.c
115Wed Aug 18 11:28:38 EST 1999
116>> random(0) and random(x,0) are wrong (0 is read as no argument!).
117(by Dave Bollinger; since 3.1)
118
119** lparser.c
120Thu Sep 2 10:07:20 EST 1999
121>> in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname
122could realloc f->consts.
123(by Supratik Champati; since 3.2 beta)
124
125** lobject.c / lbuiltin.c
126Wed Sep 8 17:41:54 EST 1999
127>> tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil.
128(since 3.1)
129
130** lstrlib.c
131Thu Nov 11 14:36:30 EDT 1999
132>> `strfind' does not handle \0 in plain search.
133(by Jon Kleiser; since 3.1)
134
135** lparser.c
136Wed Dec 29 16:05:43 EDT 1999
137>> return gives wrong line in debug information
138(by lhf; since 3.2 [at least])
139
140** ldo.c
141Thu Dec 30 16:39:33 EDT 1999
142>> cannot reopen stdin (for binary mode)
143(by lhf & roberto; since 3.1)
144
145** lapi.c
146Thu Mar 2 09:41:53 EST 2000
147>> lua_settable should check stack space (it could call a T.M.)
148(by lhf & celes; since 3.2; it was already fixed by fixed stack)
149
150** lparser.c
151Mon Apr 3 09:59:06 EST 2000
152>> '%' should be in expfollow
153(by Edgar Toernig; since 3.1; it was already fixed)
154
155** lbuiltin.c
156Mon Apr 3 10:05:05 EST 2000
157>> tostring() without arguments gives seg. fault.
158(by Edgar Toernig; since 3.0)
159
160
161
162=================================================================
163--- Version 4.0 alpha
164
165Tested with full test suites (as locked in Mon Apr 24 14:23:11 EST 2000)
166in the following platforms:
167* Linux - gcc, g++
168* AIX - gcc
169* Solaris - gcc, cc
170* IRIX - cc, cc-purify
171* Windows - Visual C++ (.c e .cpp, warning level=4)
172
173
174** lstrlib.c
175Tue May 2 15:27:58 EST 2000
176>> `strfind' gets wrong subject length when there is an offset
177(by Jon Kleiser; since 4.0a)
178
179** lparser.c
180Fri May 12 15:11:12 EST 2000
181>> first element in a list constructor is not adjusted to one value
182>> (e.g. «a = {gsub('a','a','')}»)
183(by Tomas; since 4.0a)
184
185** lparser.c
186Wed May 24 14:50:16 EST 2000
187>> record-constructor starting with an upvalue name gets an error
188>> (e.g. «local a; function f() x = {a=1} end»)
189(by Edgar Toernig; since 3.1)
190
191** lparser.c
192Tue Aug 29 15:56:05 EST 2000
193>> error message for `for' uses `while'
194(since 4.0a; already corrected)
195
196** lgc.c
197Tue Aug 29 15:57:41 EST 2000
198>> gc tag method for nil could call line hook
199(by ry; since ?)
200
201
202
203=================================================================
204--- Version 4.0 Beta
205
206** liolib.c
207Fri Sep 22 15:12:37 EST 2000
208>> `read("*w")' should return nil at EOF
209(by roberto; since 4.0b)
210
211** lvm.c
212Mon Sep 25 11:47:48 EST 2000
213>> lua_gettable does not get key from stack top
214(by Philip Yi; since 4.0b)
215
216** lgc.c
217Mon Sep 25 11:50:48 EST 2000
218>> GC may crash when checking locked C closures
219(by Philip Yi; since 4.0b)
220
221** lapi.c
222Wed Sep 27 09:50:19 EST 2000
223>> lua_tag should return LUA_NOTAG for non-valid indices
224(by Paul Hankin; since 4.0b)
225
226** llex.h / llex.c / lparser.c
227Wed Sep 27 13:39:45 EST 2000
228>> parser overwrites semantic information when looking ahead
229>> (e.g. «a = {print'foo'}»)
230(by Edgar Toernig; since 4.0b, deriving from previous bug)
231
232** liolib.c
233Thu Oct 26 10:50:46 EDT 2000
234>> in function `read_file', realloc() doesn't free the buffer if it can't
235>> allocate new memory
236(by Mauro Vezzosi; since 4.0b)
237
238
239
240=================================================================
241--- Version 4.0
242
243** lparser.c
244Wed Nov 29 09:51:44 EDT 2000
245>> parser does not accept a `;' after a `return'
246(by lhf; since 4.0b)
247
248** liolib.c
249Fri Dec 22 15:30:42 EDT 2000
250>> when `read' fails it must return nil (and not no value)
251(by cassino; since at least 3.1)
252
253** lstring.c/lapi.c
254Thu Feb 1 11:55:45 EDT 2001
255>> lua_pushuserdata(L, NULL) is buggy
256(by Edgar Toernig; since 4.0)
257
258** ldo.c
259Fri Feb 2 14:06:40 EDT 2001
260>> «while 1 dostring[[print('hello\n')]] end» never reclaims memory
261(by Andrew Paton; since 4.0b)
262
263** lbaselib.c
264Tue Feb 6 11:57:13 EDT 2001
265>> ESC (which starts precompiled code) in C is \33, not \27
266(by Edgar Toernig and lhf; since 4.0b)
267
268** lparser.c
269Tue Jul 10 16:59:18 EST 2001
270>> error message for `%a' gave wrong line number
271(by Leonardo Constantino; since 4.0)
272
273** lbaselib.c
274Fri Dec 21 15:21:05 EDT 2001
275>> seg. fault when rawget/rawset get extra arguments
276(by Eric Mauger; since 4.0b)
277
278** lvm.c
279Wed Jun 19 13:28:20 EST 2002
280>> line hook gets wrong `ar'
281(by Daniel C. Sinclair; since 4.0.b)
282
283** ldo.c
284Wed Jun 19 13:31:49 EST 2002
285>> `protectedparser' may run GC, and then collect `filename'
286>> (in function `parse_file')
287(by Alex Bilyk; since 4.0)
288
289
290
291
292=================================================================
293--- Version 5.0 alpha
294
295** lgc.c
296Fri Aug 30 13:49:14 EST 2002
297>> GC metamethod stored in a weak metatable being collected together with
298>> userdata may not be cleared properly
299(by Roberto; since 5.0a)
300
301** lapi.c
302Thu Nov 21 11:00:00 EST 2002
303>> ULONG_MAX>>10 may not fit into an int
304(by Jeff Petkau; since 4.0)
305
306** lparser.c
307Fri Dec 6 17:06:40 UTC 2002
308>> scope of generic for variables is not sound
309(by Gavin Wraith; since 5.0a)
310
311
312
313
314=================================================================
315--- Version 5.0 beta
316** lbaselib.c
317Fri Dec 20 09:53:19 UTC 2002
318>> `resume' was checking the wrong value for stack overflow
319(by Maik Zimmermann; since 5.0b)
320
321** ldo.c
322Thu Jan 23 11:29:06 UTC 2003
323>> error during garbage collection in luaD_protectedparser is not being
324>> protected
325(by Benoit Germain; since 5.0a)
326
327** ldo.c (and others)
328Fri Feb 28 14:20:33 EST 2003
329>> GC metamethod calls could mess C/Lua stack syncronization
330(by Roberto; since 5.0b)
331
332** lzio.h/zlio.c
333Thu Mar 20 11:40:12 EST 2003
334>> zio mixes a 255 as first char in a buffer with EOZ
335(by lhf; since 5.0a)
336
337
338
339--]=]
340-----------------------------------------------------------------
341-- Lua 5.0 (final)
342
343Bug{
344what = [[lua_closethread exists only in the manual]],
345report = [[by Nguyen Binh, 28/04/2003]],
346patch = [[no patch; the manual is wrong]],
347}
348
349
350Bug{
351what = [[attempt to resume a running coroutine crashes Lua]],
352example = [[
353function co_func (current_co)
354 coroutine.resume(co)
355end
356co = coroutine.create(co_func)
357coroutine.resume(co)
358coroutine.resume(co) --> seg. fault
359]],
360report = [[by Alex Bilyk, 09/05/2003]],
361patch = [[
362* ldo.c:
363325,326c325
364< if (nargs >= L->top - L->base)
365< luaG_runerror(L, "cannot resume dead coroutine");
366---
367> lua_assert(nargs < L->top - L->base);
368329c328,329
369< else if (ci->state & CI_YIELD) { /* inside a yield? */
370---
371> else { /* inside a yield */
372> lua_assert(ci->state & CI_YIELD);
373344,345d343
374< else
375< luaG_runerror(L, "cannot resume non-suspended coroutine");
376351a350,358
377> static int resume_error (lua_State *L, const char *msg) {
378> L->top = L->ci->base;
379> setsvalue2s(L->top, luaS_new(L, msg));
380> incr_top(L);
381> lua_unlock(L);
382> return LUA_ERRRUN;
383> }
384>
385>
386355a363,368
387> if (L->ci == L->base_ci) {
388> if (nargs >= L->top - L->base)
389> return resume_error(L, "cannot resume dead coroutine");
390> }
391> else if (!(L->ci->state & CI_YIELD)) /* not inside a yield? */
392> return resume_error(L, "cannot resume non-suspended coroutine");
393]],
394}
395
396
397Bug{
398what = [[file:close cannot be called without a file. (results in seg fault)]],
399example = [[
400> io.stdin.close() -- correct call shold be io.stdin:close()
401]],
402report = [[by Tuomo Valkonen, 27/05/2003]],
403patch = [[
404* liolib.c:
405161c161
406< if (lua_isnone(L, 1)) {
407---
408> if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {
409]], --}}
410}
411
412
413Bug{
414what = [[C functions also may have stacks larger than current top]],
415example = [[
416Must recompile lua with a change in lua.c and with lua_assert defined:
417* lua.c:
418381a382
419> lua_checkstack(l, 1000);
420]],
421report = [[Alex Bilyk, 09/06/2003]],
422patch = [[
423* lgc.c:
424247c247
425< if (!(ci->state & CI_C) && lim < ci->top)
426---
427> if (lim < ci->top)
428]],
429}
430
431
432Bug{
433what = [[`pc' address is invalidated when a coroutine is suspended]],
434example = [[
435function g(x)
436 coroutine.yield(x)
437end
438
439function f (i)
440 debug.sethook(print, "l")
441 for j=1,1000 do
442 g(i+j)
443 end
444end
445
446co = coroutine.wrap(f)
447co(10)
448pcall(co)
449pcall(co)
450]],
451report = [[Nick Trout, 07/07/2003]],
452patch = [[
453* lvm.c:
454402,403c402,403
455< L->ci->u.l.pc = &pc;
456< if (L->hookmask & LUA_MASKCALL)
457---
458> if (L->hookmask & LUA_MASKCALL) {
459> L->ci->u.l.pc = &pc;
460404a405
461> }
462405a407
463> L->ci->u.l.pc = &pc;
464676,678c678
465< lua_assert(ci->u.l.pc == &pc &&
466< ttisfunction(ci->base - 1) &&
467< (ci->state & CI_SAVEDPC));
468---
469> lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));
470]]
471}
472
473
474Bug{
475what = [[userdata to be collected still counts into new GC threshold,
476increasing memory consumption]],
477report = [[Roberto, 25/07/2003]],
478example = [[
479a = newproxy(true)
480getmetatable(a).__gc = function () end
481for i=1,10000000 do
482 newproxy(a)
483 if math.mod(i, 10000) == 0 then print(gcinfo()) end
484end
485]],
486patch = [[
487* lgc.h:
48818c18
489< void luaC_separateudata (lua_State *L);
490---
491> size_t luaC_separateudata (lua_State *L);
492
493* lgc.c:
494113c113,114
495< void luaC_separateudata (lua_State *L) {
496---
497> size_t luaC_separateudata (lua_State *L) {
498> size_t deadmem = 0;
499127a129
500> deadmem += sizeudata(gcotou(curr)->uv.len);
501136a139
502> return deadmem;
503390c393
504< static void checkSizes (lua_State *L) {
505---
506> static void checkSizes (lua_State *L, size_t deadmem) {
507400c403
508< G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
509---
510> G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */
511454c457,458
512< static void mark (lua_State *L) {
513---
514> static size_t mark (lua_State *L) {
515> size_t deadmem;
516467c471
517< luaC_separateudata(L); /* separate userdata to be preserved */
518---
519> deadmem = luaC_separateudata(L); /* separate userdata to be preserved */
520475a480
521> return deadmem;
522480c485
523< mark(L);
524---
525> size_t deadmem = mark(L);
526482c487
527< checkSizes(L);
528---
529> checkSizes(L, deadmem);
530]]
531}
532
533Bug{
534what=[[IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
535up to 60 characters in a `printf'. That causes a buffer overflow in
536`tostring'.]],
537
538report = [[David Burgess, 25/08/2003]],
539
540example = [[print{}; (in an AS400 machine)]],
541
542patch = [[
543* liolib.c:
544178c178
545< char buff[32];
546---
547> char buff[128];
548
549* lbaselib.c:
550327c327
551< char buff[64];
552---
553> char buff[128];
554]]
555}
556
557
558Bug{
559what = [[syntax `local function' does not increment stack size]],
560
561report = [[Rici Lake, 26/09/2003]],
562
563example = [[
564-- must run this with precompiled code
565local a,b,c
566local function d () end
567]],
568
569patch = [[
570* lparser.c:
5711143a1144
572> FuncState *fs = ls->fs;
5731145c1146,1147
574< init_exp(&v, VLOCAL, ls->fs->freereg++);
575---
576> init_exp(&v, VLOCAL, fs->freereg);
577> luaK_reserveregs(fs, 1);
5781148c1150,1152
579< luaK_storevar(ls->fs, &v, &b);
580---
581> luaK_storevar(fs, &v, &b);
582> /* debug information will only see the variable after this point! */
583> getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
584]],
585
586}
587
588
589Bug{
590
591what = [[count hook may be called without being set]],
592
593report = [[Andreas Stenius, 06/10/2003]],
594
595example = [[
596set your hooks with
597
598 lua_sethook(L, my_hook, LUA_MASKLINE | LUA_MASKRET, 1);
599
600(It is weird to use a count > 0 without setting the count hook,
601but it is not wrong.)
602]],
603
604patch = [[
605* lvm.c:
60669c69
607< if (mask > LUA_MASKLINE) { /* instruction-hook set? */
608---
609> if (mask & LUA_MASKCOUNT) { /* instruction-hook set? */
610]],
611
612}
613
614
615Bug{
616
617what = [[`dofile' eats one return value when called without arguments]],
618
619report = [[Frederico Abraham, 15/01/2004]],
620
621example = [[
622a,b = dofile() --< here you enter `return 1,2,3 <eof>'
623print(a,b) --> 2 3 (should be 1 and 2)
624]],
625
626patch = [[
627* lbaselib.c:
628313a314
629> int n = lua_gettop(L);
630317c318
631< return lua_gettop(L) - 1;
632---
633> return lua_gettop(L) - n;
634]],
635
636}
637
638
639
640-----------------------------------------------------------------
641-- Lua 5.0.2
642
643Bug{
644what = [[string concatenation may cause arithmetic overflow, leading
645to a buffer overflow]],
646
647report = [[Rici Lake, 20/05/2004]],
648
649example = [[
650longs = string.rep("\0", 2^25)
651function catter(i)
652 return assert(loadstring(
653 string.format("return function(a) return a%s end",
654 string.rep("..a", i-1))))()
655end
656rep129 = catter(129)
657rep129(longs)
658]],
659
660patch = [[
661* lvm.c:
662@@ -321,15 +321,15 @@
663 luaG_concaterror(L, top-2, top-1);
664 } else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */
665 /* at least two string values; get as many as possible */
666- lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) +
667- cast(lu_mem, tsvalue(top-2)->tsv.len);
668+ size_t tl = tsvalue(top-1)->tsv.len;
669 char *buffer;
670 int i;
671- while (n < total && tostring(L, top-n-1)) { /* collect total length */
672- tl += tsvalue(top-n-1)->tsv.len;
673- n++;
674+ /* collect total length */
675+ for (n = 1; n < total && tostring(L, top-n-1); n++) {
676+ size_t l = tsvalue(top-n-1)->tsv.len;
677+ if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
678+ tl += l;
679 }
680- if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
681 buffer = luaZ_openspace(L, &G(L)->buff, tl);
682 tl = 0;
683 for (i=n; i>0; i--) { /* concat all strings */
684]]
685}
686
687
688Bug{
689what = [[lua_getupvalue and setupvalue do not check for index too small]],
690
691report = [[Mike Pall, ?/2004]],
692
693example = [[debug.getupvalue(function() end, 0)]],
694
695patch = [[
696* lapi.c
697941c941
698< if (n > f->c.nupvalues) return NULL;
699---
700> if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
701947c947
702< if (n > p->sizeupvalues) return NULL;
703---
704> if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
705]]
706}
707
708
709Bug{
710what = [[values holded in open upvalues of suspended threads may be
711incorrectly collected]],
712
713report = [[Spencer Schumann, 31/12/2004]],
714
715example = [[
716local thread_id = 0
717local threads = {}
718
719function fn(thread)
720 thread_id = thread_id + 1
721 threads[thread_id] = function()
722 thread = nil
723 end
724 coroutine.yield()
725end
726
727while true do
728 local thread = coroutine.create(fn)
729 coroutine.resume(thread, thread)
730end
731]],
732
733patch = [[
734* lgc.c:
735221,224c221,222
736< if (!u->marked) {
737< markobject(st, &u->value);
738< u->marked = 1;
739< }
740---
741> markobject(st, u->v);
742> u->marked = 1;
743]],
744}
745
746
747Bug{
748what = [[rawset/rawget do not ignore extra arguments]],
749
750report = [[Romulo Bahiense, 11/03/2005]],
751
752example = [[
753a = {}
754rawset(a, 1, 2, 3)
755print(a[1], a[2]) -- should be 2 and nil
756]],
757
758patch = [[
759* lbaselib.c:
760175a176
761> lua_settop(L, 2);
762183a185
763> lua_settop(L, 3);
764]],
765}
766
767
768Bug{
769what = [[weak tables that survive one collection are never collected]],
770
771report = [[Chromix, 02/01/2006]],
772
773example = [[
774a = {}
775print(gcinfo())
776for i = 1, 10000 do
777 a[i] = setmetatable({}, {__mode = "v"})
778end
779collectgarbage()
780a = nil
781collectgarbage()
782print(gcinfo())
783]],
784
785patch = [[
786* lgc.c
787@@ -366,7 +366,7 @@
788 GCObject *curr;
789 int count = 0; /* number of collected items */
790 while ((curr = *p) != NULL) {
791- if (curr->gch.marked > limit) {
792+ if ((curr->gch.marked & ~(KEYWEAK | VALUEWEAK)) > limit) {
793 unmark(curr);
794 p = &curr->gch.next;
795 }
796]],
797
798}
799
800
801
802-----------------------------------------------------------------
803-- Lua 5.1
804
805Bug{
806what = [[In 16-bit machines, expressions and/or with numeric constants as the
807right operand may result in weird values]],
808
809report = [[Andreas Stenius/Kein-Hong Man, 15/03/2006]],
810
811example = [[
812print(false or 0) -- on 16-bit machines
813]],
814
815patch = [[
816* lcode.c:
817@@ -731,17 +731,15 @@
818 case OPR_AND: {
819 lua_assert(e1->t == NO_JUMP); /* list must be closed */
820 luaK_dischargevars(fs, e2);
821- luaK_concat(fs, &e1->f, e2->f);
822- e1->k = e2->k; e1->u.s.info = e2->u.s.info;
823- e1->u.s.aux = e2->u.s.aux; e1->t = e2->t;
824+ luaK_concat(fs, &e2->f, e1->f);
825+ *e1 = *e2;
826 break;
827 }
828 case OPR_OR: {
829 lua_assert(e1->f == NO_JUMP); /* list must be closed */
830 luaK_dischargevars(fs, e2);
831- luaK_concat(fs, &e1->t, e2->t);
832- e1->k = e2->k; e1->u.s.info = e2->u.s.info;
833- e1->u.s.aux = e2->u.s.aux; e1->f = e2->f;
834+ luaK_concat(fs, &e2->t, e1->t);
835+ *e1 = *e2;
836 break;
837 }
838]],
839
840}
841
842
843Bug{
844what = [[luaL_checkudata may produce wrong error message]],
845
846report = [[Greg Falcon, 21/03/2006]],
847
848example = [[
849getmetatable(io.stdin).__gc()
850 --> bad argument #1 to '__gc' (FILE* expected, got table)
851]],
852
853patch = [[
854* lauxlib.c:
855@@ -123,11 +123,17 @@
856
857 LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
858 void *p = lua_touserdata(L, ud);
859- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
860- if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
861- luaL_typerror(L, ud, tname);
862- lua_pop(L, 2); /* remove both metatables */
863- return p;
864+ if (p != NULL) { /* value is a userdata? */
865+ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
866+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
867+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
868+ lua_pop(L, 2); /* remove both metatables */
869+ return p;
870+ }
871+ }
872+ }
873+ luaL_typerror(L, ud, tname); /* else error */
874+ return NULL; /* to avoid warnings */
875 }
876]]
877
878}
879
880
881Bug{
882what = [[
883In Windows,
884when Lua is used in an application that also uses DirectX,
885it may present an erractic behavior.
886THIS IS NOT A LUA BUG!
887The problem is that DirectX violates an ABI that Lua depends on.]],
888
889patch = [[
890The simplest solution is to use DirectX with
891the D3DCREATE_FPU_PRESERVE flag.
892
893Otherwise, you can change the definition of lua_number2int,
894in luaconf.h, to this one:
895#define lua_number2int(i,d) __asm fld d __asm fistp i
896]],
897
898}
899
900
901Bug{
902what = [[option '%q' in string.format does not handle '\r' correctly.]],
903
904example = [[
905local s = "a string with \r and \n and \r\n and \n\r"
906local c = string.format("return %q", s)
907assert(assert(loadstring(c))() == s)
908]],
909
910patch = [[
911* lstrlib.c:
912@@ -703,6 +703,10 @@
913 luaL_addchar(b, *s);
914 break;
915 }
916+ case '\r': {
917+ luaL_addlstring(b, "\\r", 2);
918+ break;
919+ }
920 case '\0': {
921 luaL_addlstring(b, "\\000", 4);
922 break;
923]],
924
925}
926
927
928Bug{
929what = [[lua_dostring/lua_dofile should return any values returned
930by the chunk]],
931
932patch = [[
933* lauxlib.h:
934@@ -108,9 +108,11 @@
935
936 #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
937
938-#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, 0, 0))
939+#define luaL_dofile(L, fn) \
940+ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
941
942-#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, 0, 0))+#define luaL_dostring(L, s) \
943+ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
944
945 #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
946]],
947
948}
949
950
951Bug{
952
953what = [[garbage collector does not compensate enough for finalizers]],
954
955patch = [[
956lgc.c:
957@@ -322,4 +322,6 @@
958
959-static void propagateall (global_State *g) {
960- while (g->gray) propagatemark(g);
961+static size_t propagateall (global_State *g) {
962+ size_t m = 0;
963+ while (g->gray) m += propagatemark(g);
964+ return m;
965 }
966@@ -542,3 +544,3 @@
967 marktmu(g); /* mark `preserved' userdata */
968- propagateall(g); /* remark, to propagate `preserveness' */
969+ udsize += propagateall(g); /* remark, to propagate `preserveness' */
970 cleartable(g->weak); /* remove collected objects from weak tables */
971@@ -592,2 +594,4 @@
972 GCTM(L);
973+ if (g->estimate > GCFINALIZECOST)
974+ g->estimate -= GCFINALIZECOST;
975]]
976}
977
978
979But{
980
981what = [[debug hooks may get wrong when mixed with coroutines]],
982
983report = [[by Ivko Stanilov, 03/06/2006]],
984
985example = [[
986co = coroutine.create(function (a,b)
987 coroutine.yield(a, b)
988 return b, "end"
989end)
990
991debug.sethook(co, function() end, "lcr")
992coroutine.resume(co, 100, 2000)
993coroutine.resume(co, 100, 2000)
994]],
995
996patch = [[
997* ldo.c:
998@@ -389,6 +389,7 @@
999 return;
1000 }
1001 else { /* resuming from previous yield */
1002+ L->status = 0;
1003 if (!f_isLua(ci)) { /* `common' yield? */
1004 /* finish interrupted execution of `OP_CALL' */
1005 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
1006@@ -399,7 +400,6 @@
1007 else /* yielded inside a hook: just continue its execution */
1008 L->base = L->ci->base;
1009 }
1010- L->status = 0;
1011 luaV_execute(L, cast_int(L->ci - L->base_ci));
1012 }
1013]],
1014
1015}
diff --git a/lapi.c b/lapi.c
deleted file mode 100644
index 0fa66eb4..00000000
--- a/lapi.c
+++ /dev/null
@@ -1,1080 +0,0 @@
1/*
2** $Id: lapi.c,v 2.54 2006/06/02 15:34:00 roberto Exp roberto $
3** Lua API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <assert.h>
9#include <math.h>
10#include <stdarg.h>
11#include <string.h>
12
13#define lapi_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "ldebug.h"
20#include "ldo.h"
21#include "lfunc.h"
22#include "lgc.h"
23#include "lmem.h"
24#include "lobject.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lundump.h"
30#include "lvm.h"
31
32
33
34const char lua_ident[] =
35 "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
36 "$Authors: " LUA_AUTHORS " $\n"
37 "$URL: www.lua.org $\n";
38
39
40
41#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
42
43#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
44
45#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
46
47
48
49static TValue *index2adr (lua_State *L, int idx) {
50 if (idx > 0) {
51 TValue *o = L->base + (idx - 1);
52 api_check(L, idx <= L->ci->top - L->base);
53 if (o >= L->top) return cast(TValue *, luaO_nilobject);
54 else return o;
55 }
56 else if (idx > LUA_REGISTRYINDEX) {
57 api_check(L, idx != 0 && -idx <= L->top - L->base);
58 return L->top + idx;
59 }
60 else switch (idx) { /* pseudo-indices */
61 case LUA_REGISTRYINDEX: return registry(L);
62 case LUA_ENVIRONINDEX: {
63 Closure *func = curr_func(L);
64 sethvalue(L, &L->env, func->c.env);
65 return &L->env;
66 }
67 case LUA_GLOBALSINDEX: return gt(L);
68 default: {
69 Closure *func = curr_func(L);
70 idx = LUA_GLOBALSINDEX - idx;
71 return (idx <= func->c.nupvalues)
72 ? &func->c.upvalue[idx-1]
73 : cast(TValue *, luaO_nilobject);
74 }
75 }
76}
77
78
79static Table *getcurrenv (lua_State *L) {
80 if (L->ci == L->base_ci) /* no enclosing function? */
81 return hvalue(gt(L)); /* use global table as environment */
82 else {
83 Closure *func = curr_func(L);
84 return func->c.env;
85 }
86}
87
88
89void luaA_pushobject (lua_State *L, const TValue *o) {
90 setobj2s(L, L->top, o);
91 api_incr_top(L);
92}
93
94
95LUA_API int lua_checkstack (lua_State *L, int size) {
96 int res;
97 lua_lock(L);
98 if ((L->top - L->base + size) > LUAI_MAXCSTACK)
99 res = 0; /* stack overflow */
100 else {
101 luaD_checkstack(L, size);
102 if (L->ci->top < L->top + size)
103 L->ci->top = L->top + size;
104 res = 1;
105 }
106 lua_unlock(L);
107 return res;
108}
109
110
111LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
112 int i;
113 if (from == to) return;
114 lua_lock(to);
115 api_checknelems(from, n);
116 api_check(from, G(from) == G(to));
117 api_check(from, to->ci->top - to->top >= n);
118 from->top -= n;
119 for (i = 0; i < n; i++) {
120 setobj2s(to, to->top++, from->top + i);
121 }
122 lua_unlock(to);
123}
124
125
126LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
127 lua_CFunction old;
128 lua_lock(L);
129 old = G(L)->panic;
130 G(L)->panic = panicf;
131 lua_unlock(L);
132 return old;
133}
134
135
136LUA_API lua_State *lua_newthread (lua_State *L) {
137 lua_State *L1;
138 lua_lock(L);
139 luaC_checkGC(L);
140 L1 = luaE_newthread(L);
141 setthvalue(L, L->top, L1);
142 api_incr_top(L);
143 lua_unlock(L);
144 luai_userstatethread(L, L1);
145 return L1;
146}
147
148
149
150/*
151** basic stack manipulation
152*/
153
154
155LUA_API int lua_gettop (lua_State *L) {
156 return cast_int(L->top - L->base);
157}
158
159
160LUA_API void lua_settop (lua_State *L, int idx) {
161 lua_lock(L);
162 if (idx >= 0) {
163 api_check(L, idx <= L->stack_last - L->base);
164 while (L->top < L->base + idx)
165 setnilvalue(L->top++);
166 L->top = L->base + idx;
167 }
168 else {
169 api_check(L, -(idx+1) <= (L->top - L->base));
170 L->top += idx+1; /* `subtract' index (index is negative) */
171 }
172 lua_unlock(L);
173}
174
175
176LUA_API void lua_remove (lua_State *L, int idx) {
177 StkId p;
178 lua_lock(L);
179 p = index2adr(L, idx);
180 api_checkvalidindex(L, p);
181 while (++p < L->top) setobjs2s(L, p-1, p);
182 L->top--;
183 lua_unlock(L);
184}
185
186
187LUA_API void lua_insert (lua_State *L, int idx) {
188 StkId p;
189 StkId q;
190 lua_lock(L);
191 p = index2adr(L, idx);
192 api_checkvalidindex(L, p);
193 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
194 setobjs2s(L, p, L->top);
195 lua_unlock(L);
196}
197
198
199LUA_API void lua_replace (lua_State *L, int idx) {
200 StkId o;
201 lua_lock(L);
202 /* explicit test for incompatible code */
203 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
204 luaG_runerror(L, "no calling environment");
205 api_checknelems(L, 1);
206 o = index2adr(L, idx);
207 api_checkvalidindex(L, o);
208 if (idx == LUA_ENVIRONINDEX) {
209 Closure *func = curr_func(L);
210 api_check(L, ttistable(L->top - 1));
211 func->c.env = hvalue(L->top - 1);
212 luaC_barrier(L, func, L->top - 1);
213 }
214 else {
215 setobj(L, o, L->top - 1);
216 if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
217 luaC_barrier(L, curr_func(L), L->top - 1);
218 }
219 L->top--;
220 lua_unlock(L);
221}
222
223
224LUA_API void lua_pushvalue (lua_State *L, int idx) {
225 lua_lock(L);
226 setobj2s(L, L->top, index2adr(L, idx));
227 api_incr_top(L);
228 lua_unlock(L);
229}
230
231
232
233/*
234** access functions (stack -> C)
235*/
236
237
238LUA_API int lua_type (lua_State *L, int idx) {
239 StkId o = index2adr(L, idx);
240 return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
241}
242
243
244LUA_API const char *lua_typename (lua_State *L, int t) {
245 UNUSED(L);
246 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
247}
248
249
250LUA_API int lua_iscfunction (lua_State *L, int idx) {
251 StkId o = index2adr(L, idx);
252 return iscfunction(o);
253}
254
255
256LUA_API int lua_isnumber (lua_State *L, int idx) {
257 TValue n;
258 const TValue *o = index2adr(L, idx);
259 return tonumber(o, &n);
260}
261
262
263LUA_API int lua_isstring (lua_State *L, int idx) {
264 int t = lua_type(L, idx);
265 return (t == LUA_TSTRING || t == LUA_TNUMBER);
266}
267
268
269LUA_API int lua_isuserdata (lua_State *L, int idx) {
270 const TValue *o = index2adr(L, idx);
271 return (ttisuserdata(o) || ttislightuserdata(o));
272}
273
274
275LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
276 StkId o1 = index2adr(L, index1);
277 StkId o2 = index2adr(L, index2);
278 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
279 : luaO_rawequalObj(o1, o2);
280}
281
282
283LUA_API int lua_equal (lua_State *L, int index1, int index2) {
284 StkId o1, o2;
285 int i;
286 lua_lock(L); /* may call tag method */
287 o1 = index2adr(L, index1);
288 o2 = index2adr(L, index2);
289 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
290 lua_unlock(L);
291 return i;
292}
293
294
295LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
296 StkId o1, o2;
297 int i;
298 lua_lock(L); /* may call tag method */
299 o1 = index2adr(L, index1);
300 o2 = index2adr(L, index2);
301 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
302 : luaV_lessthan(L, o1, o2);
303 lua_unlock(L);
304 return i;
305}
306
307
308
309LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
310 TValue n;
311 const TValue *o = index2adr(L, idx);
312 if (tonumber(o, &n))
313 return nvalue(o);
314 else
315 return 0;
316}
317
318
319LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
320 TValue n;
321 const TValue *o = index2adr(L, idx);
322 if (tonumber(o, &n)) {
323 lua_Integer res;
324 lua_Number num = nvalue(o);
325 lua_number2integer(res, num);
326 return res;
327 }
328 else
329 return 0;
330}
331
332
333LUA_API int lua_toboolean (lua_State *L, int idx) {
334 const TValue *o = index2adr(L, idx);
335 return !l_isfalse(o);
336}
337
338
339LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
340 StkId o = index2adr(L, idx);
341 if (!ttisstring(o)) {
342 lua_lock(L); /* `luaV_tostring' may create a new string */
343 if (!luaV_tostring(L, o)) { /* conversion failed? */
344 if (len != NULL) *len = 0;
345 lua_unlock(L);
346 return NULL;
347 }
348 luaC_checkGC(L);
349 o = index2adr(L, idx); /* previous call may reallocate the stack */
350 lua_unlock(L);
351 }
352 if (len != NULL) *len = tsvalue(o)->len;
353 return svalue(o);
354}
355
356
357LUA_API size_t lua_objlen (lua_State *L, int idx) {
358 StkId o = index2adr(L, idx);
359 switch (ttype(o)) {
360 case LUA_TSTRING: return tsvalue(o)->len;
361 case LUA_TUSERDATA: return uvalue(o)->len;
362 case LUA_TTABLE: return luaH_getn(hvalue(o));
363 case LUA_TNUMBER: {
364 size_t l;
365 lua_lock(L); /* `luaV_tostring' may create a new string */
366 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
367 lua_unlock(L);
368 return l;
369 }
370 default: return 0;
371 }
372}
373
374
375LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
376 StkId o = index2adr(L, idx);
377 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
378}
379
380
381LUA_API void *lua_touserdata (lua_State *L, int idx) {
382 StkId o = index2adr(L, idx);
383 switch (ttype(o)) {
384 case LUA_TUSERDATA: return (rawuvalue(o) + 1);
385 case LUA_TLIGHTUSERDATA: return pvalue(o);
386 default: return NULL;
387 }
388}
389
390
391LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
392 StkId o = index2adr(L, idx);
393 return (!ttisthread(o)) ? NULL : thvalue(o);
394}
395
396
397LUA_API const void *lua_topointer (lua_State *L, int idx) {
398 StkId o = index2adr(L, idx);
399 switch (ttype(o)) {
400 case LUA_TTABLE: return hvalue(o);
401 case LUA_TFUNCTION: return clvalue(o);
402 case LUA_TTHREAD: return thvalue(o);
403 case LUA_TUSERDATA:
404 case LUA_TLIGHTUSERDATA:
405 return lua_touserdata(L, idx);
406 default: return NULL;
407 }
408}
409
410
411
412/*
413** push functions (C -> stack)
414*/
415
416
417LUA_API void lua_pushnil (lua_State *L) {
418 lua_lock(L);
419 setnilvalue(L->top);
420 api_incr_top(L);
421 lua_unlock(L);
422}
423
424
425LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
426 lua_lock(L);
427 setnvalue(L->top, n);
428 api_incr_top(L);
429 lua_unlock(L);
430}
431
432
433LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
434 lua_lock(L);
435 setnvalue(L->top, cast_num(n));
436 api_incr_top(L);
437 lua_unlock(L);
438}
439
440
441LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
442 lua_lock(L);
443 luaC_checkGC(L);
444 setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
445 api_incr_top(L);
446 lua_unlock(L);
447}
448
449
450LUA_API void lua_pushstring (lua_State *L, const char *s) {
451 if (s == NULL)
452 lua_pushnil(L);
453 else
454 lua_pushlstring(L, s, strlen(s));
455}
456
457
458LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
459 va_list argp) {
460 const char *ret;
461 lua_lock(L);
462 luaC_checkGC(L);
463 ret = luaO_pushvfstring(L, fmt, argp);
464 lua_unlock(L);
465 return ret;
466}
467
468
469LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
470 const char *ret;
471 va_list argp;
472 lua_lock(L);
473 luaC_checkGC(L);
474 va_start(argp, fmt);
475 ret = luaO_pushvfstring(L, fmt, argp);
476 va_end(argp);
477 lua_unlock(L);
478 return ret;
479}
480
481
482LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
483 Closure *cl;
484 lua_lock(L);
485 luaC_checkGC(L);
486 api_checknelems(L, n);
487 cl = luaF_newCclosure(L, n, getcurrenv(L));
488 cl->c.f = fn;
489 L->top -= n;
490 while (n--)
491 setobj2n(L, &cl->c.upvalue[n], L->top+n);
492 setclvalue(L, L->top, cl);
493 lua_assert(iswhite(obj2gco(cl)));
494 api_incr_top(L);
495 lua_unlock(L);
496}
497
498
499LUA_API void lua_pushboolean (lua_State *L, int b) {
500 lua_lock(L);
501 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
502 api_incr_top(L);
503 lua_unlock(L);
504}
505
506
507LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
508 lua_lock(L);
509 setpvalue(L->top, p);
510 api_incr_top(L);
511 lua_unlock(L);
512}
513
514
515LUA_API int lua_pushthread (lua_State *L) {
516 lua_lock(L);
517 setthvalue(L, L->top, L);
518 api_incr_top(L);
519 lua_unlock(L);
520 return (G(L)->mainthread == L);
521}
522
523
524
525/*
526** get functions (Lua -> stack)
527*/
528
529
530LUA_API void lua_gettable (lua_State *L, int idx) {
531 StkId t;
532 lua_lock(L);
533 t = index2adr(L, idx);
534 api_checkvalidindex(L, t);
535 luaV_gettable(L, t, L->top - 1, L->top - 1);
536 lua_unlock(L);
537}
538
539
540LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
541 StkId t;
542 TValue key;
543 lua_lock(L);
544 t = index2adr(L, idx);
545 api_checkvalidindex(L, t);
546 setsvalue(L, &key, luaS_new(L, k));
547 luaV_gettable(L, t, &key, L->top);
548 api_incr_top(L);
549 lua_unlock(L);
550}
551
552
553LUA_API void lua_rawget (lua_State *L, int idx) {
554 StkId t;
555 lua_lock(L);
556 t = index2adr(L, idx);
557 api_check(L, ttistable(t));
558 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
559 lua_unlock(L);
560}
561
562
563LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
564 StkId o;
565 lua_lock(L);
566 o = index2adr(L, idx);
567 api_check(L, ttistable(o));
568 setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
569 api_incr_top(L);
570 lua_unlock(L);
571}
572
573
574LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
575 lua_lock(L);
576 luaC_checkGC(L);
577 sethvalue(L, L->top, luaH_new(L, narray, nrec));
578 api_incr_top(L);
579 lua_unlock(L);
580}
581
582
583LUA_API int lua_getmetatable (lua_State *L, int objindex) {
584 const TValue *obj;
585 Table *mt = NULL;
586 int res;
587 lua_lock(L);
588 obj = index2adr(L, objindex);
589 switch (ttype(obj)) {
590 case LUA_TTABLE:
591 mt = hvalue(obj)->metatable;
592 break;
593 case LUA_TUSERDATA:
594 mt = uvalue(obj)->metatable;
595 break;
596 default:
597 mt = G(L)->mt[ttype(obj)];
598 break;
599 }
600 if (mt == NULL)
601 res = 0;
602 else {
603 sethvalue(L, L->top, mt);
604 api_incr_top(L);
605 res = 1;
606 }
607 lua_unlock(L);
608 return res;
609}
610
611
612LUA_API void lua_getfenv (lua_State *L, int idx) {
613 StkId o;
614 lua_lock(L);
615 o = index2adr(L, idx);
616 api_checkvalidindex(L, o);
617 switch (ttype(o)) {
618 case LUA_TFUNCTION:
619 sethvalue(L, L->top, clvalue(o)->c.env);
620 break;
621 case LUA_TUSERDATA:
622 sethvalue(L, L->top, uvalue(o)->env);
623 break;
624 case LUA_TTHREAD:
625 setobj2s(L, L->top, gt(thvalue(o)));
626 break;
627 default:
628 setnilvalue(L->top);
629 break;
630 }
631 api_incr_top(L);
632 lua_unlock(L);
633}
634
635
636/*
637** set functions (stack -> Lua)
638*/
639
640
641LUA_API void lua_settable (lua_State *L, int idx) {
642 StkId t;
643 lua_lock(L);
644 api_checknelems(L, 2);
645 t = index2adr(L, idx);
646 api_checkvalidindex(L, t);
647 luaV_settable(L, t, L->top - 2, L->top - 1);
648 L->top -= 2; /* pop index and value */
649 lua_unlock(L);
650}
651
652
653LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
654 StkId t;
655 TValue key;
656 lua_lock(L);
657 api_checknelems(L, 1);
658 t = index2adr(L, idx);
659 api_checkvalidindex(L, t);
660 setsvalue(L, &key, luaS_new(L, k));
661 luaV_settable(L, t, &key, L->top - 1);
662 L->top--; /* pop value */
663 lua_unlock(L);
664}
665
666
667LUA_API void lua_rawset (lua_State *L, int idx) {
668 StkId t;
669 lua_lock(L);
670 api_checknelems(L, 2);
671 t = index2adr(L, idx);
672 api_check(L, ttistable(t));
673 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
674 luaC_barriert(L, hvalue(t), L->top-1);
675 L->top -= 2;
676 lua_unlock(L);
677}
678
679
680LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
681 StkId o;
682 lua_lock(L);
683 api_checknelems(L, 1);
684 o = index2adr(L, idx);
685 api_check(L, ttistable(o));
686 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
687 luaC_barriert(L, hvalue(o), L->top-1);
688 L->top--;
689 lua_unlock(L);
690}
691
692
693LUA_API int lua_setmetatable (lua_State *L, int objindex) {
694 TValue *obj;
695 Table *mt;
696 lua_lock(L);
697 api_checknelems(L, 1);
698 obj = index2adr(L, objindex);
699 api_checkvalidindex(L, obj);
700 if (ttisnil(L->top - 1))
701 mt = NULL;
702 else {
703 api_check(L, ttistable(L->top - 1));
704 mt = hvalue(L->top - 1);
705 }
706 switch (ttype(obj)) {
707 case LUA_TTABLE: {
708 hvalue(obj)->metatable = mt;
709 if (mt)
710 luaC_objbarriert(L, hvalue(obj), mt);
711 break;
712 }
713 case LUA_TUSERDATA: {
714 uvalue(obj)->metatable = mt;
715 if (mt)
716 luaC_objbarrier(L, rawuvalue(obj), mt);
717 break;
718 }
719 default: {
720 G(L)->mt[ttype(obj)] = mt;
721 break;
722 }
723 }
724 L->top--;
725 lua_unlock(L);
726 return 1;
727}
728
729
730LUA_API int lua_setfenv (lua_State *L, int idx) {
731 StkId o;
732 int res = 1;
733 lua_lock(L);
734 api_checknelems(L, 1);
735 o = index2adr(L, idx);
736 api_checkvalidindex(L, o);
737 api_check(L, ttistable(L->top - 1));
738 switch (ttype(o)) {
739 case LUA_TFUNCTION:
740 clvalue(o)->c.env = hvalue(L->top - 1);
741 break;
742 case LUA_TUSERDATA:
743 uvalue(o)->env = hvalue(L->top - 1);
744 break;
745 case LUA_TTHREAD:
746 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
747 break;
748 default:
749 res = 0;
750 break;
751 }
752 luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
753 L->top--;
754 lua_unlock(L);
755 return res;
756}
757
758
759/*
760** `load' and `call' functions (run Lua code)
761*/
762
763
764#define adjustresults(L,nres) \
765 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
766
767
768#define checkresults(L,na,nr) \
769 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
770
771
772LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
773 StkId func;
774 lua_lock(L);
775 api_checknelems(L, nargs+1);
776 checkresults(L, nargs, nresults);
777 func = L->top - (nargs+1);
778 luaD_call(L, func, nresults);
779 adjustresults(L, nresults);
780 lua_unlock(L);
781}
782
783
784
785/*
786** Execute a protected call.
787*/
788struct CallS { /* data to `f_call' */
789 StkId func;
790 int nresults;
791};
792
793
794static void f_call (lua_State *L, void *ud) {
795 struct CallS *c = cast(struct CallS *, ud);
796 luaD_call(L, c->func, c->nresults);
797}
798
799
800
801LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
802 struct CallS c;
803 int status;
804 ptrdiff_t func;
805 lua_lock(L);
806 api_checknelems(L, nargs+1);
807 checkresults(L, nargs, nresults);
808 if (errfunc == 0)
809 func = 0;
810 else {
811 StkId o = index2adr(L, errfunc);
812 api_checkvalidindex(L, o);
813 func = savestack(L, o);
814 }
815 c.func = L->top - (nargs+1); /* function to be called */
816 c.nresults = nresults;
817 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
818 adjustresults(L, nresults);
819 lua_unlock(L);
820 return status;
821}
822
823
824/*
825** Execute a protected C call.
826*/
827struct CCallS { /* data to `f_Ccall' */
828 lua_CFunction func;
829 void *ud;
830};
831
832
833static void f_Ccall (lua_State *L, void *ud) {
834 struct CCallS *c = cast(struct CCallS *, ud);
835 Closure *cl;
836 cl = luaF_newCclosure(L, 0, getcurrenv(L));
837 cl->c.f = c->func;
838 setclvalue(L, L->top, cl); /* push function */
839 api_incr_top(L);
840 setpvalue(L->top, c->ud); /* push only argument */
841 api_incr_top(L);
842 luaD_call(L, L->top - 2, 0);
843}
844
845
846LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
847 struct CCallS c;
848 int status;
849 lua_lock(L);
850 c.func = func;
851 c.ud = ud;
852 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
853 lua_unlock(L);
854 return status;
855}
856
857
858LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
859 const char *chunkname) {
860 ZIO z;
861 int status;
862 lua_lock(L);
863 if (!chunkname) chunkname = "?";
864 luaZ_init(L, &z, reader, data);
865 status = luaD_protectedparser(L, &z, chunkname);
866 lua_unlock(L);
867 return status;
868}
869
870
871LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
872 int status;
873 TValue *o;
874 lua_lock(L);
875 api_checknelems(L, 1);
876 o = L->top - 1;
877 if (isLfunction(o))
878 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
879 else
880 status = 1;
881 lua_unlock(L);
882 return status;
883}
884
885
886LUA_API int lua_status (lua_State *L) {
887 return L->status;
888}
889
890
891/*
892** Garbage-collection function
893*/
894
895LUA_API int lua_gc (lua_State *L, int what, int data) {
896 int res = 0;
897 global_State *g;
898 lua_lock(L);
899 g = G(L);
900 switch (what) {
901 case LUA_GCSTOP: {
902 g->GCthreshold = MAX_LUMEM;
903 break;
904 }
905 case LUA_GCRESTART: {
906 g->GCthreshold = g->totalbytes;
907 break;
908 }
909 case LUA_GCCOLLECT: {
910 luaC_fullgc(L);
911 break;
912 }
913 case LUA_GCCOUNT: {
914 /* GC values are expressed in Kbytes: #bytes/2^10 */
915 res = cast_int(g->totalbytes >> 10);
916 break;
917 }
918 case LUA_GCCOUNTB: {
919 res = cast_int(g->totalbytes & 0x3ff);
920 break;
921 }
922 case LUA_GCSTEP: {
923 lu_mem a = (cast(lu_mem, data) << 10);
924 if (a <= g->totalbytes)
925 g->GCthreshold = g->totalbytes - a;
926 else
927 g->GCthreshold = 0;
928 while (g->GCthreshold <= g->totalbytes)
929 luaC_step(L);
930 if (g->gcstate == GCSpause) /* end of cycle? */
931 res = 1; /* signal it */
932 break;
933 }
934 case LUA_GCSETPAUSE: {
935 res = g->gcpause;
936 g->gcpause = data;
937 break;
938 }
939 case LUA_GCSETSTEPMUL: {
940 res = g->gcstepmul;
941 g->gcstepmul = data;
942 break;
943 }
944 default: res = -1; /* invalid option */
945 }
946 lua_unlock(L);
947 return res;
948}
949
950
951
952/*
953** miscellaneous functions
954*/
955
956
957LUA_API int lua_error (lua_State *L) {
958 lua_lock(L);
959 api_checknelems(L, 1);
960 luaG_errormsg(L);
961 lua_unlock(L);
962 return 0; /* to avoid warnings */
963}
964
965
966LUA_API int lua_next (lua_State *L, int idx) {
967 StkId t;
968 int more;
969 lua_lock(L);
970 t = index2adr(L, idx);
971 api_check(L, ttistable(t));
972 more = luaH_next(L, hvalue(t), L->top - 1);
973 if (more) {
974 api_incr_top(L);
975 }
976 else /* no more elements */
977 L->top -= 1; /* remove key */
978 lua_unlock(L);
979 return more;
980}
981
982
983LUA_API void lua_concat (lua_State *L, int n) {
984 lua_lock(L);
985 api_checknelems(L, n);
986 if (n >= 2) {
987 luaC_checkGC(L);
988 luaV_concat(L, n, cast_int(L->top - L->base) - 1);
989 L->top -= (n-1);
990 }
991 else if (n == 0) { /* push empty string */
992 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
993 api_incr_top(L);
994 }
995 /* else n == 1; nothing to do */
996 lua_unlock(L);
997}
998
999
1000LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1001 lua_Alloc f;
1002 lua_lock(L);
1003 if (ud) *ud = G(L)->ud;
1004 f = G(L)->frealloc;
1005 lua_unlock(L);
1006 return f;
1007}
1008
1009
1010LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1011 lua_lock(L);
1012 G(L)->ud = ud;
1013 G(L)->frealloc = f;
1014 lua_unlock(L);
1015}
1016
1017
1018LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1019 Udata *u;
1020 lua_lock(L);
1021 luaC_checkGC(L);
1022 u = luaS_newudata(L, size, getcurrenv(L));
1023 setuvalue(L, L->top, u);
1024 api_incr_top(L);
1025 lua_unlock(L);
1026 return u + 1;
1027}
1028
1029
1030
1031
1032static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1033 Closure *f;
1034 if (!ttisfunction(fi)) return NULL;
1035 f = clvalue(fi);
1036 if (f->c.isC) {
1037 if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1038 *val = &f->c.upvalue[n-1];
1039 return "";
1040 }
1041 else {
1042 Proto *p = f->l.p;
1043 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1044 *val = f->l.upvals[n-1]->v;
1045 return getstr(p->upvalues[n-1]);
1046 }
1047}
1048
1049
1050LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1051 const char *name;
1052 TValue *val;
1053 lua_lock(L);
1054 name = aux_upvalue(index2adr(L, funcindex), n, &val);
1055 if (name) {
1056 setobj2s(L, L->top, val);
1057 api_incr_top(L);
1058 }
1059 lua_unlock(L);
1060 return name;
1061}
1062
1063
1064LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1065 const char *name;
1066 TValue *val;
1067 StkId fi;
1068 lua_lock(L);
1069 fi = index2adr(L, funcindex);
1070 api_checknelems(L, 1);
1071 name = aux_upvalue(fi, n, &val);
1072 if (name) {
1073 L->top--;
1074 setobj(L, val, L->top);
1075 luaC_barrier(L, clvalue(fi), L->top);
1076 }
1077 lua_unlock(L);
1078 return name;
1079}
1080
diff --git a/lapi.h b/lapi.h
deleted file mode 100644
index bb522de5..00000000
--- a/lapi.h
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2** $Id: lapi.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lapi_h
8#define lapi_h
9
10
11#include "lobject.h"
12
13
14LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
15
16#endif
diff --git a/lauxlib.c b/lauxlib.c
deleted file mode 100644
index 402dcd80..00000000
--- a/lauxlib.c
+++ /dev/null
@@ -1,653 +0,0 @@
1/*
2** $Id: lauxlib.c,v 1.158 2006/01/16 12:42:21 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <errno.h>
10#include <stdarg.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15
16/* This file uses only the official API of Lua.
17** Any function declared here could be written as an application function.
18*/
19
20#define lauxlib_c
21#define LUA_LIB
22
23#include "lua.h"
24
25#include "lauxlib.h"
26
27
28#define FREELIST_REF 0 /* free list of references */
29
30
31/* convert a stack index to positive */
32#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
33 lua_gettop(L) + (i) + 1)
34
35
36/*
37** {======================================================
38** Error-report functions
39** =======================================================
40*/
41
42
43LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
44 lua_Debug ar;
45 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
46 return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
47 lua_getinfo(L, "n", &ar);
48 if (strcmp(ar.namewhat, "method") == 0) {
49 narg--; /* do not count `self' */
50 if (narg == 0) /* error is in the self argument itself? */
51 return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
52 ar.name, extramsg);
53 }
54 if (ar.name == NULL)
55 ar.name = "?";
56 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
57 narg, ar.name, extramsg);
58}
59
60
61LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
62 const char *msg = lua_pushfstring(L, "%s expected, got %s",
63 tname, luaL_typename(L, narg));
64 return luaL_argerror(L, narg, msg);
65}
66
67
68static void tag_error (lua_State *L, int narg, int tag) {
69 luaL_typerror(L, narg, lua_typename(L, tag));
70}
71
72
73LUALIB_API void luaL_where (lua_State *L, int level) {
74 lua_Debug ar;
75 if (lua_getstack(L, level, &ar)) { /* check function at level */
76 lua_getinfo(L, "Sl", &ar); /* get info about it */
77 if (ar.currentline > 0) { /* is there info? */
78 lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
79 return;
80 }
81 }
82 lua_pushliteral(L, ""); /* else, no information available... */
83}
84
85
86LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
87 va_list argp;
88 va_start(argp, fmt);
89 luaL_where(L, 1);
90 lua_pushvfstring(L, fmt, argp);
91 va_end(argp);
92 lua_concat(L, 2);
93 return lua_error(L);
94}
95
96/* }====================================================== */
97
98
99LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
100 const char *const lst[]) {
101 const char *name = (def) ? luaL_optstring(L, narg, def) :
102 luaL_checkstring(L, narg);
103 int i;
104 for (i=0; lst[i]; i++)
105 if (strcmp(lst[i], name) == 0)
106 return i;
107 return luaL_argerror(L, narg,
108 lua_pushfstring(L, "invalid option " LUA_QS, name));
109}
110
111
112LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
113 lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
114 if (!lua_isnil(L, -1)) /* name already in use? */
115 return 0; /* leave previous value on top, but return 0 */
116 lua_pop(L, 1);
117 lua_newtable(L); /* create metatable */
118 lua_pushvalue(L, -1);
119 lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
120 return 1;
121}
122
123
124LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
125 void *p = lua_touserdata(L, ud);
126 if (p != NULL) { /* value is a userdata? */
127 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
128 lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
129 if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
130 lua_pop(L, 2); /* remove both metatables */
131 return p;
132 }
133 }
134 }
135 luaL_typerror(L, ud, tname); /* else error */
136 return NULL; /* to avoid warnings */
137}
138
139
140LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
141 if (!lua_checkstack(L, space))
142 luaL_error(L, "stack overflow (%s)", mes);
143}
144
145
146LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
147 if (lua_type(L, narg) != t)
148 tag_error(L, narg, t);
149}
150
151
152LUALIB_API void luaL_checkany (lua_State *L, int narg) {
153 if (lua_type(L, narg) == LUA_TNONE)
154 luaL_argerror(L, narg, "value expected");
155}
156
157
158LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
159 const char *s = lua_tolstring(L, narg, len);
160 if (!s) tag_error(L, narg, LUA_TSTRING);
161 return s;
162}
163
164
165LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
166 const char *def, size_t *len) {
167 if (lua_isnoneornil(L, narg)) {
168 if (len)
169 *len = (def ? strlen(def) : 0);
170 return def;
171 }
172 else return luaL_checklstring(L, narg, len);
173}
174
175
176LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
177 lua_Number d = lua_tonumber(L, narg);
178 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
179 tag_error(L, narg, LUA_TNUMBER);
180 return d;
181}
182
183
184LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
185 return luaL_opt(L, luaL_checknumber, narg, def);
186}
187
188
189LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
190 lua_Integer d = lua_tointeger(L, narg);
191 if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
192 tag_error(L, narg, LUA_TNUMBER);
193 return d;
194}
195
196
197LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
198 lua_Integer def) {
199 return luaL_opt(L, luaL_checkinteger, narg, def);
200}
201
202
203LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
204 if (!lua_getmetatable(L, obj)) /* no metatable? */
205 return 0;
206 lua_pushstring(L, event);
207 lua_rawget(L, -2);
208 if (lua_isnil(L, -1)) {
209 lua_pop(L, 2); /* remove metatable and metafield */
210 return 0;
211 }
212 else {
213 lua_remove(L, -2); /* remove only metatable */
214 return 1;
215 }
216}
217
218
219LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
220 obj = abs_index(L, obj);
221 if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
222 return 0;
223 lua_pushvalue(L, obj);
224 lua_call(L, 1, 1);
225 return 1;
226}
227
228
229LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
230 const luaL_Reg *l) {
231 luaI_openlib(L, libname, l, 0);
232}
233
234
235static int libsize (const luaL_Reg *l) {
236 int size = 0;
237 for (; l->name; l++) size++;
238 return size;
239}
240
241
242LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
243 const luaL_Reg *l, int nup) {
244 if (libname) {
245 int size = libsize(l);
246 /* check whether lib already exists */
247 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", size);
248 lua_getfield(L, -1, libname); /* get _LOADED[libname] */
249 if (!lua_istable(L, -1)) { /* not found? */
250 lua_pop(L, 1); /* remove previous result */
251 /* try global variable (and create one if it does not exist) */
252 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
253 luaL_error(L, "name conflict for module " LUA_QS, libname);
254 lua_pushvalue(L, -1);
255 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
256 }
257 lua_remove(L, -2); /* remove _LOADED table */
258 lua_insert(L, -(nup+1)); /* move library table to below upvalues */
259 }
260 for (; l->name; l++) {
261 int i;
262 for (i=0; i<nup; i++) /* copy upvalues to the top */
263 lua_pushvalue(L, -nup);
264 lua_pushcclosure(L, l->func, nup);
265 lua_setfield(L, -(nup+2), l->name);
266 }
267 lua_pop(L, nup); /* remove upvalues */
268}
269
270
271
272/*
273** {======================================================
274** getn-setn: size for arrays
275** =======================================================
276*/
277
278#if defined(LUA_COMPAT_GETN)
279
280static int checkint (lua_State *L, int topop) {
281 int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
282 lua_pop(L, topop);
283 return n;
284}
285
286
287static void getsizes (lua_State *L) {
288 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
289 if (lua_isnil(L, -1)) { /* no `size' table? */
290 lua_pop(L, 1); /* remove nil */
291 lua_newtable(L); /* create it */
292 lua_pushvalue(L, -1); /* `size' will be its own metatable */
293 lua_setmetatable(L, -2);
294 lua_pushliteral(L, "kv");
295 lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
296 lua_pushvalue(L, -1);
297 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
298 }
299}
300
301
302LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
303 t = abs_index(L, t);
304 lua_pushliteral(L, "n");
305 lua_rawget(L, t);
306 if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
307 lua_pushliteral(L, "n"); /* use it */
308 lua_pushinteger(L, n);
309 lua_rawset(L, t);
310 }
311 else { /* use `sizes' */
312 getsizes(L);
313 lua_pushvalue(L, t);
314 lua_pushinteger(L, n);
315 lua_rawset(L, -3); /* sizes[t] = n */
316 lua_pop(L, 1); /* remove `sizes' */
317 }
318}
319
320
321LUALIB_API int luaL_getn (lua_State *L, int t) {
322 int n;
323 t = abs_index(L, t);
324 lua_pushliteral(L, "n"); /* try t.n */
325 lua_rawget(L, t);
326 if ((n = checkint(L, 1)) >= 0) return n;
327 getsizes(L); /* else try sizes[t] */
328 lua_pushvalue(L, t);
329 lua_rawget(L, -2);
330 if ((n = checkint(L, 2)) >= 0) return n;
331 return (int)lua_objlen(L, t);
332}
333
334#endif
335
336/* }====================================================== */
337
338
339
340LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
341 const char *r) {
342 const char *wild;
343 size_t l = strlen(p);
344 luaL_Buffer b;
345 luaL_buffinit(L, &b);
346 while ((wild = strstr(s, p)) != NULL) {
347 luaL_addlstring(&b, s, wild - s); /* push prefix */
348 luaL_addstring(&b, r); /* push replacement in place of pattern */
349 s = wild + l; /* continue after `p' */
350 }
351 luaL_addstring(&b, s); /* push last suffix */
352 luaL_pushresult(&b);
353 return lua_tostring(L, -1);
354}
355
356
357LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
358 const char *fname, int szhint) {
359 const char *e;
360 lua_pushvalue(L, idx);
361 do {
362 e = strchr(fname, '.');
363 if (e == NULL) e = fname + strlen(fname);
364 lua_pushlstring(L, fname, e - fname);
365 lua_rawget(L, -2);
366 if (lua_isnil(L, -1)) { /* no such field? */
367 lua_pop(L, 1); /* remove this nil */
368 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
369 lua_pushlstring(L, fname, e - fname);
370 lua_pushvalue(L, -2);
371 lua_settable(L, -4); /* set new table into field */
372 }
373 else if (!lua_istable(L, -1)) { /* field has a non-table value? */
374 lua_pop(L, 2); /* remove table and value */
375 return fname; /* return problematic part of the name */
376 }
377 lua_remove(L, -2); /* remove previous table */
378 fname = e + 1;
379 } while (*e == '.');
380 return NULL;
381}
382
383
384
385/*
386** {======================================================
387** Generic Buffer manipulation
388** =======================================================
389*/
390
391
392#define bufflen(B) ((B)->p - (B)->buffer)
393#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
394
395#define LIMIT (LUA_MINSTACK/2)
396
397
398static int emptybuffer (luaL_Buffer *B) {
399 size_t l = bufflen(B);
400 if (l == 0) return 0; /* put nothing on stack */
401 else {
402 lua_pushlstring(B->L, B->buffer, l);
403 B->p = B->buffer;
404 B->lvl++;
405 return 1;
406 }
407}
408
409
410static void adjuststack (luaL_Buffer *B) {
411 if (B->lvl > 1) {
412 lua_State *L = B->L;
413 int toget = 1; /* number of levels to concat */
414 size_t toplen = lua_strlen(L, -1);
415 do {
416 size_t l = lua_strlen(L, -(toget+1));
417 if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
418 toplen += l;
419 toget++;
420 }
421 else break;
422 } while (toget < B->lvl);
423 lua_concat(L, toget);
424 B->lvl = B->lvl - toget + 1;
425 }
426}
427
428
429LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
430 if (emptybuffer(B))
431 adjuststack(B);
432 return B->buffer;
433}
434
435
436LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
437 while (l--)
438 luaL_addchar(B, *s++);
439}
440
441
442LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
443 luaL_addlstring(B, s, strlen(s));
444}
445
446
447LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
448 emptybuffer(B);
449 lua_concat(B->L, B->lvl);
450 B->lvl = 1;
451}
452
453
454LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
455 lua_State *L = B->L;
456 size_t vl;
457 const char *s = lua_tolstring(L, -1, &vl);
458 if (vl <= bufffree(B)) { /* fit into buffer? */
459 memcpy(B->p, s, vl); /* put it there */
460 B->p += vl;
461 lua_pop(L, 1); /* remove from stack */
462 }
463 else {
464 if (emptybuffer(B))
465 lua_insert(L, -2); /* put buffer before new value */
466 B->lvl++; /* add new value into B stack */
467 adjuststack(B);
468 }
469}
470
471
472LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
473 B->L = L;
474 B->p = B->buffer;
475 B->lvl = 0;
476}
477
478/* }====================================================== */
479
480
481LUALIB_API int luaL_ref (lua_State *L, int t) {
482 int ref;
483 t = abs_index(L, t);
484 if (lua_isnil(L, -1)) {
485 lua_pop(L, 1); /* remove from stack */
486 return LUA_REFNIL; /* `nil' has a unique fixed reference */
487 }
488 lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
489 ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
490 lua_pop(L, 1); /* remove it from stack */
491 if (ref != 0) { /* any free element? */
492 lua_rawgeti(L, t, ref); /* remove it from list */
493 lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
494 }
495 else { /* no free elements */
496 ref = (int)lua_objlen(L, t);
497 ref++; /* create new reference */
498 }
499 lua_rawseti(L, t, ref);
500 return ref;
501}
502
503
504LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
505 if (ref >= 0) {
506 t = abs_index(L, t);
507 lua_rawgeti(L, t, FREELIST_REF);
508 lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
509 lua_pushinteger(L, ref);
510 lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
511 }
512}
513
514
515
516/*
517** {======================================================
518** Load functions
519** =======================================================
520*/
521
522typedef struct LoadF {
523 int extraline;
524 FILE *f;
525 char buff[LUAL_BUFFERSIZE];
526} LoadF;
527
528
529static const char *getF (lua_State *L, void *ud, size_t *size) {
530 LoadF *lf = (LoadF *)ud;
531 (void)L;
532 if (lf->extraline) {
533 lf->extraline = 0;
534 *size = 1;
535 return "\n";
536 }
537 if (feof(lf->f)) return NULL;
538 *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f);
539 return (*size > 0) ? lf->buff : NULL;
540}
541
542
543static int errfile (lua_State *L, const char *what, int fnameindex) {
544 const char *serr = strerror(errno);
545 const char *filename = lua_tostring(L, fnameindex) + 1;
546 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
547 lua_remove(L, fnameindex);
548 return LUA_ERRFILE;
549}
550
551
552LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
553 LoadF lf;
554 int status, readstatus;
555 int c;
556 int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
557 lf.extraline = 0;
558 if (filename == NULL) {
559 lua_pushliteral(L, "=stdin");
560 lf.f = stdin;
561 }
562 else {
563 lua_pushfstring(L, "@%s", filename);
564 lf.f = fopen(filename, "r");
565 if (lf.f == NULL) return errfile(L, "open", fnameindex);
566 }
567 c = getc(lf.f);
568 if (c == '#') { /* Unix exec. file? */
569 lf.extraline = 1;
570 while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
571 if (c == '\n') c = getc(lf.f);
572 }
573 if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */
574 fclose(lf.f);
575 lf.f = fopen(filename, "rb"); /* reopen in binary mode */
576 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
577 /* skip eventual `#!...' */
578 while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
579 lf.extraline = 0;
580 }
581 ungetc(c, lf.f);
582 status = lua_load(L, getF, &lf, lua_tostring(L, -1));
583 readstatus = ferror(lf.f);
584 if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
585 if (readstatus) {
586 lua_settop(L, fnameindex); /* ignore results from `lua_load' */
587 return errfile(L, "read", fnameindex);
588 }
589 lua_remove(L, fnameindex);
590 return status;
591}
592
593
594typedef struct LoadS {
595 const char *s;
596 size_t size;
597} LoadS;
598
599
600static const char *getS (lua_State *L, void *ud, size_t *size) {
601 LoadS *ls = (LoadS *)ud;
602 (void)L;
603 if (ls->size == 0) return NULL;
604 *size = ls->size;
605 ls->size = 0;
606 return ls->s;
607}
608
609
610LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
611 const char *name) {
612 LoadS ls;
613 ls.s = buff;
614 ls.size = size;
615 return lua_load(L, getS, &ls, name);
616}
617
618
619LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
620 return luaL_loadbuffer(L, s, strlen(s), s);
621}
622
623
624
625/* }====================================================== */
626
627
628static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
629 (void)ud;
630 (void)osize;
631 if (nsize == 0) {
632 free(ptr);
633 return NULL;
634 }
635 else
636 return realloc(ptr, nsize);
637}
638
639
640static int panic (lua_State *L) {
641 (void)L; /* to avoid warnings */
642 fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
643 lua_tostring(L, -1));
644 return 0;
645}
646
647
648LUALIB_API lua_State *luaL_newstate (void) {
649 lua_State *L = lua_newstate(l_alloc, NULL);
650 if (L) lua_atpanic(L, &panic);
651 return L;
652}
653
diff --git a/lauxlib.h b/lauxlib.h
deleted file mode 100644
index f7b02db5..00000000
--- a/lauxlib.h
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2** $Id: lauxlib.h,v 1.87 2005/12/29 15:32:11 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lauxlib_h
9#define lauxlib_h
10
11
12#include <stddef.h>
13#include <stdio.h>
14
15#include "lua.h"
16
17
18#if defined(LUA_COMPAT_GETN)
19LUALIB_API int (luaL_getn) (lua_State *L, int t);
20LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
21#else
22#define luaL_getn(L,i) ((int)lua_objlen(L, i))
23#define luaL_setn(L,i,j) ((void)0) /* no op! */
24#endif
25
26#if defined(LUA_COMPAT_OPENLIB)
27#define luaI_openlib luaL_openlib
28#endif
29
30
31/* extra error code for `luaL_load' */
32#define LUA_ERRFILE (LUA_ERRERR+1)
33
34
35typedef struct luaL_Reg {
36 const char *name;
37 lua_CFunction func;
38} luaL_Reg;
39
40
41
42LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
43 const luaL_Reg *l, int nup);
44LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
45 const luaL_Reg *l);
46LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
47LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
48LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
49LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
50LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
51 size_t *l);
52LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
53 const char *def, size_t *l);
54LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
55LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
56
57LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
58LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
59 lua_Integer def);
60
61LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
62LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
63LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
64
65LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
66LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
67
68LUALIB_API void (luaL_where) (lua_State *L, int lvl);
69LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
70
71LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
72 const char *const lst[]);
73
74LUALIB_API int (luaL_ref) (lua_State *L, int t);
75LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
76
77LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
78LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
79 const char *name);
80LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
81
82LUALIB_API lua_State *(luaL_newstate) (void);
83
84
85LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
86 const char *r);
87
88LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
89 const char *fname, int szhint);
90
91
92
93
94/*
95** ===============================================================
96** some useful macros
97** ===============================================================
98*/
99
100#define luaL_argcheck(L, cond,numarg,extramsg) \
101 ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
102#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
103#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
104#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
105#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
106#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
107#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
108
109#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
110
111#define luaL_dofile(L, fn) \
112 (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
113
114#define luaL_dostring(L, s) \
115 (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
116
117#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
118
119#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
120
121/*
122** {======================================================
123** Generic Buffer manipulation
124** =======================================================
125*/
126
127
128
129typedef struct luaL_Buffer {
130 char *p; /* current position in buffer */
131 int lvl; /* number of strings in the stack (level) */
132 lua_State *L;
133 char buffer[LUAL_BUFFERSIZE];
134} luaL_Buffer;
135
136#define luaL_addchar(B,c) \
137 ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
138 (*(B)->p++ = (char)(c)))
139
140/* compatibility only */
141#define luaL_putchar(B,c) luaL_addchar(B,c)
142
143#define luaL_addsize(B,n) ((B)->p += (n))
144
145LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
146LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
147LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
148LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
149LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
150LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
151
152
153/* }====================================================== */
154
155
156/* compatibility with ref system */
157
158/* pre-defined references */
159#define LUA_NOREF (-2)
160#define LUA_REFNIL (-1)
161
162#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
163 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
164
165#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
166
167#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
168
169
170#define luaL_reg luaL_Reg
171
172#endif
173
174
diff --git a/lbaselib.c b/lbaselib.c
deleted file mode 100644
index 4bd6a1f9..00000000
--- a/lbaselib.c
+++ /dev/null
@@ -1,643 +0,0 @@
1/*
2** $Id: lbaselib.c,v 1.190 2006/05/31 16:50:40 roberto Exp roberto $
3** Basic library
4** See Copyright Notice in lua.h
5*/
6
7
8
9#include <ctype.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lbaselib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23
24
25/*
26** If your system does not support `stdout', you can just remove this function.
27** If you need, you can define your own `print' function, following this
28** model but changing `fputs' to put the strings at a proper place
29** (a console window or a log file, for instance).
30*/
31static int luaB_print (lua_State *L) {
32 int n = lua_gettop(L); /* number of arguments */
33 int i;
34 lua_getglobal(L, "tostring");
35 for (i=1; i<=n; i++) {
36 const char *s;
37 lua_pushvalue(L, -1); /* function to be called */
38 lua_pushvalue(L, i); /* value to print */
39 lua_call(L, 1, 1);
40 s = lua_tostring(L, -1); /* get result */
41 if (s == NULL)
42 return luaL_error(L, LUA_QL("tostring") " must return a string to "
43 LUA_QL("print"));
44 if (i>1) fputs("\t", stdout);
45 fputs(s, stdout);
46 lua_pop(L, 1); /* pop result */
47 }
48 fputs("\n", stdout);
49 return 0;
50}
51
52
53static int luaB_tonumber (lua_State *L) {
54 int base = luaL_optint(L, 2, 10);
55 if (base == 10) { /* standard conversion */
56 luaL_checkany(L, 1);
57 if (lua_isnumber(L, 1)) {
58 lua_pushnumber(L, lua_tonumber(L, 1));
59 return 1;
60 }
61 }
62 else {
63 const char *s1 = luaL_checkstring(L, 1);
64 char *s2;
65 unsigned long n;
66 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
67 n = strtoul(s1, &s2, base);
68 if (s1 != s2) { /* at least one valid digit? */
69 while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
70 if (*s2 == '\0') { /* no invalid trailing characters? */
71 lua_pushnumber(L, (lua_Number)n);
72 return 1;
73 }
74 }
75 }
76 lua_pushnil(L); /* else not a number */
77 return 1;
78}
79
80
81static int luaB_error (lua_State *L) {
82 int level = luaL_optint(L, 2, 1);
83 lua_settop(L, 1);
84 if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
85 luaL_where(L, level);
86 lua_pushvalue(L, 1);
87 lua_concat(L, 2);
88 }
89 return lua_error(L);
90}
91
92
93static int luaB_getmetatable (lua_State *L) {
94 luaL_checkany(L, 1);
95 if (!lua_getmetatable(L, 1)) {
96 lua_pushnil(L);
97 return 1; /* no metatable */
98 }
99 luaL_getmetafield(L, 1, "__metatable");
100 return 1; /* returns either __metatable field (if present) or metatable */
101}
102
103
104static int luaB_setmetatable (lua_State *L) {
105 int t = lua_type(L, 2);
106 luaL_checktype(L, 1, LUA_TTABLE);
107 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
108 "nil or table expected");
109 if (luaL_getmetafield(L, 1, "__metatable"))
110 luaL_error(L, "cannot change a protected metatable");
111 lua_settop(L, 2);
112 lua_setmetatable(L, 1);
113 return 1;
114}
115
116
117static void getfunc (lua_State *L) {
118 if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
119 else {
120 lua_Debug ar;
121 int level = luaL_optint(L, 1, 1);
122 luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
123 if (lua_getstack(L, level, &ar) == 0)
124 luaL_argerror(L, 1, "invalid level");
125 lua_getinfo(L, "f", &ar);
126 if (lua_isnil(L, -1))
127 luaL_error(L, "no function environment for tail call at level %d",
128 level);
129 }
130}
131
132
133static int luaB_getfenv (lua_State *L) {
134 getfunc(L);
135 if (lua_iscfunction(L, -1)) /* is a C function? */
136 lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
137 else
138 lua_getfenv(L, -1);
139 return 1;
140}
141
142
143static int luaB_setfenv (lua_State *L) {
144 luaL_checktype(L, 2, LUA_TTABLE);
145 getfunc(L);
146 lua_pushvalue(L, 2);
147 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
148 /* change environment of current thread */
149 lua_pushthread(L);
150 lua_insert(L, -2);
151 lua_setfenv(L, -2);
152 return 0;
153 }
154 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
155 luaL_error(L,
156 LUA_QL("setfenv") " cannot change environment of given object");
157 return 1;
158}
159
160
161static int luaB_rawequal (lua_State *L) {
162 luaL_checkany(L, 1);
163 luaL_checkany(L, 2);
164 lua_pushboolean(L, lua_rawequal(L, 1, 2));
165 return 1;
166}
167
168
169static int luaB_rawget (lua_State *L) {
170 luaL_checktype(L, 1, LUA_TTABLE);
171 luaL_checkany(L, 2);
172 lua_settop(L, 2);
173 lua_rawget(L, 1);
174 return 1;
175}
176
177static int luaB_rawset (lua_State *L) {
178 luaL_checktype(L, 1, LUA_TTABLE);
179 luaL_checkany(L, 2);
180 luaL_checkany(L, 3);
181 lua_settop(L, 3);
182 lua_rawset(L, 1);
183 return 1;
184}
185
186
187static int luaB_gcinfo (lua_State *L) {
188 lua_pushinteger(L, lua_getgccount(L));
189 return 1;
190}
191
192
193static int luaB_collectgarbage (lua_State *L) {
194 static const char *const opts[] = {"stop", "restart", "collect",
195 "count", "step", "setpause", "setstepmul", NULL};
196 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
197 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
198 int o = luaL_checkoption(L, 1, "collect", opts);
199 int ex = luaL_optint(L, 2, 0);
200 int res = lua_gc(L, optsnum[o], ex);
201 switch (optsnum[o]) {
202 case LUA_GCCOUNT: {
203 int b = lua_gc(L, LUA_GCCOUNTB, 0);
204 lua_pushnumber(L, res + ((lua_Number)b/1024));
205 return 1;
206 }
207 case LUA_GCSTEP: {
208 lua_pushboolean(L, res);
209 return 1;
210 }
211 default: {
212 lua_pushnumber(L, res);
213 return 1;
214 }
215 }
216}
217
218
219static int luaB_type (lua_State *L) {
220 luaL_checkany(L, 1);
221 lua_pushstring(L, luaL_typename(L, 1));
222 return 1;
223}
224
225
226static int luaB_next (lua_State *L) {
227 luaL_checktype(L, 1, LUA_TTABLE);
228 lua_settop(L, 2); /* create a 2nd argument if there isn't one */
229 if (lua_next(L, 1))
230 return 2;
231 else {
232 lua_pushnil(L);
233 return 1;
234 }
235}
236
237
238static int luaB_pairs (lua_State *L) {
239 luaL_checktype(L, 1, LUA_TTABLE);
240 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
241 lua_pushvalue(L, 1); /* state, */
242 lua_pushnil(L); /* and initial value */
243 return 3;
244}
245
246
247static int ipairsaux (lua_State *L) {
248 int i = luaL_checkint(L, 2);
249 luaL_checktype(L, 1, LUA_TTABLE);
250 i++; /* next value */
251 lua_pushinteger(L, i);
252 lua_rawgeti(L, 1, i);
253 return (lua_isnil(L, -1)) ? 0 : 2;
254}
255
256
257static int luaB_ipairs (lua_State *L) {
258 luaL_checktype(L, 1, LUA_TTABLE);
259 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
260 lua_pushvalue(L, 1); /* state, */
261 lua_pushinteger(L, 0); /* and initial value */
262 return 3;
263}
264
265
266static int load_aux (lua_State *L, int status) {
267 if (status == 0) /* OK? */
268 return 1;
269 else {
270 lua_pushnil(L);
271 lua_insert(L, -2); /* put before error message */
272 return 2; /* return nil plus error message */
273 }
274}
275
276
277static int luaB_loadstring (lua_State *L) {
278 size_t l;
279 const char *s = luaL_checklstring(L, 1, &l);
280 const char *chunkname = luaL_optstring(L, 2, s);
281 return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
282}
283
284
285static int luaB_loadfile (lua_State *L) {
286 const char *fname = luaL_optstring(L, 1, NULL);
287 return load_aux(L, luaL_loadfile(L, fname));
288}
289
290
291/*
292** Reader for generic `load' function: `lua_load' uses the
293** stack for internal stuff, so the reader cannot change the
294** stack top. Instead, it keeps its resulting string in a
295** reserved slot inside the stack.
296*/
297static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
298 (void)ud; /* to avoid warnings */
299 luaL_checkstack(L, 2, "too many nested functions");
300 lua_pushvalue(L, 1); /* get function */
301 lua_call(L, 0, 1); /* call it */
302 if (lua_isnil(L, -1)) {
303 *size = 0;
304 return NULL;
305 }
306 else if (lua_isstring(L, -1)) {
307 lua_replace(L, 3); /* save string in a reserved stack slot */
308 return lua_tolstring(L, 3, size);
309 }
310 else luaL_error(L, "reader function must return a string");
311 return NULL; /* to avoid warnings */
312}
313
314
315static int luaB_load (lua_State *L) {
316 int status;
317 const char *cname = luaL_optstring(L, 2, "=(load)");
318 luaL_checktype(L, 1, LUA_TFUNCTION);
319 lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
320 status = lua_load(L, generic_reader, NULL, cname);
321 return load_aux(L, status);
322}
323
324
325static int luaB_dofile (lua_State *L) {
326 const char *fname = luaL_optstring(L, 1, NULL);
327 int n = lua_gettop(L);
328 if (luaL_loadfile(L, fname) != 0) lua_error(L);
329 lua_call(L, 0, LUA_MULTRET);
330 return lua_gettop(L) - n;
331}
332
333
334static int luaB_assert (lua_State *L) {
335 luaL_checkany(L, 1);
336 if (!lua_toboolean(L, 1))
337 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
338 return lua_gettop(L);
339}
340
341
342static int luaB_unpack (lua_State *L) {
343 int i, e, n;
344 luaL_checktype(L, 1, LUA_TTABLE);
345 i = luaL_optint(L, 2, 1);
346 e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
347 n = e - i + 1; /* number of elements */
348 if (n <= 0) return 0; /* empty range */
349 luaL_checkstack(L, n, "table too big to unpack");
350 for (; i<=e; i++) /* push arg[i...e] */
351 lua_rawgeti(L, 1, i);
352 return n;
353}
354
355
356static int luaB_select (lua_State *L) {
357 int n = lua_gettop(L);
358 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
359 lua_pushinteger(L, n-1);
360 return 1;
361 }
362 else {
363 int i = luaL_checkint(L, 1);
364 if (i < 0) i = n + i;
365 else if (i > n) i = n;
366 luaL_argcheck(L, 1 <= i, 1, "index out of range");
367 return n - i;
368 }
369}
370
371
372static int luaB_pcall (lua_State *L) {
373 int status;
374 luaL_checkany(L, 1);
375 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
376 lua_pushboolean(L, (status == 0));
377 lua_insert(L, 1);
378 return lua_gettop(L); /* return status + all results */
379}
380
381
382static int luaB_xpcall (lua_State *L) {
383 int status;
384 luaL_checkany(L, 2);
385 lua_settop(L, 2);
386 lua_insert(L, 1); /* put error function under function to be called */
387 status = lua_pcall(L, 0, LUA_MULTRET, 1);
388 lua_pushboolean(L, (status == 0));
389 lua_replace(L, 1);
390 return lua_gettop(L); /* return status + all results */
391}
392
393
394static int luaB_tostring (lua_State *L) {
395 luaL_checkany(L, 1);
396 if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
397 return 1; /* use its value */
398 switch (lua_type(L, 1)) {
399 case LUA_TNUMBER:
400 lua_pushstring(L, lua_tostring(L, 1));
401 break;
402 case LUA_TSTRING:
403 lua_pushvalue(L, 1);
404 break;
405 case LUA_TBOOLEAN:
406 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
407 break;
408 case LUA_TNIL:
409 lua_pushliteral(L, "nil");
410 break;
411 default:
412 lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
413 break;
414 }
415 return 1;
416}
417
418
419static int luaB_newproxy (lua_State *L) {
420 lua_settop(L, 1);
421 lua_newuserdata(L, 0); /* create proxy */
422 if (lua_toboolean(L, 1) == 0)
423 return 1; /* no metatable */
424 else if (lua_isboolean(L, 1)) {
425 lua_newtable(L); /* create a new metatable `m' ... */
426 lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
427 lua_pushboolean(L, 1);
428 lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
429 }
430 else {
431 int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
432 if (lua_getmetatable(L, 1)) {
433 lua_rawget(L, lua_upvalueindex(1));
434 validproxy = lua_toboolean(L, -1);
435 lua_pop(L, 1); /* remove value */
436 }
437 luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
438 lua_getmetatable(L, 1); /* metatable is valid; get it */
439 }
440 lua_setmetatable(L, 2);
441 return 1;
442}
443
444
445static const luaL_Reg base_funcs[] = {
446 {"assert", luaB_assert},
447 {"collectgarbage", luaB_collectgarbage},
448 {"dofile", luaB_dofile},
449 {"error", luaB_error},
450 {"gcinfo", luaB_gcinfo},
451 {"getfenv", luaB_getfenv},
452 {"getmetatable", luaB_getmetatable},
453 {"loadfile", luaB_loadfile},
454 {"load", luaB_load},
455 {"loadstring", luaB_loadstring},
456 {"next", luaB_next},
457 {"pcall", luaB_pcall},
458 {"print", luaB_print},
459 {"rawequal", luaB_rawequal},
460 {"rawget", luaB_rawget},
461 {"rawset", luaB_rawset},
462 {"select", luaB_select},
463 {"setfenv", luaB_setfenv},
464 {"setmetatable", luaB_setmetatable},
465 {"tonumber", luaB_tonumber},
466 {"tostring", luaB_tostring},
467 {"type", luaB_type},
468 {"unpack", luaB_unpack},
469 {"xpcall", luaB_xpcall},
470 {NULL, NULL}
471};
472
473
474/*
475** {======================================================
476** Coroutine library
477** =======================================================
478*/
479
480static int auxresume (lua_State *L, lua_State *co, int narg) {
481 int status;
482 if (!lua_checkstack(co, narg))
483 luaL_error(L, "too many arguments to resume");
484 if (lua_status(co) == 0 && lua_gettop(co) == 0) {
485 lua_pushliteral(L, "cannot resume dead coroutine");
486 return -1; /* error flag */
487 }
488 lua_xmove(L, co, narg);
489 status = lua_resume(co, narg);
490 if (status == 0 || status == LUA_YIELD) {
491 int nres = lua_gettop(co);
492 if (!lua_checkstack(L, nres))
493 luaL_error(L, "too many results to resume");
494 lua_xmove(co, L, nres); /* move yielded values */
495 return nres;
496 }
497 else {
498 lua_xmove(co, L, 1); /* move error message */
499 return -1; /* error flag */
500 }
501}
502
503
504static int luaB_coresume (lua_State *L) {
505 lua_State *co = lua_tothread(L, 1);
506 int r;
507 luaL_argcheck(L, co, 1, "coroutine expected");
508 r = auxresume(L, co, lua_gettop(L) - 1);
509 if (r < 0) {
510 lua_pushboolean(L, 0);
511 lua_insert(L, -2);
512 return 2; /* return false + error message */
513 }
514 else {
515 lua_pushboolean(L, 1);
516 lua_insert(L, -(r + 1));
517 return r + 1; /* return true + `resume' returns */
518 }
519}
520
521
522static int luaB_auxwrap (lua_State *L) {
523 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
524 int r = auxresume(L, co, lua_gettop(L));
525 if (r < 0) {
526 if (lua_isstring(L, -1)) { /* error object is a string? */
527 luaL_where(L, 1); /* add extra info */
528 lua_insert(L, -2);
529 lua_concat(L, 2);
530 }
531 lua_error(L); /* propagate error */
532 }
533 return r;
534}
535
536
537static int luaB_cocreate (lua_State *L) {
538 lua_State *NL = lua_newthread(L);
539 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
540 "Lua function expected");
541 lua_pushvalue(L, 1); /* move function to top */
542 lua_xmove(L, NL, 1); /* move function from L to NL */
543 return 1;
544}
545
546
547static int luaB_cowrap (lua_State *L) {
548 luaB_cocreate(L);
549 lua_pushcclosure(L, luaB_auxwrap, 1);
550 return 1;
551}
552
553
554static int luaB_yield (lua_State *L) {
555 return lua_yield(L, lua_gettop(L));
556}
557
558
559static int luaB_costatus (lua_State *L) {
560 lua_State *co = lua_tothread(L, 1);
561 luaL_argcheck(L, co, 1, "coroutine expected");
562 if (L == co) lua_pushliteral(L, "running");
563 else {
564 switch (lua_status(co)) {
565 case LUA_YIELD:
566 lua_pushliteral(L, "suspended");
567 break;
568 case 0: {
569 lua_Debug ar;
570 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
571 lua_pushliteral(L, "normal"); /* it is running */
572 else if (lua_gettop(co) == 0)
573 lua_pushliteral(L, "dead");
574 else
575 lua_pushliteral(L, "suspended"); /* initial state */
576 break;
577 }
578 default: /* some error occured */
579 lua_pushliteral(L, "dead");
580 break;
581 }
582 }
583 return 1;
584}
585
586
587static int luaB_corunning (lua_State *L) {
588 if (lua_pushthread(L))
589 return 0; /* main thread is not a coroutine */
590 else
591 return 1;
592}
593
594
595static const luaL_Reg co_funcs[] = {
596 {"create", luaB_cocreate},
597 {"resume", luaB_coresume},
598 {"running", luaB_corunning},
599 {"status", luaB_costatus},
600 {"wrap", luaB_cowrap},
601 {"yield", luaB_yield},
602 {NULL, NULL}
603};
604
605/* }====================================================== */
606
607
608static void auxopen (lua_State *L, const char *name,
609 lua_CFunction f, lua_CFunction u) {
610 lua_pushcfunction(L, u);
611 lua_pushcclosure(L, f, 1);
612 lua_setfield(L, -2, name);
613}
614
615
616static void base_open (lua_State *L) {
617 /* set global _G */
618 lua_pushvalue(L, LUA_GLOBALSINDEX);
619 lua_setglobal(L, "_G");
620 /* open lib into global table */
621 luaL_register(L, "_G", base_funcs);
622 lua_pushliteral(L, LUA_VERSION);
623 lua_setglobal(L, "_VERSION"); /* set global _VERSION */
624 /* `ipairs' and `pairs' need auxiliary functions as upvalues */
625 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
626 auxopen(L, "pairs", luaB_pairs, luaB_next);
627 /* `newproxy' needs a weaktable as upvalue */
628 lua_createtable(L, 0, 1); /* new table `w' */
629 lua_pushvalue(L, -1); /* `w' will be its own metatable */
630 lua_setmetatable(L, -2);
631 lua_pushliteral(L, "kv");
632 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
633 lua_pushcclosure(L, luaB_newproxy, 1);
634 lua_setglobal(L, "newproxy"); /* set global `newproxy' */
635}
636
637
638LUALIB_API int luaopen_base (lua_State *L) {
639 base_open(L);
640 luaL_register(L, LUA_COLIBNAME, co_funcs);
641 return 2;
642}
643
diff --git a/lcode.c b/lcode.c
deleted file mode 100644
index b8ba2a98..00000000
--- a/lcode.c
+++ /dev/null
@@ -1,823 +0,0 @@
1/*
2** $Id: lcode.c,v 2.24 2005/12/22 16:19:56 roberto Exp roberto $
3** Code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9
10#define lcode_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lcode.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lgc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lparser.h"
24#include "ltable.h"
25
26
27#define hasjumps(e) ((e)->t != (e)->f)
28
29
30static int isnumeral(expdesc *e) {
31 return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
32}
33
34
35void luaK_nil (FuncState *fs, int from, int n) {
36 Instruction *previous;
37 if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
38 if (fs->pc == 0) /* function start? */
39 return; /* positions are already clean */
40 if (GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
41 int pfrom = GETARG_A(*previous);
42 int pto = GETARG_B(*previous);
43 if (pfrom <= from && from <= pto+1) { /* can connect both? */
44 if (from+n-1 > pto)
45 SETARG_B(*previous, from+n-1);
46 return;
47 }
48 }
49 }
50 luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
51}
52
53
54int luaK_jump (FuncState *fs) {
55 int jpc = fs->jpc; /* save list of jumps to here */
56 int j;
57 fs->jpc = NO_JUMP;
58 j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
59 luaK_concat(fs, &j, jpc); /* keep them on hold */
60 return j;
61}
62
63
64void luaK_ret (FuncState *fs, int first, int nret) {
65 luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
66}
67
68
69static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
70 luaK_codeABC(fs, op, A, B, C);
71 return luaK_jump(fs);
72}
73
74
75static void fixjump (FuncState *fs, int pc, int dest) {
76 Instruction *jmp = &fs->f->code[pc];
77 int offset = dest-(pc+1);
78 lua_assert(dest != NO_JUMP);
79 if (abs(offset) > MAXARG_sBx)
80 luaX_syntaxerror(fs->ls, "control structure too long");
81 SETARG_sBx(*jmp, offset);
82}
83
84
85/*
86** returns current `pc' and marks it as a jump target (to avoid wrong
87** optimizations with consecutive instructions not in the same basic block).
88*/
89int luaK_getlabel (FuncState *fs) {
90 fs->lasttarget = fs->pc;
91 return fs->pc;
92}
93
94
95static int getjump (FuncState *fs, int pc) {
96 int offset = GETARG_sBx(fs->f->code[pc]);
97 if (offset == NO_JUMP) /* point to itself represents end of list */
98 return NO_JUMP; /* end of list */
99 else
100 return (pc+1)+offset; /* turn offset into absolute position */
101}
102
103
104static Instruction *getjumpcontrol (FuncState *fs, int pc) {
105 Instruction *pi = &fs->f->code[pc];
106 if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
107 return pi-1;
108 else
109 return pi;
110}
111
112
113/*
114** check whether list has any jump that do not produce a value
115** (or produce an inverted value)
116*/
117static int need_value (FuncState *fs, int list) {
118 for (; list != NO_JUMP; list = getjump(fs, list)) {
119 Instruction i = *getjumpcontrol(fs, list);
120 if (GET_OPCODE(i) != OP_TESTSET) return 1;
121 }
122 return 0; /* not found */
123}
124
125
126static int patchtestreg (FuncState *fs, int node, int reg) {
127 Instruction *i = getjumpcontrol(fs, node);
128 if (GET_OPCODE(*i) != OP_TESTSET)
129 return 0; /* cannot patch other instructions */
130 if (reg != NO_REG && reg != GETARG_B(*i))
131 SETARG_A(*i, reg);
132 else /* no register to put value or register already has the value */
133 *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
134
135 return 1;
136}
137
138
139static void removevalues (FuncState *fs, int list) {
140 for (; list != NO_JUMP; list = getjump(fs, list))
141 patchtestreg(fs, list, NO_REG);
142}
143
144
145static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
146 int dtarget) {
147 while (list != NO_JUMP) {
148 int next = getjump(fs, list);
149 if (patchtestreg(fs, list, reg))
150 fixjump(fs, list, vtarget);
151 else
152 fixjump(fs, list, dtarget); /* jump to default target */
153 list = next;
154 }
155}
156
157
158static void dischargejpc (FuncState *fs) {
159 patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
160 fs->jpc = NO_JUMP;
161}
162
163
164void luaK_patchlist (FuncState *fs, int list, int target) {
165 if (target == fs->pc)
166 luaK_patchtohere(fs, list);
167 else {
168 lua_assert(target < fs->pc);
169 patchlistaux(fs, list, target, NO_REG, target);
170 }
171}
172
173
174void luaK_patchtohere (FuncState *fs, int list) {
175 luaK_getlabel(fs);
176 luaK_concat(fs, &fs->jpc, list);
177}
178
179
180void luaK_concat (FuncState *fs, int *l1, int l2) {
181 if (l2 == NO_JUMP) return;
182 else if (*l1 == NO_JUMP)
183 *l1 = l2;
184 else {
185 int list = *l1;
186 int next;
187 while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
188 list = next;
189 fixjump(fs, list, l2);
190 }
191}
192
193
194void luaK_checkstack (FuncState *fs, int n) {
195 int newstack = fs->freereg + n;
196 if (newstack > fs->f->maxstacksize) {
197 if (newstack >= MAXSTACK)
198 luaX_syntaxerror(fs->ls, "function or expression too complex");
199 fs->f->maxstacksize = cast_byte(newstack);
200 }
201}
202
203
204void luaK_reserveregs (FuncState *fs, int n) {
205 luaK_checkstack(fs, n);
206 fs->freereg += n;
207}
208
209
210static void freereg (FuncState *fs, int reg) {
211 if (!ISK(reg) && reg >= fs->nactvar) {
212 fs->freereg--;
213 lua_assert(reg == fs->freereg);
214 }
215}
216
217
218static void freeexp (FuncState *fs, expdesc *e) {
219 if (e->k == VNONRELOC)
220 freereg(fs, e->u.s.info);
221}
222
223
224static int addk (FuncState *fs, TValue *k, TValue *v) {
225 lua_State *L = fs->L;
226 TValue *idx = luaH_set(L, fs->h, k);
227 Proto *f = fs->f;
228 int oldsize = f->sizek;
229 if (ttisnumber(idx)) {
230 lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
231 return cast_int(nvalue(idx));
232 }
233 else { /* constant not found; create a new entry */
234 setnvalue(idx, cast_num(fs->nk));
235 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
236 MAXARG_Bx, "constant table overflow");
237 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
238 setobj(L, &f->k[fs->nk], v);
239 luaC_barrier(L, f, v);
240 return fs->nk++;
241 }
242}
243
244
245int luaK_stringK (FuncState *fs, TString *s) {
246 TValue o;
247 setsvalue(fs->L, &o, s);
248 return addk(fs, &o, &o);
249}
250
251
252int luaK_numberK (FuncState *fs, lua_Number r) {
253 TValue o;
254 setnvalue(&o, r);
255 return addk(fs, &o, &o);
256}
257
258
259static int boolK (FuncState *fs, int b) {
260 TValue o;
261 setbvalue(&o, b);
262 return addk(fs, &o, &o);
263}
264
265
266static int nilK (FuncState *fs) {
267 TValue k, v;
268 setnilvalue(&v);
269 /* cannot use nil as key; instead use table itself to represent nil */
270 sethvalue(fs->L, &k, fs->h);
271 return addk(fs, &k, &v);
272}
273
274
275void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
276 if (e->k == VCALL) { /* expression is an open function call? */
277 SETARG_C(getcode(fs, e), nresults+1);
278 }
279 else if (e->k == VVARARG) {
280 SETARG_B(getcode(fs, e), nresults+1);
281 SETARG_A(getcode(fs, e), fs->freereg);
282 luaK_reserveregs(fs, 1);
283 }
284}
285
286
287void luaK_setoneret (FuncState *fs, expdesc *e) {
288 if (e->k == VCALL) { /* expression is an open function call? */
289 e->k = VNONRELOC;
290 e->u.s.info = GETARG_A(getcode(fs, e));
291 }
292 else if (e->k == VVARARG) {
293 SETARG_B(getcode(fs, e), 2);
294 e->k = VRELOCABLE; /* can relocate its simple result */
295 }
296}
297
298
299void luaK_dischargevars (FuncState *fs, expdesc *e) {
300 switch (e->k) {
301 case VLOCAL: {
302 e->k = VNONRELOC;
303 break;
304 }
305 case VUPVAL: {
306 e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
307 e->k = VRELOCABLE;
308 break;
309 }
310 case VGLOBAL: {
311 e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
312 e->k = VRELOCABLE;
313 break;
314 }
315 case VINDEXED: {
316 freereg(fs, e->u.s.aux);
317 freereg(fs, e->u.s.info);
318 e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
319 e->k = VRELOCABLE;
320 break;
321 }
322 case VVARARG:
323 case VCALL: {
324 luaK_setoneret(fs, e);
325 break;
326 }
327 default: break; /* there is one value available (somewhere) */
328 }
329}
330
331
332static int code_label (FuncState *fs, int A, int b, int jump) {
333 luaK_getlabel(fs); /* those instructions may be jump targets */
334 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
335}
336
337
338static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
339 luaK_dischargevars(fs, e);
340 switch (e->k) {
341 case VNIL: {
342 luaK_nil(fs, reg, 1);
343 break;
344 }
345 case VFALSE: case VTRUE: {
346 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
347 break;
348 }
349 case VK: {
350 luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
351 break;
352 }
353 case VKNUM: {
354 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
355 break;
356 }
357 case VRELOCABLE: {
358 Instruction *pc = &getcode(fs, e);
359 SETARG_A(*pc, reg);
360 break;
361 }
362 case VNONRELOC: {
363 if (reg != e->u.s.info)
364 luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
365 break;
366 }
367 default: {
368 lua_assert(e->k == VVOID || e->k == VJMP);
369 return; /* nothing to do... */
370 }
371 }
372 e->u.s.info = reg;
373 e->k = VNONRELOC;
374}
375
376
377static void discharge2anyreg (FuncState *fs, expdesc *e) {
378 if (e->k != VNONRELOC) {
379 luaK_reserveregs(fs, 1);
380 discharge2reg(fs, e, fs->freereg-1);
381 }
382}
383
384
385static void exp2reg (FuncState *fs, expdesc *e, int reg) {
386 discharge2reg(fs, e, reg);
387 if (e->k == VJMP)
388 luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
389 if (hasjumps(e)) {
390 int final; /* position after whole expression */
391 int p_f = NO_JUMP; /* position of an eventual LOAD false */
392 int p_t = NO_JUMP; /* position of an eventual LOAD true */
393 if (need_value(fs, e->t) || need_value(fs, e->f)) {
394 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
395 p_f = code_label(fs, reg, 0, 1);
396 p_t = code_label(fs, reg, 1, 0);
397 luaK_patchtohere(fs, fj);
398 }
399 final = luaK_getlabel(fs);
400 patchlistaux(fs, e->f, final, reg, p_f);
401 patchlistaux(fs, e->t, final, reg, p_t);
402 }
403 e->f = e->t = NO_JUMP;
404 e->u.s.info = reg;
405 e->k = VNONRELOC;
406}
407
408
409void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
410 luaK_dischargevars(fs, e);
411 freeexp(fs, e);
412 luaK_reserveregs(fs, 1);
413 exp2reg(fs, e, fs->freereg - 1);
414}
415
416
417int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
418 luaK_dischargevars(fs, e);
419 if (e->k == VNONRELOC) {
420 if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
421 if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
422 exp2reg(fs, e, e->u.s.info); /* put value on it */
423 return e->u.s.info;
424 }
425 }
426 luaK_exp2nextreg(fs, e); /* default */
427 return e->u.s.info;
428}
429
430
431void luaK_exp2val (FuncState *fs, expdesc *e) {
432 if (hasjumps(e))
433 luaK_exp2anyreg(fs, e);
434 else
435 luaK_dischargevars(fs, e);
436}
437
438
439int luaK_exp2RK (FuncState *fs, expdesc *e) {
440 luaK_exp2val(fs, e);
441 switch (e->k) {
442 case VKNUM:
443 case VTRUE:
444 case VFALSE:
445 case VNIL: {
446 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
447 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
448 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
449 boolK(fs, (e->k == VTRUE));
450 e->k = VK;
451 return RKASK(e->u.s.info);
452 }
453 else break;
454 }
455 case VK: {
456 if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
457 return RKASK(e->u.s.info);
458 else break;
459 }
460 default: break;
461 }
462 /* not a constant in the right range: put it in a register */
463 return luaK_exp2anyreg(fs, e);
464}
465
466
467void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
468 switch (var->k) {
469 case VLOCAL: {
470 freeexp(fs, ex);
471 exp2reg(fs, ex, var->u.s.info);
472 return;
473 }
474 case VUPVAL: {
475 int e = luaK_exp2anyreg(fs, ex);
476 luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
477 break;
478 }
479 case VGLOBAL: {
480 int e = luaK_exp2anyreg(fs, ex);
481 luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
482 break;
483 }
484 case VINDEXED: {
485 int e = luaK_exp2RK(fs, ex);
486 luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
487 break;
488 }
489 default: {
490 lua_assert(0); /* invalid var kind to store */
491 break;
492 }
493 }
494 freeexp(fs, ex);
495}
496
497
498void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
499 int func;
500 luaK_exp2anyreg(fs, e);
501 freeexp(fs, e);
502 func = fs->freereg;
503 luaK_reserveregs(fs, 2);
504 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
505 freeexp(fs, key);
506 e->u.s.info = func;
507 e->k = VNONRELOC;
508}
509
510
511static void invertjump (FuncState *fs, expdesc *e) {
512 Instruction *pc = getjumpcontrol(fs, e->u.s.info);
513 lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
514 GET_OPCODE(*pc) != OP_TEST);
515 SETARG_A(*pc, !(GETARG_A(*pc)));
516}
517
518
519static int jumponcond (FuncState *fs, expdesc *e, int cond) {
520 if (e->k == VRELOCABLE) {
521 Instruction ie = getcode(fs, e);
522 if (GET_OPCODE(ie) == OP_NOT) {
523 fs->pc--; /* remove previous OP_NOT */
524 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
525 }
526 /* else go through */
527 }
528 discharge2anyreg(fs, e);
529 freeexp(fs, e);
530 return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
531}
532
533
534void luaK_goiftrue (FuncState *fs, expdesc *e) {
535 int pc; /* pc of last jump */
536 luaK_dischargevars(fs, e);
537 switch (e->k) {
538 case VK: case VKNUM: case VTRUE: {
539 pc = NO_JUMP; /* always true; do nothing */
540 break;
541 }
542 case VFALSE: {
543 pc = luaK_jump(fs); /* always jump */
544 break;
545 }
546 case VJMP: {
547 invertjump(fs, e);
548 pc = e->u.s.info;
549 break;
550 }
551 default: {
552 pc = jumponcond(fs, e, 0);
553 break;
554 }
555 }
556 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
557 luaK_patchtohere(fs, e->t);
558 e->t = NO_JUMP;
559}
560
561
562static void luaK_goiffalse (FuncState *fs, expdesc *e) {
563 int pc; /* pc of last jump */
564 luaK_dischargevars(fs, e);
565 switch (e->k) {
566 case VNIL: case VFALSE: {
567 pc = NO_JUMP; /* always false; do nothing */
568 break;
569 }
570 case VTRUE: {
571 pc = luaK_jump(fs); /* always jump */
572 break;
573 }
574 case VJMP: {
575 pc = e->u.s.info;
576 break;
577 }
578 default: {
579 pc = jumponcond(fs, e, 1);
580 break;
581 }
582 }
583 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
584 luaK_patchtohere(fs, e->f);
585 e->f = NO_JUMP;
586}
587
588
589static void codenot (FuncState *fs, expdesc *e) {
590 luaK_dischargevars(fs, e);
591 switch (e->k) {
592 case VNIL: case VFALSE: {
593 e->k = VTRUE;
594 break;
595 }
596 case VK: case VKNUM: case VTRUE: {
597 e->k = VFALSE;
598 break;
599 }
600 case VJMP: {
601 invertjump(fs, e);
602 break;
603 }
604 case VRELOCABLE:
605 case VNONRELOC: {
606 discharge2anyreg(fs, e);
607 freeexp(fs, e);
608 e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
609 e->k = VRELOCABLE;
610 break;
611 }
612 default: {
613 lua_assert(0); /* cannot happen */
614 break;
615 }
616 }
617 /* interchange true and false lists */
618 { int temp = e->f; e->f = e->t; e->t = temp; }
619 removevalues(fs, e->f);
620 removevalues(fs, e->t);
621}
622
623
624void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
625 t->u.s.aux = luaK_exp2RK(fs, k);
626 t->k = VINDEXED;
627}
628
629
630static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
631 lua_Number v1, v2, r;
632 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
633 v1 = e1->u.nval;
634 v2 = e2->u.nval;
635 switch (op) {
636 case OP_ADD: r = luai_numadd(v1, v2); break;
637 case OP_SUB: r = luai_numsub(v1, v2); break;
638 case OP_MUL: r = luai_nummul(v1, v2); break;
639 case OP_DIV:
640 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
641 r = luai_numdiv(v1, v2); break;
642 case OP_MOD:
643 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
644 r = luai_nummod(v1, v2); break;
645 case OP_POW: r = luai_numpow(v1, v2); break;
646 case OP_UNM: r = luai_numunm(v1); break;
647 case OP_LEN: return 0; /* no constant folding for 'len' */
648 default: lua_assert(0); r = 0; break;
649 }
650 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
651 e1->u.nval = r;
652 return 1;
653}
654
655
656static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
657 if (constfolding(op, e1, e2))
658 return;
659 else {
660 int o1 = luaK_exp2RK(fs, e1);
661 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
662 freeexp(fs, e2);
663 freeexp(fs, e1);
664 e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
665 e1->k = VRELOCABLE;
666 }
667}
668
669
670static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
671 expdesc *e2) {
672 int o1 = luaK_exp2RK(fs, e1);
673 int o2 = luaK_exp2RK(fs, e2);
674 freeexp(fs, e2);
675 freeexp(fs, e1);
676 if (cond == 0 && op != OP_EQ) {
677 int temp; /* exchange args to replace by `<' or `<=' */
678 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
679 cond = 1;
680 }
681 e1->u.s.info = condjump(fs, op, cond, o1, o2);
682 e1->k = VJMP;
683}
684
685
686void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
687 expdesc e2;
688 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
689 switch (op) {
690 case OPR_MINUS: {
691 if (e->k == VK)
692 luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
693 codearith(fs, OP_UNM, e, &e2);
694 break;
695 }
696 case OPR_NOT: codenot(fs, e); break;
697 case OPR_LEN: {
698 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
699 codearith(fs, OP_LEN, e, &e2);
700 break;
701 }
702 default: lua_assert(0);
703 }
704}
705
706
707void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
708 switch (op) {
709 case OPR_AND: {
710 luaK_goiftrue(fs, v);
711 break;
712 }
713 case OPR_OR: {
714 luaK_goiffalse(fs, v);
715 break;
716 }
717 case OPR_CONCAT: {
718 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
719 break;
720 }
721 default: {
722 if (!isnumeral(v)) luaK_exp2RK(fs, v);
723 break;
724 }
725 }
726}
727
728
729void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
730 switch (op) {
731 case OPR_AND: {
732 lua_assert(e1->t == NO_JUMP); /* list must be closed */
733 luaK_dischargevars(fs, e2);
734 luaK_concat(fs, &e2->f, e1->f);
735 *e1 = *e2;
736 break;
737 }
738 case OPR_OR: {
739 lua_assert(e1->f == NO_JUMP); /* list must be closed */
740 luaK_dischargevars(fs, e2);
741 luaK_concat(fs, &e2->t, e1->t);
742 *e1 = *e2;
743 break;
744 }
745 case OPR_CONCAT: {
746 luaK_exp2val(fs, e2);
747 if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
748 lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
749 freeexp(fs, e1);
750 SETARG_B(getcode(fs, e2), e1->u.s.info);
751 e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
752 }
753 else {
754 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
755 codearith(fs, OP_CONCAT, e1, e2);
756 }
757 break;
758 }
759 case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
760 case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
761 case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
762 case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
763 case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
764 case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
765 case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
766 case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
767 case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
768 case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
769 case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
770 case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
771 default: lua_assert(0);
772 }
773}
774
775
776void luaK_fixline (FuncState *fs, int line) {
777 fs->f->lineinfo[fs->pc - 1] = line;
778}
779
780
781static int luaK_code (FuncState *fs, Instruction i, int line) {
782 Proto *f = fs->f;
783 dischargejpc(fs); /* `pc' will change */
784 /* put new instruction in code array */
785 luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
786 MAX_INT, "code size overflow");
787 f->code[fs->pc] = i;
788 /* save corresponding line information */
789 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
790 MAX_INT, "code size overflow");
791 f->lineinfo[fs->pc] = line;
792 return fs->pc++;
793}
794
795
796int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
797 lua_assert(getOpMode(o) == iABC);
798 lua_assert(getBMode(o) != OpArgN || b == 0);
799 lua_assert(getCMode(o) != OpArgN || c == 0);
800 return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
801}
802
803
804int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
805 lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
806 lua_assert(getCMode(o) == OpArgN);
807 return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
808}
809
810
811void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
812 int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
813 int b = (tostore == LUA_MULTRET) ? 0 : tostore;
814 lua_assert(tostore != 0);
815 if (c <= MAXARG_C)
816 luaK_codeABC(fs, OP_SETLIST, base, b, c);
817 else {
818 luaK_codeABC(fs, OP_SETLIST, base, b, 0);
819 luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
820 }
821 fs->freereg = base + 1; /* free registers with list values */
822}
823
diff --git a/lcode.h b/lcode.h
deleted file mode 100644
index ff5ee27d..00000000
--- a/lcode.h
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2** $Id: lcode.h,v 1.47 2005/11/08 19:44:31 roberto Exp roberto $
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*/
26typedef enum BinOpr {
27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
28 OPR_CONCAT,
29 OPR_NE, OPR_EQ,
30 OPR_LT, OPR_LE, OPR_GT, OPR_GE,
31 OPR_AND, OPR_OR,
32 OPR_NOBINOPR
33} BinOpr;
34
35
36typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37
38
39#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
40
41#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
42
43#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
44
45LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
47LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
48LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
49LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
50LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
51LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
52LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
53LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
54LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
55LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
56LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
57LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
58LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
59LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
61LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
62LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
63LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
64LUAI_FUNC int luaK_jump (FuncState *fs);
65LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
66LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
67LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
68LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
69LUAI_FUNC int luaK_getlabel (FuncState *fs);
70LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
71LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
72LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
73LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
74
75
76#endif
diff --git a/ldblib.c b/ldblib.c
deleted file mode 100644
index 6a07237b..00000000
--- a/ldblib.c
+++ /dev/null
@@ -1,397 +0,0 @@
1/*
2** $Id: ldblib.c,v 1.103 2005/11/01 16:08:32 roberto Exp roberto $
3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define ldblib_c
13#define LUA_LIB
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20
21
22static int db_getregistry (lua_State *L) {
23 lua_pushvalue(L, LUA_REGISTRYINDEX);
24 return 1;
25}
26
27
28static int db_getmetatable (lua_State *L) {
29 luaL_checkany(L, 1);
30 if (!lua_getmetatable(L, 1)) {
31 lua_pushnil(L); /* no metatable */
32 }
33 return 1;
34}
35
36
37static int db_setmetatable (lua_State *L) {
38 int t = lua_type(L, 2);
39 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
40 "nil or table expected");
41 lua_settop(L, 2);
42 lua_pushboolean(L, lua_setmetatable(L, 1));
43 return 1;
44}
45
46
47static int db_getfenv (lua_State *L) {
48 lua_getfenv(L, 1);
49 return 1;
50}
51
52
53static int db_setfenv (lua_State *L) {
54 luaL_checktype(L, 2, LUA_TTABLE);
55 lua_settop(L, 2);
56 if (lua_setfenv(L, 1) == 0)
57 luaL_error(L, LUA_QL("setfenv")
58 " cannot change environment of given object");
59 return 1;
60}
61
62
63static void settabss (lua_State *L, const char *i, const char *v) {
64 lua_pushstring(L, v);
65 lua_setfield(L, -2, i);
66}
67
68
69static void settabsi (lua_State *L, const char *i, int v) {
70 lua_pushinteger(L, v);
71 lua_setfield(L, -2, i);
72}
73
74
75static lua_State *getthread (lua_State *L, int *arg) {
76 if (lua_isthread(L, 1)) {
77 *arg = 1;
78 return lua_tothread(L, 1);
79 }
80 else {
81 *arg = 0;
82 return L;
83 }
84}
85
86
87static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
88 if (L == L1) {
89 lua_pushvalue(L, -2);
90 lua_remove(L, -3);
91 }
92 else
93 lua_xmove(L1, L, 1);
94 lua_setfield(L, -2, fname);
95}
96
97
98static int db_getinfo (lua_State *L) {
99 lua_Debug ar;
100 int arg;
101 lua_State *L1 = getthread(L, &arg);
102 const char *options = luaL_optstring(L, arg+2, "flnSu");
103 if (lua_isnumber(L, arg+1)) {
104 if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
105 lua_pushnil(L); /* level out of range */
106 return 1;
107 }
108 }
109 else if (lua_isfunction(L, arg+1)) {
110 lua_pushfstring(L, ">%s", options);
111 options = lua_tostring(L, -1);
112 lua_pushvalue(L, arg+1);
113 lua_xmove(L, L1, 1);
114 }
115 else
116 return luaL_argerror(L, arg+1, "function or level expected");
117 if (!lua_getinfo(L1, options, &ar))
118 return luaL_argerror(L, arg+2, "invalid option");
119 lua_createtable(L, 0, 2);
120 if (strchr(options, 'S')) {
121 settabss(L, "source", ar.source);
122 settabss(L, "short_src", ar.short_src);
123 settabsi(L, "linedefined", ar.linedefined);
124 settabsi(L, "lastlinedefined", ar.lastlinedefined);
125 settabss(L, "what", ar.what);
126 }
127 if (strchr(options, 'l'))
128 settabsi(L, "currentline", ar.currentline);
129 if (strchr(options, 'u'))
130 settabsi(L, "nups", ar.nups);
131 if (strchr(options, 'n')) {
132 settabss(L, "name", ar.name);
133 settabss(L, "namewhat", ar.namewhat);
134 }
135 if (strchr(options, 'L'))
136 treatstackoption(L, L1, "activelines");
137 if (strchr(options, 'f'))
138 treatstackoption(L, L1, "func");
139 return 1; /* return table */
140}
141
142
143static int db_getlocal (lua_State *L) {
144 int arg;
145 lua_State *L1 = getthread(L, &arg);
146 lua_Debug ar;
147 const char *name;
148 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
149 return luaL_argerror(L, arg+1, "level out of range");
150 name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
151 if (name) {
152 lua_xmove(L1, L, 1);
153 lua_pushstring(L, name);
154 lua_pushvalue(L, -2);
155 return 2;
156 }
157 else {
158 lua_pushnil(L);
159 return 1;
160 }
161}
162
163
164static int db_setlocal (lua_State *L) {
165 int arg;
166 lua_State *L1 = getthread(L, &arg);
167 lua_Debug ar;
168 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
169 return luaL_argerror(L, arg+1, "level out of range");
170 luaL_checkany(L, arg+3);
171 lua_settop(L, arg+3);
172 lua_xmove(L, L1, 1);
173 lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
174 return 1;
175}
176
177
178static int auxupvalue (lua_State *L, int get) {
179 const char *name;
180 int n = luaL_checkint(L, 2);
181 luaL_checktype(L, 1, LUA_TFUNCTION);
182 if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
183 name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
184 if (name == NULL) return 0;
185 lua_pushstring(L, name);
186 lua_insert(L, -(get+1));
187 return get + 1;
188}
189
190
191static int db_getupvalue (lua_State *L) {
192 return auxupvalue(L, 1);
193}
194
195
196static int db_setupvalue (lua_State *L) {
197 luaL_checkany(L, 3);
198 return auxupvalue(L, 0);
199}
200
201
202
203static const char KEY_HOOK = 'h';
204
205
206static void hookf (lua_State *L, lua_Debug *ar) {
207 static const char *const hooknames[] =
208 {"call", "return", "line", "count", "tail return"};
209 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
210 lua_rawget(L, LUA_REGISTRYINDEX);
211 lua_pushlightuserdata(L, L);
212 lua_rawget(L, -2);
213 if (lua_isfunction(L, -1)) {
214 lua_pushstring(L, hooknames[(int)ar->event]);
215 if (ar->currentline >= 0)
216 lua_pushinteger(L, ar->currentline);
217 else lua_pushnil(L);
218 lua_assert(lua_getinfo(L, "lS", ar));
219 lua_call(L, 2, 0);
220 }
221}
222
223
224static int makemask (const char *smask, int count) {
225 int mask = 0;
226 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
227 if (strchr(smask, 'r')) mask |= LUA_MASKRET;
228 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
229 if (count > 0) mask |= LUA_MASKCOUNT;
230 return mask;
231}
232
233
234static char *unmakemask (int mask, char *smask) {
235 int i = 0;
236 if (mask & LUA_MASKCALL) smask[i++] = 'c';
237 if (mask & LUA_MASKRET) smask[i++] = 'r';
238 if (mask & LUA_MASKLINE) smask[i++] = 'l';
239 smask[i] = '\0';
240 return smask;
241}
242
243
244static void gethooktable (lua_State *L) {
245 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
246 lua_rawget(L, LUA_REGISTRYINDEX);
247 if (!lua_istable(L, -1)) {
248 lua_pop(L, 1);
249 lua_createtable(L, 0, 1);
250 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
251 lua_pushvalue(L, -2);
252 lua_rawset(L, LUA_REGISTRYINDEX);
253 }
254}
255
256
257static int db_sethook (lua_State *L) {
258 int arg;
259 lua_State *L1 = getthread(L, &arg);
260 if (lua_isnoneornil(L, arg+1)) {
261 lua_settop(L, arg+1);
262 lua_sethook(L1, NULL, 0, 0); /* turn off hooks */
263 }
264 else {
265 const char *smask = luaL_checkstring(L, arg+2);
266 int count = luaL_optint(L, arg+3, 0);
267 luaL_checktype(L, arg+1, LUA_TFUNCTION);
268 lua_sethook(L1, hookf, makemask(smask, count), count);
269 }
270 gethooktable(L1);
271 lua_pushlightuserdata(L1, L1);
272 lua_pushvalue(L, arg+1);
273 lua_xmove(L, L1, 1);
274 lua_rawset(L1, -3); /* set new hook */
275 lua_pop(L1, 1); /* remove hook table */
276 return 0;
277}
278
279
280static int db_gethook (lua_State *L) {
281 int arg;
282 lua_State *L1 = getthread(L, &arg);
283 char buff[5];
284 int mask = lua_gethookmask(L1);
285 lua_Hook hook = lua_gethook(L1);
286 if (hook != NULL && hook != hookf) /* external hook? */
287 lua_pushliteral(L, "external hook");
288 else {
289 gethooktable(L1);
290 lua_pushlightuserdata(L1, L1);
291 lua_rawget(L1, -2); /* get hook */
292 lua_remove(L1, -2); /* remove hook table */
293 lua_xmove(L1, L, 1);
294 }
295 lua_pushstring(L, unmakemask(mask, buff));
296 lua_pushinteger(L, lua_gethookcount(L1));
297 return 3;
298}
299
300
301static int db_debug (lua_State *L) {
302 for (;;) {
303 char buffer[250];
304 fputs("lua_debug> ", stderr);
305 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
306 strcmp(buffer, "cont\n") == 0)
307 return 0;
308 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
309 lua_pcall(L, 0, 0, 0)) {
310 fputs(lua_tostring(L, -1), stderr);
311 fputs("\n", stderr);
312 }
313 lua_settop(L, 0); /* remove eventual returns */
314 }
315}
316
317
318#define LEVELS1 12 /* size of the first part of the stack */
319#define LEVELS2 10 /* size of the second part of the stack */
320
321static int db_errorfb (lua_State *L) {
322 int level;
323 int firstpart = 1; /* still before eventual `...' */
324 int arg;
325 lua_State *L1 = getthread(L, &arg);
326 lua_Debug ar;
327 if (lua_isnumber(L, arg+2)) {
328 level = (int)lua_tointeger(L, arg+2);
329 lua_pop(L, 1);
330 }
331 else
332 level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
333 if (lua_gettop(L) == arg)
334 lua_pushliteral(L, "");
335 else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
336 else lua_pushliteral(L, "\n");
337 lua_pushliteral(L, "stack traceback:");
338 while (lua_getstack(L1, level++, &ar)) {
339 if (level > LEVELS1 && firstpart) {
340 /* no more than `LEVELS2' more levels? */
341 if (!lua_getstack(L1, level+LEVELS2, &ar))
342 level--; /* keep going */
343 else {
344 lua_pushliteral(L, "\n\t..."); /* too many levels */
345 while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
346 level++;
347 }
348 firstpart = 0;
349 continue;
350 }
351 lua_pushliteral(L, "\n\t");
352 lua_getinfo(L1, "Snl", &ar);
353 lua_pushfstring(L, "%s:", ar.short_src);
354 if (ar.currentline > 0)
355 lua_pushfstring(L, "%d:", ar.currentline);
356 if (*ar.namewhat != '\0') /* is there a name? */
357 lua_pushfstring(L, " in function " LUA_QS, ar.name);
358 else {
359 if (*ar.what == 'm') /* main? */
360 lua_pushfstring(L, " in main chunk");
361 else if (*ar.what == 'C' || *ar.what == 't')
362 lua_pushliteral(L, " ?"); /* C function or tail call */
363 else
364 lua_pushfstring(L, " in function <%s:%d>",
365 ar.short_src, ar.linedefined);
366 }
367 lua_concat(L, lua_gettop(L) - arg);
368 }
369 lua_concat(L, lua_gettop(L) - arg);
370 return 1;
371}
372
373
374static const luaL_Reg dblib[] = {
375 {"debug", db_debug},
376 {"getfenv", db_getfenv},
377 {"gethook", db_gethook},
378 {"getinfo", db_getinfo},
379 {"getlocal", db_getlocal},
380 {"getregistry", db_getregistry},
381 {"getmetatable", db_getmetatable},
382 {"getupvalue", db_getupvalue},
383 {"setfenv", db_setfenv},
384 {"sethook", db_sethook},
385 {"setlocal", db_setlocal},
386 {"setmetatable", db_setmetatable},
387 {"setupvalue", db_setupvalue},
388 {"traceback", db_errorfb},
389 {NULL, NULL}
390};
391
392
393LUALIB_API int luaopen_debug (lua_State *L) {
394 luaL_register(L, LUA_DBLIBNAME, dblib);
395 return 1;
396}
397
diff --git a/ldebug.c b/ldebug.c
deleted file mode 100644
index 4fa42ac9..00000000
--- a/ldebug.c
+++ /dev/null
@@ -1,620 +0,0 @@
1/*
2** $Id: ldebug.c,v 2.28 2005/11/01 16:08:52 roberto Exp roberto $
3** Debug Interface
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdarg.h>
9#include <stddef.h>
10#include <string.h>
11
12
13#define ldebug_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "lcode.h"
20#include "ldebug.h"
21#include "ldo.h"
22#include "lfunc.h"
23#include "lobject.h"
24#include "lopcodes.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lvm.h"
30
31
32
33static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
34
35
36static int currentpc (lua_State *L, CallInfo *ci) {
37 if (!isLua(ci)) return -1; /* function is not a Lua function? */
38 if (ci == L->ci)
39 ci->savedpc = L->savedpc;
40 return pcRel(ci->savedpc, ci_func(ci)->l.p);
41}
42
43
44static int currentline (lua_State *L, CallInfo *ci) {
45 int pc = currentpc(L, ci);
46 if (pc < 0)
47 return -1; /* only active lua functions have current-line information */
48 else
49 return getline(ci_func(ci)->l.p, pc);
50}
51
52
53/*
54** this function can be called asynchronous (e.g. during a signal)
55*/
56LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
57 if (func == NULL || mask == 0) { /* turn off hooks? */
58 mask = 0;
59 func = NULL;
60 }
61 L->hook = func;
62 L->basehookcount = count;
63 resethookcount(L);
64 L->hookmask = cast_byte(mask);
65 return 1;
66}
67
68
69LUA_API lua_Hook lua_gethook (lua_State *L) {
70 return L->hook;
71}
72
73
74LUA_API int lua_gethookmask (lua_State *L) {
75 return L->hookmask;
76}
77
78
79LUA_API int lua_gethookcount (lua_State *L) {
80 return L->basehookcount;
81}
82
83
84LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
85 int status;
86 CallInfo *ci;
87 lua_lock(L);
88 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
89 level--;
90 if (f_isLua(ci)) /* Lua function? */
91 level -= ci->tailcalls; /* skip lost tail calls */
92 }
93 if (level == 0 && ci > L->base_ci) { /* level found? */
94 status = 1;
95 ar->i_ci = cast_int(ci - L->base_ci);
96 }
97 else if (level < 0) { /* level is of a lost tail call? */
98 status = 1;
99 ar->i_ci = 0;
100 }
101 else status = 0; /* no such level */
102 lua_unlock(L);
103 return status;
104}
105
106
107static Proto *getluaproto (CallInfo *ci) {
108 return (isLua(ci) ? ci_func(ci)->l.p : NULL);
109}
110
111
112static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
113 const char *name;
114 Proto *fp = getluaproto(ci);
115 if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
116 return name; /* is a local variable in a Lua function */
117 else {
118 StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
119 if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
120 return "(*temporary)";
121 else
122 return NULL;
123 }
124}
125
126
127LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
128 CallInfo *ci = L->base_ci + ar->i_ci;
129 const char *name = findlocal(L, ci, n);
130 lua_lock(L);
131 if (name)
132 luaA_pushobject(L, ci->base + (n - 1));
133 lua_unlock(L);
134 return name;
135}
136
137
138LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
139 CallInfo *ci = L->base_ci + ar->i_ci;
140 const char *name = findlocal(L, ci, n);
141 lua_lock(L);
142 if (name)
143 setobjs2s(L, ci->base + (n - 1), L->top - 1);
144 L->top--; /* pop value */
145 lua_unlock(L);
146 return name;
147}
148
149
150static void funcinfo (lua_Debug *ar, Closure *cl) {
151 if (cl->c.isC) {
152 ar->source = "=[C]";
153 ar->linedefined = -1;
154 ar->lastlinedefined = -1;
155 ar->what = "C";
156 }
157 else {
158 ar->source = getstr(cl->l.p->source);
159 ar->linedefined = cl->l.p->linedefined;
160 ar->lastlinedefined = cl->l.p->lastlinedefined;
161 ar->what = (ar->linedefined == 0) ? "main" : "Lua";
162 }
163 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
164}
165
166
167static void info_tailcall (lua_Debug *ar) {
168 ar->name = ar->namewhat = "";
169 ar->what = "tail";
170 ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
171 ar->source = "=(tail call)";
172 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
173 ar->nups = 0;
174}
175
176
177static void collectvalidlines (lua_State *L, Closure *f) {
178 if (f == NULL || f->c.isC) {
179 setnilvalue(L->top);
180 }
181 else {
182 Table *t = luaH_new(L, 0, 0);
183 int *lineinfo = f->l.p->lineinfo;
184 int i;
185 for (i=0; i<f->l.p->sizelineinfo; i++)
186 setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
187 sethvalue(L, L->top, t);
188 }
189 incr_top(L);
190}
191
192
193static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
194 Closure *f, CallInfo *ci) {
195 int status = 1;
196 if (f == NULL) {
197 info_tailcall(ar);
198 return status;
199 }
200 for (; *what; what++) {
201 switch (*what) {
202 case 'S': {
203 funcinfo(ar, f);
204 break;
205 }
206 case 'l': {
207 ar->currentline = (ci) ? currentline(L, ci) : -1;
208 break;
209 }
210 case 'u': {
211 ar->nups = f->c.nupvalues;
212 break;
213 }
214 case 'n': {
215 ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
216 if (ar->namewhat == NULL) {
217 ar->namewhat = ""; /* not found */
218 ar->name = NULL;
219 }
220 break;
221 }
222 case 'L':
223 case 'f': /* handled by lua_getinfo */
224 break;
225 default: status = 0; /* invalid option */
226 }
227 }
228 return status;
229}
230
231
232LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
233 int status;
234 Closure *f = NULL;
235 CallInfo *ci = NULL;
236 lua_lock(L);
237 if (*what == '>') {
238 StkId func = L->top - 1;
239 luai_apicheck(L, ttisfunction(func));
240 what++; /* skip the '>' */
241 f = clvalue(func);
242 L->top--; /* pop function */
243 }
244 else if (ar->i_ci != 0) { /* no tail call? */
245 ci = L->base_ci + ar->i_ci;
246 lua_assert(ttisfunction(ci->func));
247 f = clvalue(ci->func);
248 }
249 status = auxgetinfo(L, what, ar, f, ci);
250 if (strchr(what, 'f')) {
251 if (f == NULL) setnilvalue(L->top);
252 else setclvalue(L, L->top, f);
253 incr_top(L);
254 }
255 if (strchr(what, 'L'))
256 collectvalidlines(L, f);
257 lua_unlock(L);
258 return status;
259}
260
261
262/*
263** {======================================================
264** Symbolic Execution and code checker
265** =======================================================
266*/
267
268#define check(x) if (!(x)) return 0;
269
270#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
271
272#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
273
274
275
276static int precheck (const Proto *pt) {
277 check(pt->maxstacksize <= MAXSTACK);
278 lua_assert(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
279 lua_assert(!(pt->is_vararg & VARARG_NEEDSARG) ||
280 (pt->is_vararg & VARARG_HASARG));
281 check(pt->sizeupvalues <= pt->nups);
282 check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
283 check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
284 return 1;
285}
286
287
288#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
289
290int luaG_checkopenop (Instruction i) {
291 switch (GET_OPCODE(i)) {
292 case OP_CALL:
293 case OP_TAILCALL:
294 case OP_RETURN:
295 case OP_SETLIST: {
296 check(GETARG_B(i) == 0);
297 return 1;
298 }
299 default: return 0; /* invalid instruction after an open call */
300 }
301}
302
303
304static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
305 switch (mode) {
306 case OpArgN: check(r == 0); break;
307 case OpArgU: break;
308 case OpArgR: checkreg(pt, r); break;
309 case OpArgK:
310 check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
311 break;
312 }
313 return 1;
314}
315
316
317static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
318 int pc;
319 int last; /* stores position of last instruction that changed `reg' */
320 last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
321 check(precheck(pt));
322 for (pc = 0; pc < lastpc; pc++) {
323 Instruction i = pt->code[pc];
324 OpCode op = GET_OPCODE(i);
325 int a = GETARG_A(i);
326 int b = 0;
327 int c = 0;
328 check(op < NUM_OPCODES);
329 checkreg(pt, a);
330 switch (getOpMode(op)) {
331 case iABC: {
332 b = GETARG_B(i);
333 c = GETARG_C(i);
334 check(checkArgMode(pt, b, getBMode(op)));
335 check(checkArgMode(pt, c, getCMode(op)));
336 break;
337 }
338 case iABx: {
339 b = GETARG_Bx(i);
340 if (getBMode(op) == OpArgK) check(b < pt->sizek);
341 break;
342 }
343 case iAsBx: {
344 b = GETARG_sBx(i);
345 if (getBMode(op) == OpArgR) {
346 int dest = pc+1+b;
347 check(0 <= dest && dest < pt->sizecode);
348 if (dest > 0) {
349 /* cannot jump to a setlist count */
350 Instruction d = pt->code[dest-1];
351 check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0));
352 }
353 }
354 break;
355 }
356 }
357 if (testAMode(op)) {
358 if (a == reg) last = pc; /* change register `a' */
359 }
360 if (testTMode(op)) {
361 check(pc+2 < pt->sizecode); /* check skip */
362 check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
363 }
364 switch (op) {
365 case OP_LOADBOOL: {
366 check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
367 break;
368 }
369 case OP_LOADNIL: {
370 if (a <= reg && reg <= b)
371 last = pc; /* set registers from `a' to `b' */
372 break;
373 }
374 case OP_GETUPVAL:
375 case OP_SETUPVAL: {
376 check(b < pt->nups);
377 break;
378 }
379 case OP_GETGLOBAL:
380 case OP_SETGLOBAL: {
381 check(ttisstring(&pt->k[b]));
382 break;
383 }
384 case OP_SELF: {
385 checkreg(pt, a+1);
386 if (reg == a+1) last = pc;
387 break;
388 }
389 case OP_CONCAT: {
390 check(b < c); /* at least two operands */
391 break;
392 }
393 case OP_TFORLOOP: {
394 check(c >= 1); /* at least one result (control variable) */
395 checkreg(pt, a+2+c); /* space for results */
396 if (reg >= a+2) last = pc; /* affect all regs above its base */
397 break;
398 }
399 case OP_FORLOOP:
400 case OP_FORPREP:
401 checkreg(pt, a+3);
402 /* go through */
403 case OP_JMP: {
404 int dest = pc+1+b;
405 /* not full check and jump is forward and do not skip `lastpc'? */
406 if (reg != NO_REG && pc < dest && dest <= lastpc)
407 pc += b; /* do the jump */
408 break;
409 }
410 case OP_CALL:
411 case OP_TAILCALL: {
412 if (b != 0) {
413 checkreg(pt, a+b-1);
414 }
415 c--; /* c = num. returns */
416 if (c == LUA_MULTRET) {
417 check(checkopenop(pt, pc));
418 }
419 else if (c != 0)
420 checkreg(pt, a+c-1);
421 if (reg >= a) last = pc; /* affect all registers above base */
422 break;
423 }
424 case OP_RETURN: {
425 b--; /* b = num. returns */
426 if (b > 0) checkreg(pt, a+b-1);
427 break;
428 }
429 case OP_SETLIST: {
430 if (b > 0) checkreg(pt, a + b);
431 if (c == 0) pc++;
432 break;
433 }
434 case OP_CLOSURE: {
435 int nup;
436 check(b < pt->sizep);
437 nup = pt->p[b]->nups;
438 check(pc + nup < pt->sizecode);
439 for (; nup>0; nup--) {
440 OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
441 check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
442 }
443 break;
444 }
445 case OP_VARARG: {
446 check((pt->is_vararg & VARARG_ISVARARG) &&
447 !(pt->is_vararg & VARARG_NEEDSARG));
448 b--;
449 if (b == LUA_MULTRET) check(checkopenop(pt, pc));
450 checkreg(pt, a+b-1);
451 break;
452 }
453 default: break;
454 }
455 }
456 return pt->code[last];
457}
458
459#undef check
460#undef checkjump
461#undef checkreg
462
463/* }====================================================== */
464
465
466int luaG_checkcode (const Proto *pt) {
467 return (symbexec(pt, pt->sizecode, NO_REG) != 0);
468}
469
470
471static const char *kname (Proto *p, int c) {
472 if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
473 return svalue(&p->k[INDEXK(c)]);
474 else
475 return "?";
476}
477
478
479static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
480 const char **name) {
481 if (isLua(ci)) { /* a Lua function? */
482 Proto *p = ci_func(ci)->l.p;
483 int pc = currentpc(L, ci);
484 Instruction i;
485 *name = luaF_getlocalname(p, stackpos+1, pc);
486 if (*name) /* is a local? */
487 return "local";
488 i = symbexec(p, pc, stackpos); /* try symbolic execution */
489 lua_assert(pc != -1);
490 switch (GET_OPCODE(i)) {
491 case OP_GETGLOBAL: {
492 int g = GETARG_Bx(i); /* global index */
493 lua_assert(ttisstring(&p->k[g]));
494 *name = svalue(&p->k[g]);
495 return "global";
496 }
497 case OP_MOVE: {
498 int a = GETARG_A(i);
499 int b = GETARG_B(i); /* move from `b' to `a' */
500 if (b < a)
501 return getobjname(L, ci, b, name); /* get name for `b' */
502 break;
503 }
504 case OP_GETTABLE: {
505 int k = GETARG_C(i); /* key index */
506 *name = kname(p, k);
507 return "field";
508 }
509 case OP_GETUPVAL: {
510 int u = GETARG_B(i); /* upvalue index */
511 *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
512 return "upvalue";
513 }
514 case OP_SELF: {
515 int k = GETARG_C(i); /* key index */
516 *name = kname(p, k);
517 return "method";
518 }
519 default: break;
520 }
521 }
522 return NULL; /* no useful name found */
523}
524
525
526static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
527 Instruction i;
528 if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
529 return NULL; /* calling function is not Lua (or is unknown) */
530 ci--; /* calling function */
531 i = ci_func(ci)->l.p->code[currentpc(L, ci)];
532 if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
533 GET_OPCODE(i) == OP_TFORLOOP)
534 return getobjname(L, ci, GETARG_A(i), name);
535 else
536 return NULL; /* no useful name can be found */
537}
538
539
540/* only ANSI way to check whether a pointer points to an array */
541static int isinstack (CallInfo *ci, const TValue *o) {
542 StkId p;
543 for (p = ci->base; p < ci->top; p++)
544 if (o == p) return 1;
545 return 0;
546}
547
548
549void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
550 const char *name = NULL;
551 const char *t = luaT_typenames[ttype(o)];
552 const char *kind = (isinstack(L->ci, o)) ?
553 getobjname(L, L->ci, cast_int(o - L->base), &name) :
554 NULL;
555 if (kind)
556 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
557 op, kind, name, t);
558 else
559 luaG_runerror(L, "attempt to %s a %s value", op, t);
560}
561
562
563void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
564 if (ttisstring(p1)) p1 = p2;
565 lua_assert(!ttisstring(p1));
566 luaG_typeerror(L, p1, "concatenate");
567}
568
569
570void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
571 TValue temp;
572 if (luaV_tonumber(p1, &temp) == NULL)
573 p2 = p1; /* first operand is wrong */
574 luaG_typeerror(L, p2, "perform arithmetic on");
575}
576
577
578int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
579 const char *t1 = luaT_typenames[ttype(p1)];
580 const char *t2 = luaT_typenames[ttype(p2)];
581 if (t1[2] == t2[2])
582 luaG_runerror(L, "attempt to compare two %s values", t1);
583 else
584 luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
585 return 0;
586}
587
588
589static void addinfo (lua_State *L, const char *msg) {
590 CallInfo *ci = L->ci;
591 if (isLua(ci)) { /* is Lua code? */
592 char buff[LUA_IDSIZE]; /* add file:line information */
593 int line = currentline(L, ci);
594 luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
595 luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
596 }
597}
598
599
600void luaG_errormsg (lua_State *L) {
601 if (L->errfunc != 0) { /* is there an error handling function? */
602 StkId errfunc = restorestack(L, L->errfunc);
603 if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
604 setobjs2s(L, L->top, L->top - 1); /* move argument */
605 setobjs2s(L, L->top - 1, errfunc); /* push function */
606 incr_top(L);
607 luaD_call(L, L->top - 2, 1); /* call it */
608 }
609 luaD_throw(L, LUA_ERRRUN);
610}
611
612
613void luaG_runerror (lua_State *L, const char *fmt, ...) {
614 va_list argp;
615 va_start(argp, fmt);
616 addinfo(L, luaO_pushvfstring(L, fmt, argp));
617 va_end(argp);
618 luaG_errormsg(L);
619}
620
diff --git a/ldebug.h b/ldebug.h
deleted file mode 100644
index fcb0b901..00000000
--- a/ldebug.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2** $Id: ldebug.h,v 2.2 2004/06/02 19:07:55 roberto Exp roberto $
3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldebug_h
8#define ldebug_h
9
10
11#include "lstate.h"
12
13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15
16#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
17
18#define resethookcount(L) (L->hookcount = L->basehookcount)
19
20
21LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
22 const char *opname);
23LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
24LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
25 const TValue *p2);
26LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
27 const TValue *p2);
28LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
29LUAI_FUNC void luaG_errormsg (lua_State *L);
30LUAI_FUNC int luaG_checkcode (const Proto *pt);
31LUAI_FUNC int luaG_checkopenop (Instruction i);
32
33#endif
diff --git a/ldo.c b/ldo.c
deleted file mode 100644
index d7a587e9..00000000
--- a/ldo.c
+++ /dev/null
@@ -1,516 +0,0 @@
1/*
2** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <setjmp.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define ldo_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lgc.h"
21#include "lmem.h"
22#include "lobject.h"
23#include "lopcodes.h"
24#include "lparser.h"
25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h"
28#include "ltm.h"
29#include "lundump.h"
30#include "lvm.h"
31#include "lzio.h"
32
33
34
35
36/*
37** {======================================================
38** Error-recovery functions
39** =======================================================
40*/
41
42
43/* chain list of long jump buffers */
44struct lua_longjmp {
45 struct lua_longjmp *previous;
46 luai_jmpbuf b;
47 volatile int status; /* error code */
48};
49
50
51void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
52 switch (errcode) {
53 case LUA_ERRMEM: {
54 setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
55 break;
56 }
57 case LUA_ERRERR: {
58 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
59 break;
60 }
61 case LUA_ERRSYNTAX:
62 case LUA_ERRRUN: {
63 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
64 break;
65 }
66 }
67 L->top = oldtop + 1;
68}
69
70
71static void restore_stack_limit (lua_State *L) {
72 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
73 if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
74 int inuse = cast_int(L->ci - L->base_ci);
75 if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
76 luaD_reallocCI(L, LUAI_MAXCALLS);
77 }
78}
79
80
81static void resetstack (lua_State *L, int status) {
82 L->ci = L->base_ci;
83 L->base = L->ci->base;
84 luaF_close(L, L->base); /* close eventual pending closures */
85 luaD_seterrorobj(L, status, L->base);
86 L->nCcalls = 0;
87 L->allowhook = 1;
88 restore_stack_limit(L);
89 L->errfunc = 0;
90 L->errorJmp = NULL;
91}
92
93
94void luaD_throw (lua_State *L, int errcode) {
95 if (L->errorJmp) {
96 L->errorJmp->status = errcode;
97 LUAI_THROW(L, L->errorJmp);
98 }
99 else {
100 L->status = cast_byte(errcode);
101 if (G(L)->panic) {
102 resetstack(L, errcode);
103 lua_unlock(L);
104 G(L)->panic(L);
105 }
106 exit(EXIT_FAILURE);
107 }
108}
109
110
111int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
112 struct lua_longjmp lj;
113 lj.status = 0;
114 lj.previous = L->errorJmp; /* chain new error handler */
115 L->errorJmp = &lj;
116 LUAI_TRY(L, &lj,
117 (*f)(L, ud);
118 );
119 L->errorJmp = lj.previous; /* restore old error handler */
120 return lj.status;
121}
122
123/* }====================================================== */
124
125
126static void correctstack (lua_State *L, TValue *oldstack) {
127 CallInfo *ci;
128 GCObject *up;
129 L->top = (L->top - oldstack) + L->stack;
130 for (up = L->openupval; up != NULL; up = up->gch.next)
131 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
132 for (ci = L->base_ci; ci <= L->ci; ci++) {
133 ci->top = (ci->top - oldstack) + L->stack;
134 ci->base = (ci->base - oldstack) + L->stack;
135 ci->func = (ci->func - oldstack) + L->stack;
136 }
137 L->base = (L->base - oldstack) + L->stack;
138}
139
140
141void luaD_reallocstack (lua_State *L, int newsize) {
142 TValue *oldstack = L->stack;
143 int realsize = newsize + 1 + EXTRA_STACK;
144 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
145 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
146 L->stacksize = realsize;
147 L->stack_last = L->stack+newsize;
148 correctstack(L, oldstack);
149}
150
151
152void luaD_reallocCI (lua_State *L, int newsize) {
153 CallInfo *oldci = L->base_ci;
154 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
155 L->size_ci = newsize;
156 L->ci = (L->ci - oldci) + L->base_ci;
157 L->end_ci = L->base_ci + L->size_ci - 1;
158}
159
160
161void luaD_growstack (lua_State *L, int n) {
162 if (n <= L->stacksize) /* double size is enough? */
163 luaD_reallocstack(L, 2*L->stacksize);
164 else
165 luaD_reallocstack(L, L->stacksize + n);
166}
167
168
169static CallInfo *growCI (lua_State *L) {
170 if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
171 luaD_throw(L, LUA_ERRERR);
172 else {
173 luaD_reallocCI(L, 2*L->size_ci);
174 if (L->size_ci > LUAI_MAXCALLS)
175 luaG_runerror(L, "stack overflow");
176 }
177 return ++L->ci;
178}
179
180
181void luaD_callhook (lua_State *L, int event, int line) {
182 lua_Hook hook = L->hook;
183 if (hook && L->allowhook) {
184 ptrdiff_t top = savestack(L, L->top);
185 ptrdiff_t ci_top = savestack(L, L->ci->top);
186 lua_Debug ar;
187 ar.event = event;
188 ar.currentline = line;
189 if (event == LUA_HOOKTAILRET)
190 ar.i_ci = 0; /* tail call; no debug information about it */
191 else
192 ar.i_ci = cast_int(L->ci - L->base_ci);
193 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
194 L->ci->top = L->top + LUA_MINSTACK;
195 lua_assert(L->ci->top <= L->stack_last);
196 L->allowhook = 0; /* cannot call hooks inside a hook */
197 lua_unlock(L);
198 (*hook)(L, &ar);
199 lua_lock(L);
200 lua_assert(!L->allowhook);
201 L->allowhook = 1;
202 L->ci->top = restorestack(L, ci_top);
203 L->top = restorestack(L, top);
204 }
205}
206
207
208static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
209 int i;
210 int nfixargs = p->numparams;
211 Table *htab = NULL;
212 StkId base, fixed;
213 for (; actual < nfixargs; ++actual)
214 setnilvalue(L->top++);
215#if defined(LUA_COMPAT_VARARG)
216 if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
217 int nvar = actual - nfixargs; /* number of extra arguments */
218 lua_assert(p->is_vararg & VARARG_HASARG);
219 luaC_checkGC(L);
220 htab = luaH_new(L, nvar, 1); /* create `arg' table */
221 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
222 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
223 /* store counter in field `n' */
224 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
225 }
226#endif
227 /* move fixed parameters to final position */
228 fixed = L->top - actual; /* first fixed argument */
229 base = L->top; /* final position of first argument */
230 for (i=0; i<nfixargs; i++) {
231 setobjs2s(L, L->top++, fixed+i);
232 setnilvalue(fixed+i);
233 }
234 /* add `arg' parameter */
235 if (htab) {
236 sethvalue(L, L->top++, htab);
237 lua_assert(iswhite(obj2gco(htab)));
238 }
239 return base;
240}
241
242
243static StkId tryfuncTM (lua_State *L, StkId func) {
244 const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
245 StkId p;
246 ptrdiff_t funcr = savestack(L, func);
247 if (!ttisfunction(tm))
248 luaG_typeerror(L, func, "call");
249 /* Open a hole inside the stack at `func' */
250 for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
251 incr_top(L);
252 func = restorestack(L, funcr); /* previous call may change stack */
253 setobj2s(L, func, tm); /* tag method is the new function to be called */
254 return func;
255}
256
257
258
259#define inc_ci(L) \
260 ((L->ci == L->end_ci) ? growCI(L) : \
261 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
262
263
264int luaD_precall (lua_State *L, StkId func, int nresults) {
265 LClosure *cl;
266 ptrdiff_t funcr;
267 if (!ttisfunction(func)) /* `func' is not a function? */
268 func = tryfuncTM(L, func); /* check the `function' tag method */
269 funcr = savestack(L, func);
270 cl = &clvalue(func)->l;
271 L->ci->savedpc = L->savedpc;
272 if (!cl->isC) { /* Lua function? prepare its call */
273 CallInfo *ci;
274 StkId st, base;
275 Proto *p = cl->p;
276 luaD_checkstack(L, p->maxstacksize);
277 func = restorestack(L, funcr);
278 if (!p->is_vararg) { /* no varargs? */
279 base = func + 1;
280 if (L->top > base + p->numparams)
281 L->top = base + p->numparams;
282 }
283 else { /* vararg function */
284 int nargs = cast_int(L->top - func) - 1;
285 base = adjust_varargs(L, p, nargs);
286 func = restorestack(L, funcr); /* previous call may change the stack */
287 }
288 ci = inc_ci(L); /* now `enter' new function */
289 ci->func = func;
290 L->base = ci->base = base;
291 ci->top = L->base + p->maxstacksize;
292 lua_assert(ci->top <= L->stack_last);
293 L->savedpc = p->code; /* starting point */
294 ci->tailcalls = 0;
295 ci->nresults = nresults;
296 for (st = L->top; st < ci->top; st++)
297 setnilvalue(st);
298 L->top = ci->top;
299 if (L->hookmask & LUA_MASKCALL) {
300 L->savedpc++; /* hooks assume 'pc' is already incremented */
301 luaD_callhook(L, LUA_HOOKCALL, -1);
302 L->savedpc--; /* correct 'pc' */
303 }
304 return PCRLUA;
305 }
306 else { /* if is a C function, call it */
307 CallInfo *ci;
308 int n;
309 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
310 ci = inc_ci(L); /* now `enter' new function */
311 ci->func = restorestack(L, funcr);
312 L->base = ci->base = ci->func + 1;
313 ci->top = L->top + LUA_MINSTACK;
314 lua_assert(ci->top <= L->stack_last);
315 ci->nresults = nresults;
316 if (L->hookmask & LUA_MASKCALL)
317 luaD_callhook(L, LUA_HOOKCALL, -1);
318 lua_unlock(L);
319 n = (*curr_func(L)->c.f)(L); /* do the actual call */
320 lua_lock(L);
321 if (n < 0) /* yielding? */
322 return PCRYIELD;
323 else {
324 luaD_poscall(L, L->top - n);
325 return PCRC;
326 }
327 }
328}
329
330
331static StkId callrethooks (lua_State *L, StkId firstResult) {
332 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
333 luaD_callhook(L, LUA_HOOKRET, -1);
334 if (f_isLua(L->ci)) { /* Lua function? */
335 while (L->ci->tailcalls--) /* call hook for eventual tail calls */
336 luaD_callhook(L, LUA_HOOKTAILRET, -1);
337 }
338 return restorestack(L, fr);
339}
340
341
342int luaD_poscall (lua_State *L, StkId firstResult) {
343 StkId res;
344 int wanted, i;
345 CallInfo *ci;
346 if (L->hookmask & LUA_MASKRET)
347 firstResult = callrethooks(L, firstResult);
348 ci = L->ci--;
349 res = ci->func; /* res == final position of 1st result */
350 wanted = ci->nresults;
351 L->base = (ci - 1)->base; /* restore base */
352 L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
353 /* move results to correct place */
354 for (i = wanted; i != 0 && firstResult < L->top; i--)
355 setobjs2s(L, res++, firstResult++);
356 while (i-- > 0)
357 setnilvalue(res++);
358 L->top = res;
359 return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
360}
361
362
363/*
364** Call a function (C or Lua). The function to be called is at *func.
365** The arguments are on the stack, right after the function.
366** When returns, all the results are on the stack, starting at the original
367** function position.
368*/
369void luaD_call (lua_State *L, StkId func, int nResults) {
370 if (++L->nCcalls >= LUAI_MAXCCALLS) {
371 if (L->nCcalls == LUAI_MAXCCALLS)
372 luaG_runerror(L, "C stack overflow");
373 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
374 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
375 }
376 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
377 luaV_execute(L, 1); /* call it */
378 L->nCcalls--;
379 luaC_checkGC(L);
380}
381
382
383static void resume (lua_State *L, void *ud) {
384 StkId firstArg = cast(StkId, ud);
385 CallInfo *ci = L->ci;
386 if (L->status == 0) { /* start coroutine? */
387 lua_assert(ci == L->base_ci && firstArg > L->base);
388 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
389 return;
390 }
391 else { /* resuming from previous yield */
392 lua_assert(L->status == LUA_YIELD);
393 L->status = 0;
394 if (!f_isLua(ci)) { /* `common' yield? */
395 /* finish interrupted execution of `OP_CALL' */
396 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
397 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
398 if (luaD_poscall(L, firstArg)) /* complete it... */
399 L->top = L->ci->top; /* and correct top if not multiple results */
400 }
401 else /* yielded inside a hook: just continue its execution */
402 L->base = L->ci->base;
403 }
404 luaV_execute(L, cast_int(L->ci - L->base_ci));
405}
406
407
408static int resume_error (lua_State *L, const char *msg) {
409 L->top = L->ci->base;
410 setsvalue2s(L, L->top, luaS_new(L, msg));
411 incr_top(L);
412 lua_unlock(L);
413 return LUA_ERRRUN;
414}
415
416
417LUA_API int lua_resume (lua_State *L, int nargs) {
418 int status;
419 lua_lock(L);
420 if (L->status != LUA_YIELD) {
421 if (L->status != 0)
422 return resume_error(L, "cannot resume dead coroutine");
423 else if (L->ci != L->base_ci)
424 return resume_error(L, "cannot resume non-suspended coroutine");
425 }
426 luai_userstateresume(L, nargs);
427 lua_assert(L->errfunc == 0 && L->nCcalls == 0);
428 status = luaD_rawrunprotected(L, resume, L->top - nargs);
429 if (status != 0) { /* error? */
430 L->status = cast_byte(status); /* mark thread as `dead' */
431 luaD_seterrorobj(L, status, L->top);
432 L->ci->top = L->top;
433 }
434 else
435 status = L->status;
436 lua_unlock(L);
437 return status;
438}
439
440
441LUA_API int lua_yield (lua_State *L, int nresults) {
442 luai_userstateyield(L, nresults);
443 lua_lock(L);
444 if (L->nCcalls > 0)
445 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
446 L->base = L->top - nresults; /* protect stack slots below */
447 L->status = LUA_YIELD;
448 lua_unlock(L);
449 return -1;
450}
451
452
453int luaD_pcall (lua_State *L, Pfunc func, void *u,
454 ptrdiff_t old_top, ptrdiff_t ef) {
455 int status;
456 unsigned short oldnCcalls = L->nCcalls;
457 ptrdiff_t old_ci = saveci(L, L->ci);
458 lu_byte old_allowhooks = L->allowhook;
459 ptrdiff_t old_errfunc = L->errfunc;
460 L->errfunc = ef;
461 status = luaD_rawrunprotected(L, func, u);
462 if (status != 0) { /* an error occurred? */
463 StkId oldtop = restorestack(L, old_top);
464 luaF_close(L, oldtop); /* close eventual pending closures */
465 luaD_seterrorobj(L, status, oldtop);
466 L->nCcalls = oldnCcalls;
467 L->ci = restoreci(L, old_ci);
468 L->base = L->ci->base;
469 L->savedpc = L->ci->savedpc;
470 L->allowhook = old_allowhooks;
471 restore_stack_limit(L);
472 }
473 L->errfunc = old_errfunc;
474 return status;
475}
476
477
478
479/*
480** Execute a protected parser.
481*/
482struct SParser { /* data to `f_parser' */
483 ZIO *z;
484 Mbuffer buff; /* buffer to be used by the scanner */
485 const char *name;
486};
487
488static void f_parser (lua_State *L, void *ud) {
489 int i;
490 Proto *tf;
491 Closure *cl;
492 struct SParser *p = cast(struct SParser *, ud);
493 int c = luaZ_lookahead(p->z);
494 luaC_checkGC(L);
495 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
496 &p->buff, p->name);
497 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
498 cl->l.p = tf;
499 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
500 cl->l.upvals[i] = luaF_newupval(L);
501 setclvalue(L, L->top, cl);
502 incr_top(L);
503}
504
505
506int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
507 struct SParser p;
508 int status;
509 p.z = z; p.name = name;
510 luaZ_initbuffer(L, &p.buff);
511 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
512 luaZ_freebuffer(L, &p.buff);
513 return status;
514}
515
516
diff --git a/ldo.h b/ldo.h
deleted file mode 100644
index 5aa65480..00000000
--- a/ldo.h
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2** $Id: ldo.h,v 2.6 2005/08/22 19:58:29 roberto Exp roberto $
3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ldo_h
8#define ldo_h
9
10
11#include "lobject.h"
12#include "lstate.h"
13#include "lzio.h"
14
15
16#define luaD_checkstack(L,n) \
17 if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
18 luaD_growstack(L, n); \
19 else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
20
21
22#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
23
24#define savestack(L,p) ((char *)(p) - (char *)L->stack)
25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
26
27#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
28#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
29
30
31/* results from luaD_precall */
32#define PCRLUA 0 /* initiated a call to a Lua function */
33#define PCRC 1 /* did a call to a C function */
34#define PCRYIELD 2 /* C funtion yielded */
35
36
37/* type of protected functions, to be ran by `runprotected' */
38typedef void (*Pfunc) (lua_State *L, void *ud);
39
40LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
41LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
42LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
43LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
44LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
45 ptrdiff_t oldtop, ptrdiff_t ef);
46LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
47LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
48LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
49LUAI_FUNC void luaD_growstack (lua_State *L, int n);
50
51LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
52LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
53
54LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
55
56#endif
57
diff --git a/ldump.c b/ldump.c
deleted file mode 100644
index f08277d3..00000000
--- a/ldump.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2** $Id: ldump.c,v 1.15 2006/02/16 15:53:49 lhf Exp $
3** save precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#include <stddef.h>
8
9#define ldump_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "lobject.h"
15#include "lstate.h"
16#include "lundump.h"
17
18typedef struct {
19 lua_State* L;
20 lua_Writer writer;
21 void* data;
22 int strip;
23 int status;
24} DumpState;
25
26#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
27#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
28
29static void DumpBlock(const void* b, size_t size, DumpState* D)
30{
31 if (D->status==0)
32 {
33 lua_unlock(D->L);
34 D->status=(*D->writer)(D->L,b,size,D->data);
35 lua_lock(D->L);
36 }
37}
38
39static void DumpChar(int y, DumpState* D)
40{
41 char x=(char)y;
42 DumpVar(x,D);
43}
44
45static void DumpInt(int x, DumpState* D)
46{
47 DumpVar(x,D);
48}
49
50static void DumpNumber(lua_Number x, DumpState* D)
51{
52 DumpVar(x,D);
53}
54
55static void DumpVector(const void* b, int n, size_t size, DumpState* D)
56{
57 DumpInt(n,D);
58 DumpMem(b,n,size,D);
59}
60
61static void DumpString(const TString* s, DumpState* D)
62{
63 if (s==NULL || getstr(s)==NULL)
64 {
65 size_t size=0;
66 DumpVar(size,D);
67 }
68 else
69 {
70 size_t size=s->tsv.len+1; /* include trailing '\0' */
71 DumpVar(size,D);
72 DumpBlock(getstr(s),size,D);
73 }
74}
75
76#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
77
78static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
79
80static void DumpConstants(const Proto* f, DumpState* D)
81{
82 int i,n=f->sizek;
83 DumpInt(n,D);
84 for (i=0; i<n; i++)
85 {
86 const TValue* o=&f->k[i];
87 DumpChar(ttype(o),D);
88 switch (ttype(o))
89 {
90 case LUA_TNIL:
91 break;
92 case LUA_TBOOLEAN:
93 DumpChar(bvalue(o),D);
94 break;
95 case LUA_TNUMBER:
96 DumpNumber(nvalue(o),D);
97 break;
98 case LUA_TSTRING:
99 DumpString(rawtsvalue(o),D);
100 break;
101 default:
102 lua_assert(0); /* cannot happen */
103 break;
104 }
105 }
106 n=f->sizep;
107 DumpInt(n,D);
108 for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
109}
110
111static void DumpDebug(const Proto* f, DumpState* D)
112{
113 int i,n;
114 n= (D->strip) ? 0 : f->sizelineinfo;
115 DumpVector(f->lineinfo,n,sizeof(int),D);
116 n= (D->strip) ? 0 : f->sizelocvars;
117 DumpInt(n,D);
118 for (i=0; i<n; i++)
119 {
120 DumpString(f->locvars[i].varname,D);
121 DumpInt(f->locvars[i].startpc,D);
122 DumpInt(f->locvars[i].endpc,D);
123 }
124 n= (D->strip) ? 0 : f->sizeupvalues;
125 DumpInt(n,D);
126 for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
127}
128
129static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
130{
131 DumpString((f->source==p || D->strip) ? NULL : f->source,D);
132 DumpInt(f->linedefined,D);
133 DumpInt(f->lastlinedefined,D);
134 DumpChar(f->nups,D);
135 DumpChar(f->numparams,D);
136 DumpChar(f->is_vararg,D);
137 DumpChar(f->maxstacksize,D);
138 DumpCode(f,D);
139 DumpConstants(f,D);
140 DumpDebug(f,D);
141}
142
143static void DumpHeader(DumpState* D)
144{
145 char h[LUAC_HEADERSIZE];
146 luaU_header(h);
147 DumpBlock(h,LUAC_HEADERSIZE,D);
148}
149
150/*
151** dump Lua function as precompiled chunk
152*/
153int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
154{
155 DumpState D;
156 D.L=L;
157 D.writer=w;
158 D.data=data;
159 D.strip=strip;
160 D.status=0;
161 DumpHeader(&D);
162 DumpFunction(f,NULL,&D);
163 return D.status;
164}
diff --git a/lfunc.c b/lfunc.c
deleted file mode 100644
index 8c3b811a..00000000
--- a/lfunc.c
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2** $Id: lfunc.c,v 2.11 2005/05/05 20:47:02 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lfunc_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lfunc.h"
16#include "lgc.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstate.h"
20
21
22
23Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
24 Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
25 luaC_link(L, obj2gco(c), LUA_TFUNCTION);
26 c->c.isC = 1;
27 c->c.env = e;
28 c->c.nupvalues = cast_byte(nelems);
29 return c;
30}
31
32
33Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
34 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
35 luaC_link(L, obj2gco(c), LUA_TFUNCTION);
36 c->l.isC = 0;
37 c->l.env = e;
38 c->l.nupvalues = cast_byte(nelems);
39 while (nelems--) c->l.upvals[nelems] = NULL;
40 return c;
41}
42
43
44UpVal *luaF_newupval (lua_State *L) {
45 UpVal *uv = luaM_new(L, UpVal);
46 luaC_link(L, obj2gco(uv), LUA_TUPVAL);
47 uv->v = &uv->u.value;
48 setnilvalue(uv->v);
49 return uv;
50}
51
52
53UpVal *luaF_findupval (lua_State *L, StkId level) {
54 global_State *g = G(L);
55 GCObject **pp = &L->openupval;
56 UpVal *p;
57 UpVal *uv;
58 while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
59 lua_assert(p->v != &p->u.value);
60 if (p->v == level) { /* found a corresponding upvalue? */
61 if (isdead(g, obj2gco(p))) /* is it dead? */
62 changewhite(obj2gco(p)); /* ressurect it */
63 return p;
64 }
65 pp = &p->next;
66 }
67 uv = luaM_new(L, UpVal); /* not found: create a new one */
68 uv->tt = LUA_TUPVAL;
69 uv->marked = luaC_white(g);
70 uv->v = level; /* current value lives in the stack */
71 uv->next = *pp; /* chain it in the proper position */
72 *pp = obj2gco(uv);
73 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
74 uv->u.l.next = g->uvhead.u.l.next;
75 uv->u.l.next->u.l.prev = uv;
76 g->uvhead.u.l.next = uv;
77 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
78 return uv;
79}
80
81
82static void unlinkupval (UpVal *uv) {
83 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
84 uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
85 uv->u.l.prev->u.l.next = uv->u.l.next;
86}
87
88
89void luaF_freeupval (lua_State *L, UpVal *uv) {
90 if (uv->v != &uv->u.value) /* is it open? */
91 unlinkupval(uv); /* remove from open list */
92 luaM_free(L, uv); /* free upvalue */
93}
94
95
96void luaF_close (lua_State *L, StkId level) {
97 UpVal *uv;
98 global_State *g = G(L);
99 while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) {
100 GCObject *o = obj2gco(uv);
101 lua_assert(!isblack(o) && uv->v != &uv->u.value);
102 L->openupval = uv->next; /* remove from `open' list */
103 if (isdead(g, o))
104 luaF_freeupval(L, uv); /* free upvalue */
105 else {
106 unlinkupval(uv);
107 setobj(L, &uv->u.value, uv->v);
108 uv->v = &uv->u.value; /* now current value lives here */
109 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
110 }
111 }
112}
113
114
115Proto *luaF_newproto (lua_State *L) {
116 Proto *f = luaM_new(L, Proto);
117 luaC_link(L, obj2gco(f), LUA_TPROTO);
118 f->k = NULL;
119 f->sizek = 0;
120 f->p = NULL;
121 f->sizep = 0;
122 f->code = NULL;
123 f->sizecode = 0;
124 f->sizelineinfo = 0;
125 f->sizeupvalues = 0;
126 f->nups = 0;
127 f->upvalues = NULL;
128 f->numparams = 0;
129 f->is_vararg = 0;
130 f->maxstacksize = 0;
131 f->lineinfo = NULL;
132 f->sizelocvars = 0;
133 f->locvars = NULL;
134 f->linedefined = 0;
135 f->lastlinedefined = 0;
136 f->source = NULL;
137 return f;
138}
139
140
141void luaF_freeproto (lua_State *L, Proto *f) {
142 luaM_freearray(L, f->code, f->sizecode, Instruction);
143 luaM_freearray(L, f->p, f->sizep, Proto *);
144 luaM_freearray(L, f->k, f->sizek, TValue);
145 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
146 luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
147 luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
148 luaM_free(L, f);
149}
150
151
152void luaF_freeclosure (lua_State *L, Closure *c) {
153 int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
154 sizeLclosure(c->l.nupvalues);
155 luaM_freemem(L, c, size);
156}
157
158
159/*
160** Look for n-th local variable at line `line' in function `func'.
161** Returns NULL if not found.
162*/
163const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
164 int i;
165 for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
166 if (pc < f->locvars[i].endpc) { /* is variable active? */
167 local_number--;
168 if (local_number == 0)
169 return getstr(f->locvars[i].varname);
170 }
171 }
172 return NULL; /* not found */
173}
174
diff --git a/lfunc.h b/lfunc.h
deleted file mode 100644
index 6f19e2fa..00000000
--- a/lfunc.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2** $Id: lfunc.h,v 2.3 2005/02/18 12:40:02 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lfunc_h
8#define lfunc_h
9
10
11#include "lobject.h"
12
13
14#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
15 cast(int, sizeof(TValue)*((n)-1)))
16
17#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
18 cast(int, sizeof(TValue *)*((n)-1)))
19
20
21LUAI_FUNC Proto *luaF_newproto (lua_State *L);
22LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
23LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
24LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
25LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
26LUAI_FUNC void luaF_close (lua_State *L, StkId level);
27LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
28LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
29LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
30LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
31 int pc);
32
33
34#endif
diff --git a/lgc.c b/lgc.c
deleted file mode 100644
index 935d8c1b..00000000
--- a/lgc.c
+++ /dev/null
@@ -1,711 +0,0 @@
1/*
2** $Id: lgc.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#include <string.h>
8
9#define lgc_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "ldebug.h"
15#include "ldo.h"
16#include "lfunc.h"
17#include "lgc.h"
18#include "lmem.h"
19#include "lobject.h"
20#include "lstate.h"
21#include "lstring.h"
22#include "ltable.h"
23#include "ltm.h"
24
25
26#define GCSTEPSIZE 1024u
27#define GCSWEEPMAX 40
28#define GCSWEEPCOST 10
29#define GCFINALIZECOST 100
30
31
32#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
33
34#define makewhite(g,x) \
35 ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g)))
36
37#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
38#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
39
40#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
41
42
43#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
44#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
45
46
47#define KEYWEAK bitmask(KEYWEAKBIT)
48#define VALUEWEAK bitmask(VALUEWEAKBIT)
49
50
51
52#define markvalue(g,o) { checkconsistency(o); \
53 if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
54
55#define markobject(g,t) { if (iswhite(obj2gco(t))) \
56 reallymarkobject(g, obj2gco(t)); }
57
58
59#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
60
61
62static void removeentry (Node *n) {
63 lua_assert(ttisnil(gval(n)));
64 if (iscollectable(gkey(n)))
65 setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
66}
67
68
69static void reallymarkobject (global_State *g, GCObject *o) {
70 lua_assert(iswhite(o) && !isdead(g, o));
71 white2gray(o);
72 switch (o->gch.tt) {
73 case LUA_TSTRING: {
74 return;
75 }
76 case LUA_TUSERDATA: {
77 Table *mt = gco2u(o)->metatable;
78 gray2black(o); /* udata are never gray */
79 if (mt) markobject(g, mt);
80 markobject(g, gco2u(o)->env);
81 return;
82 }
83 case LUA_TUPVAL: {
84 UpVal *uv = gco2uv(o);
85 markvalue(g, uv->v);
86 if (uv->v == &uv->u.value) /* closed? */
87 gray2black(o); /* open upvalues are never black */
88 return;
89 }
90 case LUA_TFUNCTION: {
91 gco2cl(o)->c.gclist = g->gray;
92 g->gray = o;
93 break;
94 }
95 case LUA_TTABLE: {
96 gco2h(o)->gclist = g->gray;
97 g->gray = o;
98 break;
99 }
100 case LUA_TTHREAD: {
101 gco2th(o)->gclist = g->gray;
102 g->gray = o;
103 break;
104 }
105 case LUA_TPROTO: {
106 gco2p(o)->gclist = g->gray;
107 g->gray = o;
108 break;
109 }
110 default: lua_assert(0);
111 }
112}
113
114
115static void marktmu (global_State *g) {
116 GCObject *u = g->tmudata;
117 if (u) {
118 do {
119 u = u->gch.next;
120 makewhite(g, u); /* may be marked, if left from previous GC */
121 reallymarkobject(g, u);
122 } while (u != g->tmudata);
123 }
124}
125
126
127/* move `dead' udata that need finalization to list `tmudata' */
128size_t luaC_separateudata (lua_State *L, int all) {
129 global_State *g = G(L);
130 size_t deadmem = 0;
131 GCObject **p = &g->mainthread->next;
132 GCObject *curr;
133 while ((curr = *p) != NULL) {
134 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
135 p = &curr->gch.next; /* don't bother with them */
136 else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
137 markfinalized(gco2u(curr)); /* don't need finalization */
138 p = &curr->gch.next;
139 }
140 else { /* must call its gc method */
141 deadmem += sizeudata(gco2u(curr));
142 markfinalized(gco2u(curr));
143 *p = curr->gch.next;
144 /* link `curr' at the end of `tmudata' list */
145 if (g->tmudata == NULL) /* list is empty? */
146 g->tmudata = curr->gch.next = curr; /* creates a circular list */
147 else {
148 curr->gch.next = g->tmudata->gch.next;
149 g->tmudata->gch.next = curr;
150 g->tmudata = curr;
151 }
152 }
153 }
154 return deadmem;
155}
156
157
158static int traversetable (global_State *g, Table *h) {
159 int i;
160 int weakkey = 0;
161 int weakvalue = 0;
162 const TValue *mode;
163 if (h->metatable)
164 markobject(g, h->metatable);
165 mode = gfasttm(g, h->metatable, TM_MODE);
166 if (mode && ttisstring(mode)) { /* is there a weak mode? */
167 weakkey = (strchr(svalue(mode), 'k') != NULL);
168 weakvalue = (strchr(svalue(mode), 'v') != NULL);
169 if (weakkey || weakvalue) { /* is really weak? */
170 h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
171 h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
172 (weakvalue << VALUEWEAKBIT));
173 h->gclist = g->weak; /* must be cleared after GC, ... */
174 g->weak = obj2gco(h); /* ... so put in the appropriate list */
175 }
176 }
177 if (weakkey && weakvalue) return 1;
178 if (!weakvalue) {
179 i = h->sizearray;
180 while (i--)
181 markvalue(g, &h->array[i]);
182 }
183 i = sizenode(h);
184 while (i--) {
185 Node *n = gnode(h, i);
186 lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
187 if (ttisnil(gval(n)))
188 removeentry(n); /* remove empty entries */
189 else {
190 lua_assert(!ttisnil(gkey(n)));
191 if (!weakkey) markvalue(g, gkey(n));
192 if (!weakvalue) markvalue(g, gval(n));
193 }
194 }
195 return weakkey || weakvalue;
196}
197
198
199/*
200** All marks are conditional because a GC may happen while the
201** prototype is still being created
202*/
203static void traverseproto (global_State *g, Proto *f) {
204 int i;
205 if (f->source) stringmark(f->source);
206 for (i=0; i<f->sizek; i++) /* mark literals */
207 markvalue(g, &f->k[i]);
208 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
209 if (f->upvalues[i])
210 stringmark(f->upvalues[i]);
211 }
212 for (i=0; i<f->sizep; i++) { /* mark nested protos */
213 if (f->p[i])
214 markobject(g, f->p[i]);
215 }
216 for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
217 if (f->locvars[i].varname)
218 stringmark(f->locvars[i].varname);
219 }
220}
221
222
223
224static void traverseclosure (global_State *g, Closure *cl) {
225 markobject(g, cl->c.env);
226 if (cl->c.isC) {
227 int i;
228 for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
229 markvalue(g, &cl->c.upvalue[i]);
230 }
231 else {
232 int i;
233 lua_assert(cl->l.nupvalues == cl->l.p->nups);
234 markobject(g, cl->l.p);
235 for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
236 markobject(g, cl->l.upvals[i]);
237 }
238}
239
240
241static void checkstacksizes (lua_State *L, StkId max) {
242 int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */
243 int s_used = cast_int(max - L->stack); /* part of stack in use */
244 if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
245 return; /* do not touch the stacks */
246 if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
247 luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
248 condhardstacktests(luaD_reallocCI(L, ci_used + 1));
249 if (4*s_used < L->stacksize &&
250 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
251 luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
252 condhardstacktests(luaD_reallocstack(L, s_used));
253}
254
255
256static void traversestack (global_State *g, lua_State *l) {
257 StkId o, lim;
258 CallInfo *ci;
259 markvalue(g, gt(l));
260 lim = l->top;
261 for (ci = l->base_ci; ci <= l->ci; ci++) {
262 lua_assert(ci->top <= l->stack_last);
263 if (lim < ci->top) lim = ci->top;
264 }
265 for (o = l->stack; o < l->top; o++)
266 markvalue(g, o);
267 for (; o <= lim; o++)
268 setnilvalue(o);
269 checkstacksizes(l, lim);
270}
271
272
273/*
274** traverse one gray object, turning it to black.
275** Returns `quantity' traversed.
276*/
277static l_mem propagatemark (global_State *g) {
278 GCObject *o = g->gray;
279 lua_assert(isgray(o));
280 gray2black(o);
281 switch (o->gch.tt) {
282 case LUA_TTABLE: {
283 Table *h = gco2h(o);
284 g->gray = h->gclist;
285 if (traversetable(g, h)) /* table is weak? */
286 black2gray(o); /* keep it gray */
287 return sizeof(Table) + sizeof(TValue) * h->sizearray +
288 sizeof(Node) * sizenode(h);
289 }
290 case LUA_TFUNCTION: {
291 Closure *cl = gco2cl(o);
292 g->gray = cl->c.gclist;
293 traverseclosure(g, cl);
294 return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
295 sizeLclosure(cl->l.nupvalues);
296 }
297 case LUA_TTHREAD: {
298 lua_State *th = gco2th(o);
299 g->gray = th->gclist;
300 th->gclist = g->grayagain;
301 g->grayagain = o;
302 black2gray(o);
303 traversestack(g, th);
304 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
305 sizeof(CallInfo) * th->size_ci;
306 }
307 case LUA_TPROTO: {
308 Proto *p = gco2p(o);
309 g->gray = p->gclist;
310 traverseproto(g, p);
311 return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
312 sizeof(Proto *) * p->sizep +
313 sizeof(TValue) * p->sizek +
314 sizeof(int) * p->sizelineinfo +
315 sizeof(LocVar) * p->sizelocvars +
316 sizeof(TString *) * p->sizeupvalues;
317 }
318 default: lua_assert(0); return 0;
319 }
320}
321
322
323static size_t propagateall (global_State *g) {
324 size_t m = 0;
325 while (g->gray) m += propagatemark(g);
326 return m;
327}
328
329
330/*
331** The next function tells whether a key or value can be cleared from
332** a weak table. Non-collectable objects are never removed from weak
333** tables. Strings behave as `values', so are never removed too. for
334** other objects: if really collected, cannot keep them; for userdata
335** being finalized, keep them in keys, but not in values
336*/
337static int iscleared (const TValue *o, int iskey) {
338 if (!iscollectable(o)) return 0;
339 if (ttisstring(o)) {
340 stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
341 return 0;
342 }
343 return iswhite(gcvalue(o)) ||
344 (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
345}
346
347
348/*
349** clear collected entries from weaktables
350*/
351static void cleartable (GCObject *l) {
352 while (l) {
353 Table *h = gco2h(l);
354 int i = h->sizearray;
355 lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
356 testbit(h->marked, KEYWEAKBIT));
357 if (testbit(h->marked, VALUEWEAKBIT)) {
358 while (i--) {
359 TValue *o = &h->array[i];
360 if (iscleared(o, 0)) /* value was collected? */
361 setnilvalue(o); /* remove value */
362 }
363 }
364 i = sizenode(h);
365 while (i--) {
366 Node *n = gnode(h, i);
367 if (!ttisnil(gval(n)) && /* non-empty entry? */
368 (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
369 setnilvalue(gval(n)); /* remove value ... */
370 removeentry(n); /* remove entry from table */
371 }
372 }
373 l = h->gclist;
374 }
375}
376
377
378static void freeobj (lua_State *L, GCObject *o) {
379 switch (o->gch.tt) {
380 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
381 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
382 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
383 case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
384 case LUA_TTHREAD: {
385 lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
386 luaE_freethread(L, gco2th(o));
387 break;
388 }
389 case LUA_TSTRING: {
390 G(L)->strt.nuse--;
391 luaM_freemem(L, o, sizestring(gco2ts(o)));
392 break;
393 }
394 case LUA_TUSERDATA: {
395 luaM_freemem(L, o, sizeudata(gco2u(o)));
396 break;
397 }
398 default: lua_assert(0);
399 }
400}
401
402
403
404#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
405
406
407static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
408 GCObject *curr;
409 global_State *g = G(L);
410 int deadmask = otherwhite(g);
411 while ((curr = *p) != NULL && count-- > 0) {
412 if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
413 sweepwholelist(L, &gco2th(curr)->openupval);
414 if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
415 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
416 makewhite(g, curr); /* make it white (for next cycle) */
417 p = &curr->gch.next;
418 }
419 else { /* must erase `curr' */
420 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
421 *p = curr->gch.next;
422 if (curr == g->rootgc) /* is the first element of the list? */
423 g->rootgc = curr->gch.next; /* adjust first */
424 freeobj(L, curr);
425 }
426 }
427 return p;
428}
429
430
431static void checkSizes (lua_State *L) {
432 global_State *g = G(L);
433 /* check size of string hash */
434 if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
435 g->strt.size > MINSTRTABSIZE*2)
436 luaS_resize(L, g->strt.size/2); /* table is too big */
437 /* check size of buffer */
438 if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
439 size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
440 luaZ_resizebuffer(L, &g->buff, newsize);
441 }
442}
443
444
445static void GCTM (lua_State *L) {
446 global_State *g = G(L);
447 GCObject *o = g->tmudata->gch.next; /* get first element */
448 Udata *udata = rawgco2u(o);
449 const TValue *tm;
450 /* remove udata from `tmudata' */
451 if (o == g->tmudata) /* last element? */
452 g->tmudata = NULL;
453 else
454 g->tmudata->gch.next = udata->uv.next;
455 udata->uv.next = g->mainthread->next; /* return it to `root' list */
456 g->mainthread->next = o;
457 makewhite(g, o);
458 tm = fasttm(L, udata->uv.metatable, TM_GC);
459 if (tm != NULL) {
460 lu_byte oldah = L->allowhook;
461 lu_mem oldt = g->GCthreshold;
462 L->allowhook = 0; /* stop debug hooks during GC tag method */
463 g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
464 setobj2s(L, L->top, tm);
465 setuvalue(L, L->top+1, udata);
466 L->top += 2;
467 luaD_call(L, L->top - 2, 0);
468 L->allowhook = oldah; /* restore hooks */
469 g->GCthreshold = oldt; /* restore threshold */
470 }
471}
472
473
474/*
475** Call all GC tag methods
476*/
477void luaC_callGCTM (lua_State *L) {
478 while (G(L)->tmudata)
479 GCTM(L);
480}
481
482
483void luaC_freeall (lua_State *L) {
484 global_State *g = G(L);
485 int i;
486 g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
487 sweepwholelist(L, &g->rootgc);
488 for (i = 0; i < g->strt.size; i++) /* free all string lists */
489 sweepwholelist(L, &g->strt.hash[i]);
490}
491
492
493static void markmt (global_State *g) {
494 int i;
495 for (i=0; i<NUM_TAGS; i++)
496 if (g->mt[i]) markobject(g, g->mt[i]);
497}
498
499
500/* mark root set */
501static void markroot (lua_State *L) {
502 global_State *g = G(L);
503 g->gray = NULL;
504 g->grayagain = NULL;
505 g->weak = NULL;
506 markobject(g, g->mainthread);
507 /* make global table be traversed before main stack */
508 markvalue(g, gt(g->mainthread));
509 markvalue(g, registry(L));
510 markmt(g);
511 g->gcstate = GCSpropagate;
512}
513
514
515static void remarkupvals (global_State *g) {
516 UpVal *uv;
517 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
518 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
519 if (isgray(obj2gco(uv)))
520 markvalue(g, uv->v);
521 }
522}
523
524
525static void atomic (lua_State *L) {
526 global_State *g = G(L);
527 size_t udsize; /* total size of userdata to be finalized */
528 /* remark occasional upvalues of (maybe) dead threads */
529 remarkupvals(g);
530 /* traverse objects cautch by write barrier and by 'remarkupvals' */
531 propagateall(g);
532 /* remark weak tables */
533 g->gray = g->weak;
534 g->weak = NULL;
535 lua_assert(!iswhite(obj2gco(g->mainthread)));
536 markobject(g, L); /* mark running thread */
537 markmt(g); /* mark basic metatables (again) */
538 propagateall(g);
539 /* remark gray again */
540 g->gray = g->grayagain;
541 g->grayagain = NULL;
542 propagateall(g);
543 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
544 marktmu(g); /* mark `preserved' userdata */
545 udsize += propagateall(g); /* remark, to propagate `preserveness' */
546 cleartable(g->weak); /* remove collected objects from weak tables */
547 /* flip current white */
548 g->currentwhite = cast_byte(otherwhite(g));
549 g->sweepstrgc = 0;
550 g->sweepgc = &g->rootgc;
551 g->gcstate = GCSsweepstring;
552 g->estimate = g->totalbytes - udsize; /* first estimate */
553}
554
555
556static l_mem singlestep (lua_State *L) {
557 global_State *g = G(L);
558 /*lua_checkmemory(L);*/
559 switch (g->gcstate) {
560 case GCSpause: {
561 markroot(L); /* start a new collection */
562 return 0;
563 }
564 case GCSpropagate: {
565 if (g->gray)
566 return propagatemark(g);
567 else { /* no more `gray' objects */
568 atomic(L); /* finish mark phase */
569 return 0;
570 }
571 }
572 case GCSsweepstring: {
573 lu_mem old = g->totalbytes;
574 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
575 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
576 g->gcstate = GCSsweep; /* end sweep-string phase */
577 lua_assert(old >= g->totalbytes);
578 g->estimate -= old - g->totalbytes;
579 return GCSWEEPCOST;
580 }
581 case GCSsweep: {
582 lu_mem old = g->totalbytes;
583 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
584 if (*g->sweepgc == NULL) { /* nothing more to sweep? */
585 checkSizes(L);
586 g->gcstate = GCSfinalize; /* end sweep phase */
587 }
588 lua_assert(old >= g->totalbytes);
589 g->estimate -= old - g->totalbytes;
590 return GCSWEEPMAX*GCSWEEPCOST;
591 }
592 case GCSfinalize: {
593 if (g->tmudata) {
594 GCTM(L);
595 if (g->estimate > GCFINALIZECOST)
596 g->estimate -= GCFINALIZECOST;
597 return GCFINALIZECOST;
598 }
599 else {
600 g->gcstate = GCSpause; /* end collection */
601 g->gcdept = 0;
602 return 0;
603 }
604 }
605 default: lua_assert(0); return 0;
606 }
607}
608
609
610void luaC_step (lua_State *L) {
611 global_State *g = G(L);
612 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
613 if (lim == 0)
614 lim = (MAX_LUMEM-1)/2; /* no limit */
615 g->gcdept += g->totalbytes - g->GCthreshold;
616 do {
617 lim -= singlestep(L);
618 if (g->gcstate == GCSpause)
619 break;
620 } while (lim > 0);
621 if (g->gcstate != GCSpause) {
622 if (g->gcdept < GCSTEPSIZE)
623 g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
624 else {
625 g->gcdept -= GCSTEPSIZE;
626 g->GCthreshold = g->totalbytes;
627 }
628 }
629 else {
630 lua_assert(g->totalbytes >= g->estimate);
631 setthreshold(g);
632 }
633}
634
635
636void luaC_fullgc (lua_State *L) {
637 global_State *g = G(L);
638 if (g->gcstate <= GCSpropagate) {
639 /* reset sweep marks to sweep all elements (returning them to white) */
640 g->sweepstrgc = 0;
641 g->sweepgc = &g->rootgc;
642 /* reset other collector lists */
643 g->gray = NULL;
644 g->grayagain = NULL;
645 g->weak = NULL;
646 g->gcstate = GCSsweepstring;
647 }
648 lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
649 /* finish any pending sweep phase */
650 while (g->gcstate != GCSfinalize) {
651 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
652 singlestep(L);
653 }
654 markroot(L);
655 while (g->gcstate != GCSpause) {
656 singlestep(L);
657 }
658 setthreshold(g);
659}
660
661
662void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
663 global_State *g = G(L);
664 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
665 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
666 lua_assert(ttype(&o->gch) != LUA_TTABLE);
667 /* must keep invariant? */
668 if (g->gcstate == GCSpropagate)
669 reallymarkobject(g, v); /* restore invariant */
670 else /* don't mind */
671 makewhite(g, o); /* mark as white just to avoid other barriers */
672}
673
674
675void luaC_barrierback (lua_State *L, Table *t) {
676 global_State *g = G(L);
677 GCObject *o = obj2gco(t);
678 lua_assert(isblack(o) && !isdead(g, o));
679 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
680 black2gray(o); /* make table gray (again) */
681 t->gclist = g->grayagain;
682 g->grayagain = o;
683}
684
685
686void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
687 global_State *g = G(L);
688 o->gch.next = g->rootgc;
689 g->rootgc = o;
690 o->gch.marked = luaC_white(g);
691 o->gch.tt = tt;
692}
693
694
695void luaC_linkupval (lua_State *L, UpVal *uv) {
696 global_State *g = G(L);
697 GCObject *o = obj2gco(uv);
698 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
699 g->rootgc = o;
700 if (isgray(o)) {
701 if (g->gcstate == GCSpropagate) {
702 gray2black(o); /* closed upvalues need barrier */
703 luaC_barrier(L, uv, uv->v);
704 }
705 else { /* sweep phase: sweep it (turning it into white) */
706 makewhite(g, o);
707 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
708 }
709 }
710}
711
diff --git a/lgc.h b/lgc.h
deleted file mode 100644
index 6079c03d..00000000
--- a/lgc.h
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2** $Id: lgc.h,v 2.14 2005/06/07 18:53:45 roberto Exp roberto $
3** Garbage Collector
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lgc_h
8#define lgc_h
9
10
11#include "lobject.h"
12
13
14/*
15** Possible states of the Garbage Collector
16*/
17#define GCSpause 0
18#define GCSpropagate 1
19#define GCSsweepstring 2
20#define GCSsweep 3
21#define GCSfinalize 4
22
23
24/*
25** some userful bit tricks
26*/
27#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
28#define setbits(x,m) ((x) |= (m))
29#define testbits(x,m) ((x) & (m))
30#define bitmask(b) (1<<(b))
31#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
32#define l_setbit(x,b) setbits(x, bitmask(b))
33#define resetbit(x,b) resetbits(x, bitmask(b))
34#define testbit(x,b) testbits(x, bitmask(b))
35#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
36#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
37#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
38
39
40
41/*
42** Layout for bit use in `marked' field:
43** bit 0 - object is white (type 0)
44** bit 1 - object is white (type 1)
45** bit 2 - object is black
46** bit 3 - for userdata: has been finalized
47** bit 3 - for tables: has weak keys
48** bit 4 - for tables: has weak values
49** bit 5 - object is fixed (should not be collected)
50** bit 6 - object is "super" fixed (only the main thread)
51*/
52
53
54#define WHITE0BIT 0
55#define WHITE1BIT 1
56#define BLACKBIT 2
57#define FINALIZEDBIT 3
58#define KEYWEAKBIT 3
59#define VALUEWEAKBIT 4
60#define FIXEDBIT 5
61#define SFIXEDBIT 6
62#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
63
64
65#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
66#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
67#define isgray(x) (!isblack(x) && !iswhite(x))
68
69#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
70#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
71
72#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
73#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
74
75#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
76
77#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
78
79
80#define luaC_checkGC(L) { \
81 condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
82 if (G(L)->totalbytes >= G(L)->GCthreshold) \
83 luaC_step(L); }
84
85
86#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
87 luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
88
89#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
90 luaC_barrierback(L,t); }
91
92#define luaC_objbarrier(L,p,o) \
93 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
94 luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
95
96#define luaC_objbarriert(L,t,o) \
97 { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
98
99LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
100LUAI_FUNC void luaC_callGCTM (lua_State *L);
101LUAI_FUNC void luaC_freeall (lua_State *L);
102LUAI_FUNC void luaC_step (lua_State *L);
103LUAI_FUNC void luaC_fullgc (lua_State *L);
104LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
105LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
106LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
107LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
108
109
110#endif
diff --git a/linit.c b/linit.c
deleted file mode 100644
index 5f3ceda7..00000000
--- a/linit.c
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2** $Id: linit.c,v 1.13 2005/08/26 17:36:32 roberto Exp roberto $
3** Initialization of libraries for lua.c
4** See Copyright Notice in lua.h
5*/
6
7
8#define linit_c
9#define LUA_LIB
10
11#include "lua.h"
12
13#include "lualib.h"
14#include "lauxlib.h"
15
16
17static const luaL_Reg lualibs[] = {
18 {"", luaopen_base},
19 {LUA_LOADLIBNAME, luaopen_package},
20 {LUA_TABLIBNAME, luaopen_table},
21 {LUA_IOLIBNAME, luaopen_io},
22 {LUA_OSLIBNAME, luaopen_os},
23 {LUA_STRLIBNAME, luaopen_string},
24 {LUA_MATHLIBNAME, luaopen_math},
25 {LUA_DBLIBNAME, luaopen_debug},
26 {NULL, NULL}
27};
28
29
30LUALIB_API void luaL_openlibs (lua_State *L) {
31 const luaL_Reg *lib = lualibs;
32 for (; lib->func; lib++) {
33 lua_pushcfunction(L, lib->func);
34 lua_pushstring(L, lib->name);
35 lua_call(L, 1, 0);
36 }
37}
38
diff --git a/liolib.c b/liolib.c
deleted file mode 100644
index 7c2d3147..00000000
--- a/liolib.c
+++ /dev/null
@@ -1,532 +0,0 @@
1/*
2** $Id: liolib.c,v 2.72 2006/01/28 12:59:13 roberto Exp roberto $
3** Standard I/O (and system) library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define liolib_c
14#define LUA_LIB
15
16#include "lua.h"
17
18#include "lauxlib.h"
19#include "lualib.h"
20
21
22
23#define IO_INPUT 1
24#define IO_OUTPUT 2
25
26
27static const char *const fnames[] = {"input", "output"};
28
29
30static int pushresult (lua_State *L, int i, const char *filename) {
31 int en = errno; /* calls to Lua API may change this value */
32 if (i) {
33 lua_pushboolean(L, 1);
34 return 1;
35 }
36 else {
37 lua_pushnil(L);
38 if (filename)
39 lua_pushfstring(L, "%s: %s", filename, strerror(en));
40 else
41 lua_pushfstring(L, "%s", strerror(en));
42 lua_pushinteger(L, en);
43 return 3;
44 }
45}
46
47
48static void fileerror (lua_State *L, int arg, const char *filename) {
49 lua_pushfstring(L, "%s: %s", filename, strerror(errno));
50 luaL_argerror(L, arg, lua_tostring(L, -1));
51}
52
53
54#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
55
56
57static int io_type (lua_State *L) {
58 void *ud;
59 luaL_checkany(L, 1);
60 ud = lua_touserdata(L, 1);
61 lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
62 if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
63 lua_pushnil(L); /* not a file */
64 else if (*((FILE **)ud) == NULL)
65 lua_pushliteral(L, "closed file");
66 else
67 lua_pushliteral(L, "file");
68 return 1;
69}
70
71
72static FILE *tofile (lua_State *L) {
73 FILE **f = topfile(L);
74 if (*f == NULL)
75 luaL_error(L, "attempt to use a closed file");
76 return *f;
77}
78
79
80
81/*
82** When creating file handles, always creates a `closed' file handle
83** before opening the actual file; so, if there is a memory error, the
84** file is not left opened.
85*/
86static FILE **newfile (lua_State *L) {
87 FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
88 *pf = NULL; /* file handle is currently `closed' */
89 luaL_getmetatable(L, LUA_FILEHANDLE);
90 lua_setmetatable(L, -2);
91 return pf;
92}
93
94
95/*
96** this function has a separated environment, which defines the
97** correct __close for 'popen' files
98*/
99static int io_pclose (lua_State *L) {
100 FILE **p = topfile(L);
101 int ok = lua_pclose(L, *p);
102 *p = NULL;
103 return pushresult(L, ok, NULL);
104}
105
106
107static int io_fclose (lua_State *L) {
108 FILE **p = topfile(L);
109 int ok = (fclose(*p) == 0);
110 *p = NULL;
111 return pushresult(L, ok, NULL);
112}
113
114
115static int aux_close (lua_State *L) {
116 lua_getfenv(L, 1);
117 lua_getfield(L, -1, "__close");
118 return (lua_tocfunction(L, -1))(L);
119}
120
121
122static int io_close (lua_State *L) {
123 if (lua_isnone(L, 1))
124 lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
125 tofile(L); /* make sure argument is a file */
126 return aux_close(L);
127}
128
129
130static int io_gc (lua_State *L) {
131 FILE *f = *topfile(L);
132 /* ignore closed files and standard files */
133 if (f != NULL && f != stdin && f != stdout && f != stderr)
134 aux_close(L);
135 return 0;
136}
137
138
139static int io_tostring (lua_State *L) {
140 FILE *f = *topfile(L);
141 if (f == NULL)
142 lua_pushstring(L, "file (closed)");
143 else
144 lua_pushfstring(L, "file (%p)", f);
145 return 1;
146}
147
148
149static int io_open (lua_State *L) {
150 const char *filename = luaL_checkstring(L, 1);
151 const char *mode = luaL_optstring(L, 2, "r");
152 FILE **pf = newfile(L);
153 *pf = fopen(filename, mode);
154 return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
155}
156
157
158static int io_popen (lua_State *L) {
159 const char *filename = luaL_checkstring(L, 1);
160 const char *mode = luaL_optstring(L, 2, "r");
161 FILE **pf = newfile(L);
162 *pf = lua_popen(L, filename, mode);
163 return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
164}
165
166
167static int io_tmpfile (lua_State *L) {
168 FILE **pf = newfile(L);
169 *pf = tmpfile();
170 return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
171}
172
173
174static FILE *getiofile (lua_State *L, int findex) {
175 FILE *f;
176 lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
177 f = *(FILE **)lua_touserdata(L, -1);
178 if (f == NULL)
179 luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
180 return f;
181}
182
183
184static int g_iofile (lua_State *L, int f, const char *mode) {
185 if (!lua_isnoneornil(L, 1)) {
186 const char *filename = lua_tostring(L, 1);
187 if (filename) {
188 FILE **pf = newfile(L);
189 *pf = fopen(filename, mode);
190 if (*pf == NULL)
191 fileerror(L, 1, filename);
192 }
193 else {
194 tofile(L); /* check that it's a valid file handle */
195 lua_pushvalue(L, 1);
196 }
197 lua_rawseti(L, LUA_ENVIRONINDEX, f);
198 }
199 /* return current value */
200 lua_rawgeti(L, LUA_ENVIRONINDEX, f);
201 return 1;
202}
203
204
205static int io_input (lua_State *L) {
206 return g_iofile(L, IO_INPUT, "r");
207}
208
209
210static int io_output (lua_State *L) {
211 return g_iofile(L, IO_OUTPUT, "w");
212}
213
214
215static int io_readline (lua_State *L);
216
217
218static void aux_lines (lua_State *L, int idx, int toclose) {
219 lua_pushvalue(L, idx);
220 lua_pushboolean(L, toclose); /* close/not close file when finished */
221 lua_pushcclosure(L, io_readline, 2);
222}
223
224
225static int f_lines (lua_State *L) {
226 tofile(L); /* check that it's a valid file handle */
227 aux_lines(L, 1, 0);
228 return 1;
229}
230
231
232static int io_lines (lua_State *L) {
233 if (lua_isnoneornil(L, 1)) { /* no arguments? */
234 /* will iterate over default input */
235 lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
236 return f_lines(L);
237 }
238 else {
239 const char *filename = luaL_checkstring(L, 1);
240 FILE **pf = newfile(L);
241 *pf = fopen(filename, "r");
242 if (*pf == NULL)
243 fileerror(L, 1, filename);
244 aux_lines(L, lua_gettop(L), 1);
245 return 1;
246 }
247}
248
249
250/*
251** {======================================================
252** READ
253** =======================================================
254*/
255
256
257static int read_number (lua_State *L, FILE *f) {
258 lua_Number d;
259 if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
260 lua_pushnumber(L, d);
261 return 1;
262 }
263 else return 0; /* read fails */
264}
265
266
267static int test_eof (lua_State *L, FILE *f) {
268 int c = getc(f);
269 ungetc(c, f);
270 lua_pushlstring(L, NULL, 0);
271 return (c != EOF);
272}
273
274
275static int read_line (lua_State *L, FILE *f) {
276 luaL_Buffer b;
277 luaL_buffinit(L, &b);
278 for (;;) {
279 size_t l;
280 char *p = luaL_prepbuffer(&b);
281 if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
282 luaL_pushresult(&b); /* close buffer */
283 return (lua_strlen(L, -1) > 0); /* check whether read something */
284 }
285 l = strlen(p);
286 if (l == 0 || p[l-1] != '\n')
287 luaL_addsize(&b, l);
288 else {
289 luaL_addsize(&b, l - 1); /* do not include `eol' */
290 luaL_pushresult(&b); /* close buffer */
291 return 1; /* read at least an `eol' */
292 }
293 }
294}
295
296
297static int read_chars (lua_State *L, FILE *f, size_t n) {
298 size_t rlen; /* how much to read */
299 size_t nr; /* number of chars actually read */
300 luaL_Buffer b;
301 luaL_buffinit(L, &b);
302 rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
303 do {
304 char *p = luaL_prepbuffer(&b);
305 if (rlen > n) rlen = n; /* cannot read more than asked */
306 nr = fread(p, sizeof(char), rlen, f);
307 luaL_addsize(&b, nr);
308 n -= nr; /* still have to read `n' chars */
309 } while (n > 0 && nr == rlen); /* until end of count or eof */
310 luaL_pushresult(&b); /* close buffer */
311 return (n == 0 || lua_strlen(L, -1) > 0);
312}
313
314
315static int g_read (lua_State *L, FILE *f, int first) {
316 int nargs = lua_gettop(L) - 1;
317 int success;
318 int n;
319 clearerr(f);
320 if (nargs == 0) { /* no arguments? */
321 success = read_line(L, f);
322 n = first+1; /* to return 1 result */
323 }
324 else { /* ensure stack space for all results and for auxlib's buffer */
325 luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
326 success = 1;
327 for (n = first; nargs-- && success; n++) {
328 if (lua_type(L, n) == LUA_TNUMBER) {
329 size_t l = (size_t)lua_tointeger(L, n);
330 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
331 }
332 else {
333 const char *p = lua_tostring(L, n);
334 luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
335 switch (p[1]) {
336 case 'n': /* number */
337 success = read_number(L, f);
338 break;
339 case 'l': /* line */
340 success = read_line(L, f);
341 break;
342 case 'a': /* file */
343 read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
344 success = 1; /* always success */
345 break;
346 default:
347 return luaL_argerror(L, n, "invalid format");
348 }
349 }
350 }
351 }
352 if (ferror(f))
353 return pushresult(L, 0, NULL);
354 if (!success) {
355 lua_pop(L, 1); /* remove last result */
356 lua_pushnil(L); /* push nil instead */
357 }
358 return n - first;
359}
360
361
362static int io_read (lua_State *L) {
363 return g_read(L, getiofile(L, IO_INPUT), 1);
364}
365
366
367static int f_read (lua_State *L) {
368 return g_read(L, tofile(L), 2);
369}
370
371
372static int io_readline (lua_State *L) {
373 FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
374 int sucess;
375 if (f == NULL) /* file is already closed? */
376 luaL_error(L, "file is already closed");
377 sucess = read_line(L, f);
378 if (ferror(f))
379 return luaL_error(L, "%s", strerror(errno));
380 if (sucess) return 1;
381 else { /* EOF */
382 if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
383 lua_settop(L, 0);
384 lua_pushvalue(L, lua_upvalueindex(1));
385 aux_close(L); /* close it */
386 }
387 return 0;
388 }
389}
390
391/* }====================================================== */
392
393
394static int g_write (lua_State *L, FILE *f, int arg) {
395 int nargs = lua_gettop(L) - 1;
396 int status = 1;
397 for (; nargs--; arg++) {
398 if (lua_type(L, arg) == LUA_TNUMBER) {
399 /* optimization: could be done exactly as for strings */
400 status = status &&
401 fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
402 }
403 else {
404 size_t l;
405 const char *s = luaL_checklstring(L, arg, &l);
406 status = status && (fwrite(s, sizeof(char), l, f) == l);
407 }
408 }
409 return pushresult(L, status, NULL);
410}
411
412
413static int io_write (lua_State *L) {
414 return g_write(L, getiofile(L, IO_OUTPUT), 1);
415}
416
417
418static int f_write (lua_State *L) {
419 return g_write(L, tofile(L), 2);
420}
421
422
423static int f_seek (lua_State *L) {
424 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
425 static const char *const modenames[] = {"set", "cur", "end", NULL};
426 FILE *f = tofile(L);
427 int op = luaL_checkoption(L, 2, "cur", modenames);
428 long offset = luaL_optlong(L, 3, 0);
429 op = fseek(f, offset, mode[op]);
430 if (op)
431 return pushresult(L, 0, NULL); /* error */
432 else {
433 lua_pushinteger(L, ftell(f));
434 return 1;
435 }
436}
437
438
439static int f_setvbuf (lua_State *L) {
440 static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
441 static const char *const modenames[] = {"no", "full", "line", NULL};
442 FILE *f = tofile(L);
443 int op = luaL_checkoption(L, 2, NULL, modenames);
444 lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
445 int res = setvbuf(f, NULL, mode[op], sz);
446 return pushresult(L, res == 0, NULL);
447}
448
449
450
451static int io_flush (lua_State *L) {
452 return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
453}
454
455
456static int f_flush (lua_State *L) {
457 return pushresult(L, fflush(tofile(L)) == 0, NULL);
458}
459
460
461static const luaL_Reg iolib[] = {
462 {"close", io_close},
463 {"flush", io_flush},
464 {"input", io_input},
465 {"lines", io_lines},
466 {"open", io_open},
467 {"output", io_output},
468 {"popen", io_popen},
469 {"read", io_read},
470 {"tmpfile", io_tmpfile},
471 {"type", io_type},
472 {"write", io_write},
473 {NULL, NULL}
474};
475
476
477static const luaL_Reg flib[] = {
478 {"close", io_close},
479 {"flush", f_flush},
480 {"lines", f_lines},
481 {"read", f_read},
482 {"seek", f_seek},
483 {"setvbuf", f_setvbuf},
484 {"write", f_write},
485 {"__gc", io_gc},
486 {"__tostring", io_tostring},
487 {NULL, NULL}
488};
489
490
491static void createmeta (lua_State *L) {
492 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
493 lua_pushvalue(L, -1); /* push metatable */
494 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
495 luaL_register(L, NULL, flib); /* file methods */
496}
497
498
499static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
500 *newfile(L) = f;
501 if (k > 0) {
502 lua_pushvalue(L, -1);
503 lua_rawseti(L, LUA_ENVIRONINDEX, k);
504 }
505 lua_setfield(L, -2, fname);
506}
507
508
509LUALIB_API int luaopen_io (lua_State *L) {
510 createmeta(L);
511 /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
512 lua_createtable(L, 2, 1);
513 lua_replace(L, LUA_ENVIRONINDEX);
514 /* open library */
515 luaL_register(L, LUA_IOLIBNAME, iolib);
516 /* create (and set) default files */
517 createstdfile(L, stdin, IO_INPUT, "stdin");
518 createstdfile(L, stdout, IO_OUTPUT, "stdout");
519 createstdfile(L, stderr, 0, "stderr");
520 /* create environment for 'popen' */
521 lua_getfield(L, -1, "popen");
522 lua_createtable(L, 0, 1);
523 lua_pushcfunction(L, io_pclose);
524 lua_setfield(L, -2, "__close");
525 lua_setfenv(L, -2);
526 lua_pop(L, 1); /* pop 'popen' */
527 /* set default close function */
528 lua_pushcfunction(L, io_fclose);
529 lua_setfield(L, LUA_ENVIRONINDEX, "__close");
530 return 1;
531}
532
diff --git a/llex.c b/llex.c
deleted file mode 100644
index 6a8c158e..00000000
--- a/llex.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/*
2** $Id: llex.c,v 2.19 2006/02/06 18:28:16 roberto Exp roberto $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <locale.h>
10#include <string.h>
11
12#define llex_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldo.h"
18#include "llex.h"
19#include "lobject.h"
20#include "lparser.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "ltable.h"
24#include "lzio.h"
25
26
27
28#define next(ls) (ls->current = zgetc(ls->z))
29
30
31
32
33#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
34
35
36/* ORDER RESERVED */
37const char *const luaX_tokens [] = {
38 "and", "break", "do", "else", "elseif",
39 "end", "false", "for", "function", "if",
40 "in", "local", "nil", "not", "or", "repeat",
41 "return", "then", "true", "until", "while",
42 "..", "...", "==", ">=", "<=", "~=",
43 "<number>", "<name>", "<string>", "<eof>",
44 NULL
45};
46
47
48#define save_and_next(ls) (save(ls, ls->current), next(ls))
49
50
51static void save (LexState *ls, int c) {
52 Mbuffer *b = ls->buff;
53 if (b->n + 1 > b->buffsize) {
54 size_t newsize;
55 if (b->buffsize >= MAX_SIZET/2)
56 luaX_lexerror(ls, "lexical element too long", 0);
57 newsize = b->buffsize * 2;
58 luaZ_resizebuffer(ls->L, b, newsize);
59 }
60 b->buffer[b->n++] = cast(char, c);
61}
62
63
64void luaX_init (lua_State *L) {
65 int i;
66 for (i=0; i<NUM_RESERVED; i++) {
67 TString *ts = luaS_new(L, luaX_tokens[i]);
68 luaS_fix(ts); /* reserved words are never collected */
69 lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
70 ts->tsv.reserved = cast_byte(i+1); /* reserved word */
71 }
72}
73
74
75#define MAXSRC 80
76
77
78const char *luaX_token2str (LexState *ls, int token) {
79 if (token < FIRST_RESERVED) {
80 lua_assert(token == cast(unsigned char, token));
81 return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
82 luaO_pushfstring(ls->L, "%c", token);
83 }
84 else
85 return luaX_tokens[token-FIRST_RESERVED];
86}
87
88
89static const char *txtToken (LexState *ls, int token) {
90 switch (token) {
91 case TK_NAME:
92 case TK_STRING:
93 case TK_NUMBER:
94 save(ls, '\0');
95 return luaZ_buffer(ls->buff);
96 default:
97 return luaX_token2str(ls, token);
98 }
99}
100
101
102void luaX_lexerror (LexState *ls, const char *msg, int token) {
103 char buff[MAXSRC];
104 luaO_chunkid(buff, getstr(ls->source), MAXSRC);
105 msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
106 if (token)
107 luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
108 luaD_throw(ls->L, LUA_ERRSYNTAX);
109}
110
111
112void luaX_syntaxerror (LexState *ls, const char *msg) {
113 luaX_lexerror(ls, msg, ls->t.token);
114}
115
116
117TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
118 lua_State *L = ls->L;
119 TString *ts = luaS_newlstr(L, str, l);
120 TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
121 if (ttisnil(o))
122 setbvalue(o, 1); /* make sure `str' will not be collected */
123 return ts;
124}
125
126
127static void inclinenumber (LexState *ls) {
128 int old = ls->current;
129 lua_assert(currIsNewline(ls));
130 next(ls); /* skip `\n' or `\r' */
131 if (currIsNewline(ls) && ls->current != old)
132 next(ls); /* skip `\n\r' or `\r\n' */
133 if (++ls->linenumber >= MAX_INT)
134 luaX_syntaxerror(ls, "chunk has too many lines");
135}
136
137
138void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
139 ls->decpoint = '.';
140 ls->L = L;
141 ls->lookahead.token = TK_EOS; /* no look-ahead token */
142 ls->z = z;
143 ls->fs = NULL;
144 ls->linenumber = 1;
145 ls->lastline = 1;
146 ls->source = source;
147 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
148 next(ls); /* read first char */
149}
150
151
152
153/*
154** =======================================================
155** LEXICAL ANALYZER
156** =======================================================
157*/
158
159
160
161static int check_next (LexState *ls, const char *set) {
162 if (!strchr(set, ls->current))
163 return 0;
164 save_and_next(ls);
165 return 1;
166}
167
168
169static void buffreplace (LexState *ls, char from, char to) {
170 size_t n = luaZ_bufflen(ls->buff);
171 char *p = luaZ_buffer(ls->buff);
172 while (n--)
173 if (p[n] == from) p[n] = to;
174}
175
176
177static void trydecpoint (LexState *ls, SemInfo *seminfo) {
178 /* format error: try to update decimal point separator */
179 struct lconv *cv = localeconv();
180 char old = ls->decpoint;
181 ls->decpoint = (cv ? cv->decimal_point[0] : '.');
182 buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
183 if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
184 /* format error with correct decimal point: no more options */
185 buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
186 luaX_lexerror(ls, "malformed number", TK_NUMBER);
187 }
188}
189
190
191/* LUA_NUMBER */
192static void read_numeral (LexState *ls, SemInfo *seminfo) {
193 lua_assert(isdigit(ls->current));
194 do {
195 save_and_next(ls);
196 } while (isdigit(ls->current) || ls->current == '.');
197 if (check_next(ls, "Ee")) /* `E'? */
198 check_next(ls, "+-"); /* optional exponent sign */
199 while (isalnum(ls->current) || ls->current == '_')
200 save_and_next(ls);
201 save(ls, '\0');
202 buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
203 if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
204 trydecpoint(ls, seminfo); /* try to update decimal point separator */
205}
206
207
208static int skip_sep (LexState *ls) {
209 int count = 0;
210 int s = ls->current;
211 lua_assert(s == '[' || s == ']');
212 save_and_next(ls);
213 while (ls->current == '=') {
214 save_and_next(ls);
215 count++;
216 }
217 return (ls->current == s) ? count : (-count) - 1;
218}
219
220
221static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
222 int cont = 0;
223 (void)(cont); /* avoid warnings when `cont' is not used */
224 save_and_next(ls); /* skip 2nd `[' */
225 if (currIsNewline(ls)) /* string starts with a newline? */
226 inclinenumber(ls); /* skip it */
227 for (;;) {
228 switch (ls->current) {
229 case EOZ:
230 luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
231 "unfinished long comment", TK_EOS);
232 break; /* to avoid warnings */
233#if defined(LUA_COMPAT_LSTR)
234 case '[': {
235 if (skip_sep(ls) == sep) {
236 save_and_next(ls); /* skip 2nd `[' */
237 cont++;
238#if LUA_COMPAT_LSTR == 1
239 if (sep == 0)
240 luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
241#endif
242 }
243 break;
244 }
245#endif
246 case ']': {
247 if (skip_sep(ls) == sep) {
248 save_and_next(ls); /* skip 2nd `]' */
249#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
250 cont--;
251 if (sep == 0 && cont >= 0) break;
252#endif
253 goto endloop;
254 }
255 break;
256 }
257 case '\n':
258 case '\r': {
259 save(ls, '\n');
260 inclinenumber(ls);
261 if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
262 break;
263 }
264 default: {
265 if (seminfo) save_and_next(ls);
266 else next(ls);
267 }
268 }
269 } endloop:
270 if (seminfo)
271 seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
272 luaZ_bufflen(ls->buff) - 2*(2 + sep));
273}
274
275
276static void read_string (LexState *ls, int del, SemInfo *seminfo) {
277 save_and_next(ls);
278 while (ls->current != del) {
279 switch (ls->current) {
280 case EOZ:
281 luaX_lexerror(ls, "unfinished string", TK_EOS);
282 continue; /* to avoid warnings */
283 case '\n':
284 case '\r':
285 luaX_lexerror(ls, "unfinished string", TK_STRING);
286 continue; /* to avoid warnings */
287 case '\\': {
288 int c;
289 next(ls); /* do not save the `\' */
290 switch (ls->current) {
291 case 'a': c = '\a'; break;
292 case 'b': c = '\b'; break;
293 case 'f': c = '\f'; break;
294 case 'n': c = '\n'; break;
295 case 'r': c = '\r'; break;
296 case 't': c = '\t'; break;
297 case 'v': c = '\v'; break;
298 case '\n': /* go through */
299 case '\r': save(ls, '\n'); inclinenumber(ls); continue;
300 case EOZ: continue; /* will raise an error next loop */
301 default: {
302 if (!isdigit(ls->current))
303 save_and_next(ls); /* handles \\, \", \', and \? */
304 else { /* \xxx */
305 int i = 0;
306 c = 0;
307 do {
308 c = 10*c + (ls->current-'0');
309 next(ls);
310 } while (++i<3 && isdigit(ls->current));
311 if (c > UCHAR_MAX)
312 luaX_lexerror(ls, "escape sequence too large", TK_STRING);
313 save(ls, c);
314 }
315 continue;
316 }
317 }
318 save(ls, c);
319 next(ls);
320 continue;
321 }
322 default:
323 save_and_next(ls);
324 }
325 }
326 save_and_next(ls); /* skip delimiter */
327 seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
328 luaZ_bufflen(ls->buff) - 2);
329}
330
331
332static int llex (LexState *ls, SemInfo *seminfo) {
333 luaZ_resetbuffer(ls->buff);
334 for (;;) {
335 switch (ls->current) {
336 case '\n':
337 case '\r': {
338 inclinenumber(ls);
339 continue;
340 }
341 case '-': {
342 next(ls);
343 if (ls->current != '-') return '-';
344 /* else is a comment */
345 next(ls);
346 if (ls->current == '[') {
347 int sep = skip_sep(ls);
348 luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
349 if (sep >= 0) {
350 read_long_string(ls, NULL, sep); /* long comment */
351 luaZ_resetbuffer(ls->buff);
352 continue;
353 }
354 }
355 /* else short comment */
356 while (!currIsNewline(ls) && ls->current != EOZ)
357 next(ls);
358 continue;
359 }
360 case '[': {
361 int sep = skip_sep(ls);
362 if (sep >= 0) {
363 read_long_string(ls, seminfo, sep);
364 return TK_STRING;
365 }
366 else if (sep == -1) return '[';
367 else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
368 }
369 case '=': {
370 next(ls);
371 if (ls->current != '=') return '=';
372 else { next(ls); return TK_EQ; }
373 }
374 case '<': {
375 next(ls);
376 if (ls->current != '=') return '<';
377 else { next(ls); return TK_LE; }
378 }
379 case '>': {
380 next(ls);
381 if (ls->current != '=') return '>';
382 else { next(ls); return TK_GE; }
383 }
384 case '~': {
385 next(ls);
386 if (ls->current != '=') return '~';
387 else { next(ls); return TK_NE; }
388 }
389 case '"':
390 case '\'': {
391 read_string(ls, ls->current, seminfo);
392 return TK_STRING;
393 }
394 case '.': {
395 save_and_next(ls);
396 if (check_next(ls, ".")) {
397 if (check_next(ls, "."))
398 return TK_DOTS; /* ... */
399 else return TK_CONCAT; /* .. */
400 }
401 else if (!isdigit(ls->current)) return '.';
402 else {
403 read_numeral(ls, seminfo);
404 return TK_NUMBER;
405 }
406 }
407 case EOZ: {
408 return TK_EOS;
409 }
410 default: {
411 if (isspace(ls->current)) {
412 lua_assert(!currIsNewline(ls));
413 next(ls);
414 continue;
415 }
416 else if (isdigit(ls->current)) {
417 read_numeral(ls, seminfo);
418 return TK_NUMBER;
419 }
420 else if (isalpha(ls->current) || ls->current == '_') {
421 /* identifier or reserved word */
422 TString *ts;
423 do {
424 save_and_next(ls);
425 } while (isalnum(ls->current) || ls->current == '_');
426 ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
427 luaZ_bufflen(ls->buff));
428 if (ts->tsv.reserved > 0) /* reserved word? */
429 return ts->tsv.reserved - 1 + FIRST_RESERVED;
430 else {
431 seminfo->ts = ts;
432 return TK_NAME;
433 }
434 }
435 else {
436 int c = ls->current;
437 next(ls);
438 return c; /* single-char tokens (+ - / ...) */
439 }
440 }
441 }
442 }
443}
444
445
446void luaX_next (LexState *ls) {
447 ls->lastline = ls->linenumber;
448 if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
449 ls->t = ls->lookahead; /* use this one */
450 ls->lookahead.token = TK_EOS; /* and discharge it */
451 }
452 else
453 ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
454}
455
456
457void luaX_lookahead (LexState *ls) {
458 lua_assert(ls->lookahead.token == TK_EOS);
459 ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
460}
461
diff --git a/llex.h b/llex.h
deleted file mode 100644
index cbe88403..00000000
--- a/llex.h
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2** $Id: llex.h,v 1.57 2005/12/07 15:43:05 roberto Exp roberto $
3** Lexical Analyzer
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llex_h
8#define llex_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13
14#define FIRST_RESERVED 257
15
16/* maximum length of a reserved word */
17#define TOKEN_LEN (sizeof("function")/sizeof(char))
18
19
20/*
21* WARNING: if you change the order of this enumeration,
22* grep "ORDER RESERVED"
23*/
24enum RESERVED {
25 /* terminal symbols denoted by reserved words */
26 TK_AND = FIRST_RESERVED, TK_BREAK,
27 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
28 TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
29 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
30 /* other terminal symbols */
31 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
32 TK_NAME, TK_STRING, TK_EOS
33};
34
35/* number of reserved words */
36#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
37
38
39/* array with token `names' */
40LUAI_DATA const char *const luaX_tokens [];
41
42
43typedef union {
44 lua_Number r;
45 TString *ts;
46} SemInfo; /* semantics information */
47
48
49typedef struct Token {
50 int token;
51 SemInfo seminfo;
52} Token;
53
54
55typedef struct LexState {
56 int current; /* current character (charint) */
57 int linenumber; /* input line counter */
58 int lastline; /* line of last token `consumed' */
59 Token t; /* current token */
60 Token lookahead; /* look ahead token */
61 struct FuncState *fs; /* `FuncState' is private to the parser */
62 struct lua_State *L;
63 ZIO *z; /* input stream */
64 Mbuffer *buff; /* buffer for tokens */
65 TString *source; /* current source name */
66 char decpoint; /* locale decimal point */
67} LexState;
68
69
70LUAI_FUNC void luaX_init (lua_State *L);
71LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
72 TString *source);
73LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
74LUAI_FUNC void luaX_next (LexState *ls);
75LUAI_FUNC void luaX_lookahead (LexState *ls);
76LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
77LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
78LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
79
80
81#endif
diff --git a/llimits.h b/llimits.h
deleted file mode 100644
index e0065649..00000000
--- a/llimits.h
+++ /dev/null
@@ -1,128 +0,0 @@
1/*
2** $Id: llimits.h,v 1.68 2005/12/22 16:19:56 roberto Exp roberto $
3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h
5*/
6
7#ifndef llimits_h
8#define llimits_h
9
10
11#include <limits.h>
12#include <stddef.h>
13
14
15#include "lua.h"
16
17
18typedef LUAI_UINT32 lu_int32;
19
20typedef LUAI_UMEM lu_mem;
21
22typedef LUAI_MEM l_mem;
23
24
25
26/* chars used as small naturals (so that `char' is reserved for characters) */
27typedef unsigned char lu_byte;
28
29
30#define MAX_SIZET ((size_t)(~(size_t)0)-2)
31
32#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
33
34
35#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
36
37/*
38** conversion of pointer to integer
39** this is for hashing only; there is no problem if the integer
40** cannot hold the whole pointer value
41*/
42#define IntPoint(p) ((unsigned int)(lu_mem)(p))
43
44
45
46/* type to ensure maximum alignment */
47typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
48
49
50/* result of a `usual argument conversion' over lua_Number */
51typedef LUAI_UACNUMBER l_uacNumber;
52
53
54/* internal assertions for in-house debugging */
55#ifdef lua_assert
56
57#define check_exp(c,e) (lua_assert(c), (e))
58#define api_check(l,e) lua_assert(e)
59
60#else
61
62#define lua_assert(c) ((void)0)
63#define check_exp(c,e) (e)
64#define api_check luai_apicheck
65
66#endif
67
68
69#ifndef UNUSED
70#define UNUSED(x) ((void)(x)) /* to avoid warnings */
71#endif
72
73
74#ifndef cast
75#define cast(t, exp) ((t)(exp))
76#endif
77
78#define cast_byte(i) cast(lu_byte, (i))
79#define cast_num(i) cast(lua_Number, (i))
80#define cast_int(i) cast(int, (i))
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*/
88typedef lu_int32 Instruction;
89
90
91
92/* maximum stack for a Lua function */
93#define MAXSTACK 250
94
95
96
97/* minimum size for the string table (must be power of 2) */
98#ifndef MINSTRTABSIZE
99#define MINSTRTABSIZE 32
100#endif
101
102
103/* minimum size for string buffer */
104#ifndef LUA_MINBUFFER
105#define LUA_MINBUFFER 32
106#endif
107
108
109#ifndef lua_lock
110#define lua_lock(L) ((void) 0)
111#define lua_unlock(L) ((void) 0)
112#endif
113
114#ifndef luai_threadyield
115#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
116#endif
117
118
119/*
120** macro to control inclusion of some hard tests on stack reallocation
121*/
122#ifndef HARDSTACKTESTS
123#define condhardstacktests(x) ((void)0)
124#else
125#define condhardstacktests(x) x
126#endif
127
128#endif
diff --git a/lmathlib.c b/lmathlib.c
deleted file mode 100644
index 9be0f160..00000000
--- a/lmathlib.c
+++ /dev/null
@@ -1,263 +0,0 @@
1/*
2** $Id: lmathlib.c,v 1.66 2005/08/15 14:12:32 roberto Exp roberto $
3** Standard mathematical library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9#include <math.h>
10
11#define lmathlib_c
12#define LUA_LIB
13
14#include "lua.h"
15
16#include "lauxlib.h"
17#include "lualib.h"
18
19
20#undef PI
21#define PI (3.14159265358979323846)
22#define RADIANS_PER_DEGREE (PI/180.0)
23
24
25
26static int math_abs (lua_State *L) {
27 lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
28 return 1;
29}
30
31static int math_sin (lua_State *L) {
32 lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
33 return 1;
34}
35
36static int math_sinh (lua_State *L) {
37 lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
38 return 1;
39}
40
41static int math_cos (lua_State *L) {
42 lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
43 return 1;
44}
45
46static int math_cosh (lua_State *L) {
47 lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
48 return 1;
49}
50
51static int math_tan (lua_State *L) {
52 lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
53 return 1;
54}
55
56static int math_tanh (lua_State *L) {
57 lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
58 return 1;
59}
60
61static int math_asin (lua_State *L) {
62 lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
63 return 1;
64}
65
66static int math_acos (lua_State *L) {
67 lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
68 return 1;
69}
70
71static int math_atan (lua_State *L) {
72 lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
73 return 1;
74}
75
76static int math_atan2 (lua_State *L) {
77 lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
78 return 1;
79}
80
81static int math_ceil (lua_State *L) {
82 lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
83 return 1;
84}
85
86static int math_floor (lua_State *L) {
87 lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
88 return 1;
89}
90
91static int math_fmod (lua_State *L) {
92 lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
93 return 1;
94}
95
96static int math_modf (lua_State *L) {
97 double ip;
98 double fp = modf(luaL_checknumber(L, 1), &ip);
99 lua_pushnumber(L, ip);
100 lua_pushnumber(L, fp);
101 return 2;
102}
103
104static int math_sqrt (lua_State *L) {
105 lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
106 return 1;
107}
108
109static int math_pow (lua_State *L) {
110 lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
111 return 1;
112}
113
114static int math_log (lua_State *L) {
115 lua_pushnumber(L, log(luaL_checknumber(L, 1)));
116 return 1;
117}
118
119static int math_log10 (lua_State *L) {
120 lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
121 return 1;
122}
123
124static int math_exp (lua_State *L) {
125 lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
126 return 1;
127}
128
129static int math_deg (lua_State *L) {
130 lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
131 return 1;
132}
133
134static int math_rad (lua_State *L) {
135 lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
136 return 1;
137}
138
139static int math_frexp (lua_State *L) {
140 int e;
141 lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
142 lua_pushinteger(L, e);
143 return 2;
144}
145
146static int math_ldexp (lua_State *L) {
147 lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
148 return 1;
149}
150
151
152
153static int math_min (lua_State *L) {
154 int n = lua_gettop(L); /* number of arguments */
155 lua_Number dmin = luaL_checknumber(L, 1);
156 int i;
157 for (i=2; i<=n; i++) {
158 lua_Number d = luaL_checknumber(L, i);
159 if (d < dmin)
160 dmin = d;
161 }
162 lua_pushnumber(L, dmin);
163 return 1;
164}
165
166
167static int math_max (lua_State *L) {
168 int n = lua_gettop(L); /* number of arguments */
169 lua_Number dmax = luaL_checknumber(L, 1);
170 int i;
171 for (i=2; i<=n; i++) {
172 lua_Number d = luaL_checknumber(L, i);
173 if (d > dmax)
174 dmax = d;
175 }
176 lua_pushnumber(L, dmax);
177 return 1;
178}
179
180
181static int math_random (lua_State *L) {
182 /* the `%' avoids the (rare) case of r==1, and is needed also because on
183 some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
184 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
185 switch (lua_gettop(L)) { /* check number of arguments */
186 case 0: { /* no arguments */
187 lua_pushnumber(L, r); /* Number between 0 and 1 */
188 break;
189 }
190 case 1: { /* only upper limit */
191 int u = luaL_checkint(L, 1);
192 luaL_argcheck(L, 1<=u, 1, "interval is empty");
193 lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
194 break;
195 }
196 case 2: { /* lower and upper limits */
197 int l = luaL_checkint(L, 1);
198 int u = luaL_checkint(L, 2);
199 luaL_argcheck(L, l<=u, 2, "interval is empty");
200 lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
201 break;
202 }
203 default: return luaL_error(L, "wrong number of arguments");
204 }
205 return 1;
206}
207
208
209static int math_randomseed (lua_State *L) {
210 srand(luaL_checkint(L, 1));
211 return 0;
212}
213
214
215static const luaL_Reg mathlib[] = {
216 {"abs", math_abs},
217 {"acos", math_acos},
218 {"asin", math_asin},
219 {"atan2", math_atan2},
220 {"atan", math_atan},
221 {"ceil", math_ceil},
222 {"cosh", math_cosh},
223 {"cos", math_cos},
224 {"deg", math_deg},
225 {"exp", math_exp},
226 {"floor", math_floor},
227 {"fmod", math_fmod},
228 {"frexp", math_frexp},
229 {"ldexp", math_ldexp},
230 {"log10", math_log10},
231 {"log", math_log},
232 {"max", math_max},
233 {"min", math_min},
234 {"modf", math_modf},
235 {"pow", math_pow},
236 {"rad", math_rad},
237 {"random", math_random},
238 {"randomseed", math_randomseed},
239 {"sinh", math_sinh},
240 {"sin", math_sin},
241 {"sqrt", math_sqrt},
242 {"tanh", math_tanh},
243 {"tan", math_tan},
244 {NULL, NULL}
245};
246
247
248/*
249** Open math library
250*/
251LUALIB_API int luaopen_math (lua_State *L) {
252 luaL_register(L, LUA_MATHLIBNAME, mathlib);
253 lua_pushnumber(L, PI);
254 lua_setfield(L, -2, "pi");
255 lua_pushnumber(L, HUGE_VAL);
256 lua_setfield(L, -2, "huge");
257#if defined(LUA_COMPAT_MOD)
258 lua_getfield(L, -1, "fmod");
259 lua_setfield(L, -2, "mod");
260#endif
261 return 1;
262}
263
diff --git a/lmem.c b/lmem.c
deleted file mode 100644
index 1a3e25c4..00000000
--- a/lmem.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2** $Id: lmem.c,v 1.69 2005/02/23 17:30:22 roberto Exp roberto $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lmem_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "ldebug.h"
16#include "ldo.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstate.h"
20
21
22
23/*
24** About the realloc function:
25** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
26** (`osize' is the old size, `nsize' is the new size)
27**
28** Lua ensures that (ptr == NULL) iff (osize == 0).
29**
30** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
31**
32** * frealloc(ud, p, x, 0) frees the block `p'
33** (in this specific case, frealloc must return NULL).
34** particularly, frealloc(ud, NULL, 0, 0) does nothing
35** (which is equivalent to free(NULL) in ANSI C)
36**
37** frealloc returns NULL if it cannot create or reallocate the area
38** (any reallocation to an equal or smaller size cannot fail!)
39*/
40
41
42
43#define MINSIZEARRAY 4
44
45
46void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
47 int limit, const char *errormsg) {
48 void *newblock;
49 int newsize;
50 if (*size >= limit/2) { /* cannot double it? */
51 if (*size >= limit) /* cannot grow even a little? */
52 luaG_runerror(L, errormsg);
53 newsize = limit; /* still have at least one free place */
54 }
55 else {
56 newsize = (*size)*2;
57 if (newsize < MINSIZEARRAY)
58 newsize = MINSIZEARRAY; /* minimum size */
59 }
60 newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
61 *size = newsize; /* update only when everything else is OK */
62 return newblock;
63}
64
65
66void *luaM_toobig (lua_State *L) {
67 luaG_runerror(L, "memory allocation error: block too big");
68 return NULL; /* to avoid warnings */
69}
70
71
72
73/*
74** generic allocation routine.
75*/
76void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
77 global_State *g = G(L);
78 lua_assert((osize == 0) == (block == NULL));
79 block = (*g->frealloc)(g->ud, block, osize, nsize);
80 if (block == NULL && nsize > 0)
81 luaD_throw(L, LUA_ERRMEM);
82 lua_assert((nsize == 0) == (block == NULL));
83 g->totalbytes = (g->totalbytes - osize) + nsize;
84 return block;
85}
86
diff --git a/lmem.h b/lmem.h
deleted file mode 100644
index d6bbdd9f..00000000
--- a/lmem.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2** $Id: lmem.h,v 1.30 2005/03/18 16:38:02 roberto Exp roberto $
3** Interface to Memory Manager
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lmem_h
8#define lmem_h
9
10
11#include <stddef.h>
12
13#include "llimits.h"
14#include "lua.h"
15
16#define MEMERRMSG "not enough memory"
17
18
19#define luaM_reallocv(L,b,on,n,e) \
20 ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
21 luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
22 luaM_toobig(L))
23
24#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
25#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
26#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
27
28#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
29#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
30#define luaM_newvector(L,n,t) \
31 cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
32
33#define luaM_growvector(L,v,nelems,size,t,limit,e) \
34 if ((nelems)+1 > (size)) \
35 ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
36
37#define luaM_reallocvector(L, v,oldn,n,t) \
38 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
39
40
41LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
42 size_t size);
43LUAI_FUNC void *luaM_toobig (lua_State *L);
44LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
45 size_t size_elem, int limit,
46 const char *errormsg);
47
48#endif
49
diff --git a/loadlib.c b/loadlib.c
deleted file mode 100644
index b9ac3761..00000000
--- a/loadlib.c
+++ /dev/null
@@ -1,663 +0,0 @@
1/*
2** $Id: loadlib.c,v 1.51 2005/12/29 15:32:11 roberto Exp roberto $
3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h
5**
6** This module contains an implementation of loadlib for Unix systems
7** that have dlfcn, an implementation for Darwin (Mac OS X), an
8** implementation for Windows, and a stub for other systems.
9*/
10
11
12#include <stdlib.h>
13#include <string.h>
14
15
16#define loadlib_c
17#define LUA_LIB
18
19#include "lauxlib.h"
20#include "lobject.h"
21#include "lua.h"
22#include "lualib.h"
23
24
25/* prefix for open functions in C libraries */
26#define LUA_POF "luaopen_"
27
28/* separator for open functions in C libraries */
29#define LUA_OFSEP "_"
30
31
32#define LIBPREFIX "LOADLIB: "
33
34#define POF LUA_POF
35#define LIB_FAIL "open"
36
37
38/* error codes for ll_loadfunc */
39#define ERRLIB 1
40#define ERRFUNC 2
41
42#define setprogdir(L) ((void)0)
43
44
45static void ll_unloadlib (void *lib);
46static void *ll_load (lua_State *L, const char *path);
47static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
48
49
50
51#if defined(LUA_DL_DLOPEN)
52/*
53** {========================================================================
54** This is an implementation of loadlib based on the dlfcn interface.
55** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
56** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
57** as an emulation layer on top of native functions.
58** =========================================================================
59*/
60
61#include <dlfcn.h>
62
63static void ll_unloadlib (void *lib) {
64 dlclose(lib);
65}
66
67
68static void *ll_load (lua_State *L, const char *path) {
69 void *lib = dlopen(path, RTLD_NOW);
70 if (lib == NULL) lua_pushstring(L, dlerror());
71 return lib;
72}
73
74
75static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
76 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
77 if (f == NULL) lua_pushstring(L, dlerror());
78 return f;
79}
80
81/* }====================================================== */
82
83
84
85#elif defined(LUA_DL_DLL)
86/*
87** {======================================================================
88** This is an implementation of loadlib for Windows using native functions.
89** =======================================================================
90*/
91
92#include <windows.h>
93
94
95#undef setprogdir
96
97static void setprogdir (lua_State *L) {
98 char buff[MAX_PATH + 1];
99 char *lb;
100 DWORD nsize = sizeof(buff)/sizeof(char);
101 DWORD n = GetModuleFileName(NULL, buff, nsize);
102 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
103 luaL_error(L, "unable to get ModuleFileName");
104 else {
105 *lb = '\0';
106 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
107 lua_remove(L, -2); /* remove original string */
108 }
109}
110
111
112static void pusherror (lua_State *L) {
113 int error = GetLastError();
114 char buffer[128];
115 if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
116 NULL, error, 0, buffer, sizeof(buffer), NULL))
117 lua_pushstring(L, buffer);
118 else
119 lua_pushfstring(L, "system error %d\n", error);
120}
121
122static void ll_unloadlib (void *lib) {
123 FreeLibrary((HINSTANCE)lib);
124}
125
126
127static void *ll_load (lua_State *L, const char *path) {
128 HINSTANCE lib = LoadLibrary(path);
129 if (lib == NULL) pusherror(L);
130 return lib;
131}
132
133
134static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
135 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
136 if (f == NULL) pusherror(L);
137 return f;
138}
139
140/* }====================================================== */
141
142
143
144#elif defined(LUA_DL_DYLD)
145/*
146** {======================================================================
147** Native Mac OS X / Darwin Implementation
148** =======================================================================
149*/
150
151#include <mach-o/dyld.h>
152
153
154/* Mac appends a `_' before C function names */
155#undef POF
156#define POF "_" LUA_POF
157
158
159static void pusherror (lua_State *L) {
160 const char *err_str;
161 const char *err_file;
162 NSLinkEditErrors err;
163 int err_num;
164 NSLinkEditError(&err, &err_num, &err_file, &err_str);
165 lua_pushstring(L, err_str);
166}
167
168
169static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
170 switch (ret) {
171 case NSObjectFileImageInappropriateFile:
172 return "file is not a bundle";
173 case NSObjectFileImageArch:
174 return "library is for wrong CPU type";
175 case NSObjectFileImageFormat:
176 return "bad format";
177 case NSObjectFileImageAccess:
178 return "cannot access file";
179 case NSObjectFileImageFailure:
180 default:
181 return "unable to load library";
182 }
183}
184
185
186static void ll_unloadlib (void *lib) {
187 NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
188}
189
190
191static void *ll_load (lua_State *L, const char *path) {
192 NSObjectFileImage img;
193 NSObjectFileImageReturnCode ret;
194 /* this would be a rare case, but prevents crashing if it happens */
195 if(!_dyld_present()) {
196 lua_pushliteral(L, "dyld not present");
197 return NULL;
198 }
199 ret = NSCreateObjectFileImageFromFile(path, &img);
200 if (ret == NSObjectFileImageSuccess) {
201 NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
202 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
203 NSDestroyObjectFileImage(img);
204 if (mod == NULL) pusherror(L);
205 return mod;
206 }
207 lua_pushstring(L, errorfromcode(ret));
208 return NULL;
209}
210
211
212static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
213 NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
214 if (nss == NULL) {
215 lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
216 return NULL;
217 }
218 return (lua_CFunction)NSAddressOfSymbol(nss);
219}
220
221/* }====================================================== */
222
223
224
225#else
226/*
227** {======================================================
228** Fallback for other systems
229** =======================================================
230*/
231
232#undef LIB_FAIL
233#define LIB_FAIL "absent"
234
235
236#define DLMSG "dynamic libraries not enabled; check your Lua installation"
237
238
239static void ll_unloadlib (void *lib) {
240 (void)lib; /* to avoid warnings */
241}
242
243
244static void *ll_load (lua_State *L, const char *path) {
245 (void)path; /* to avoid warnings */
246 lua_pushliteral(L, DLMSG);
247 return NULL;
248}
249
250
251static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
252 (void)lib; (void)sym; /* to avoid warnings */
253 lua_pushliteral(L, DLMSG);
254 return NULL;
255}
256
257/* }====================================================== */
258#endif
259
260
261
262static void **ll_register (lua_State *L, const char *path) {
263 void **plib;
264 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
265 lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
266 if (!lua_isnil(L, -1)) /* is there an entry? */
267 plib = (void **)lua_touserdata(L, -1);
268 else { /* no entry yet; create one */
269 lua_pop(L, 1);
270 plib = (void **)lua_newuserdata(L, sizeof(const void *));
271 *plib = NULL;
272 luaL_getmetatable(L, "_LOADLIB");
273 lua_setmetatable(L, -2);
274 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
275 lua_pushvalue(L, -2);
276 lua_settable(L, LUA_REGISTRYINDEX);
277 }
278 return plib;
279}
280
281
282/*
283** __gc tag method: calls library's `ll_unloadlib' function with the lib
284** handle
285*/
286static int gctm (lua_State *L) {
287 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
288 if (*lib) ll_unloadlib(*lib);
289 *lib = NULL; /* mark library as closed */
290 return 0;
291}
292
293
294static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
295 void **reg = ll_register(L, path);
296 if (*reg == NULL) *reg = ll_load(L, path);
297 if (*reg == NULL)
298 return ERRLIB; /* unable to load library */
299 else {
300 lua_CFunction f = ll_sym(L, *reg, sym);
301 if (f == NULL)
302 return ERRFUNC; /* unable to find function */
303 lua_pushcfunction(L, f);
304 return 0; /* return function */
305 }
306}
307
308
309static int ll_loadlib (lua_State *L) {
310 const char *path = luaL_checkstring(L, 1);
311 const char *init = luaL_checkstring(L, 2);
312 int stat = ll_loadfunc(L, path, init);
313 if (stat == 0) /* no errors? */
314 return 1; /* return the loaded function */
315 else { /* error; error message is on stack top */
316 lua_pushnil(L);
317 lua_insert(L, -2);
318 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
319 return 3; /* return nil, error message, and where */
320 }
321}
322
323
324
325/*
326** {======================================================
327** 'require' function
328** =======================================================
329*/
330
331
332static int readable (const char *filename) {
333 FILE *f = fopen(filename, "r"); /* try to open file */
334 if (f == NULL) return 0; /* open failed */
335 fclose(f);
336 return 1;
337}
338
339
340static const char *pushnexttemplate (lua_State *L, const char *path) {
341 const char *l;
342 while (*path == *LUA_PATHSEP) path++; /* skip separators */
343 if (*path == '\0') return NULL; /* no more templates */
344 l = strchr(path, *LUA_PATHSEP); /* find next separator */
345 if (l == NULL) l = path + strlen(path);
346 lua_pushlstring(L, path, l - path); /* template */
347 return l;
348}
349
350
351static const char *findfile (lua_State *L, const char *name,
352 const char *pname) {
353 const char *path;
354 name = luaL_gsub(L, name, ".", LUA_DIRSEP);
355 lua_getfield(L, LUA_ENVIRONINDEX, pname);
356 path = lua_tostring(L, -1);
357 if (path == NULL)
358 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
359 lua_pushstring(L, ""); /* error accumulator */
360 while ((path = pushnexttemplate(L, path)) != NULL) {
361 const char *filename;
362 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
363 if (readable(filename)) /* does file exist and is readable? */
364 return filename; /* return that file name */
365 lua_pop(L, 2); /* remove path template and file name */
366 luaO_pushfstring(L, "\n\tno file " LUA_QS, filename);
367 lua_concat(L, 2);
368 }
369 return NULL; /* not found */
370}
371
372
373static void loaderror (lua_State *L, const char *filename) {
374 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
375 lua_tostring(L, 1), filename, lua_tostring(L, -1));
376}
377
378
379static int loader_Lua (lua_State *L) {
380 const char *filename;
381 const char *name = luaL_checkstring(L, 1);
382 filename = findfile(L, name, "path");
383 if (filename == NULL) return 1; /* library not found in this path */
384 if (luaL_loadfile(L, filename) != 0)
385 loaderror(L, filename);
386 return 1; /* library loaded successfully */
387}
388
389
390static const char *mkfuncname (lua_State *L, const char *modname) {
391 const char *funcname;
392 const char *mark = strchr(modname, *LUA_IGMARK);
393 if (mark) modname = mark + 1;
394 funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
395 funcname = lua_pushfstring(L, POF"%s", funcname);
396 lua_remove(L, -2); /* remove 'gsub' result */
397 return funcname;
398}
399
400
401static int loader_C (lua_State *L) {
402 const char *funcname;
403 const char *name = luaL_checkstring(L, 1);
404 const char *filename = findfile(L, name, "cpath");
405 if (filename == NULL) return 1; /* library not found in this path */
406 funcname = mkfuncname(L, name);
407 if (ll_loadfunc(L, filename, funcname) != 0)
408 loaderror(L, filename);
409 return 1; /* library loaded successfully */
410}
411
412
413static int loader_Croot (lua_State *L) {
414 const char *funcname;
415 const char *filename;
416 const char *name = luaL_checkstring(L, 1);
417 const char *p = strchr(name, '.');
418 int stat;
419 if (p == NULL) return 0; /* is root */
420 lua_pushlstring(L, name, p - name);
421 filename = findfile(L, lua_tostring(L, -1), "cpath");
422 if (filename == NULL) return 1; /* root not found */
423 funcname = mkfuncname(L, name);
424 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
425 if (stat != ERRFUNC) loaderror(L, filename); /* real error */
426 luaO_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
427 name, filename);
428 return 1; /* function not found */
429 }
430 return 1;
431}
432
433
434static int loader_preload (lua_State *L) {
435 const char *name = luaL_checkstring(L, 1);
436 lua_getfield(L, LUA_ENVIRONINDEX, "preload");
437 if (!lua_istable(L, -1))
438 luaL_error(L, LUA_QL("package.preload") " must be a table");
439 lua_getfield(L, -1, name);
440 if (lua_isnil(L, -1)) /* not found? */
441 luaO_pushfstring(L, "\n\tno field package.preload['%s']", name);
442 return 1;
443}
444
445
446static const int sentinel_ = 0;
447#define sentinel ((void *)&sentinel_)
448
449
450static int ll_require (lua_State *L) {
451 const char *name = luaL_checkstring(L, 1);
452 int i;
453 lua_settop(L, 1); /* _LOADED table will be at index 2 */
454 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
455 lua_getfield(L, 2, name);
456 if (lua_toboolean(L, -1)) { /* is it there? */
457 if (lua_touserdata(L, -1) == sentinel) /* check loops */
458 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
459 return 1; /* package is already loaded */
460 }
461 /* else must load it; iterate over available loaders */
462 lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
463 if (!lua_istable(L, -1))
464 luaL_error(L, LUA_QL("package.loaders") " must be a table");
465 lua_pushstring(L, ""); /* error message accumulator */
466 for (i=1; ; i++) {
467 lua_rawgeti(L, -2, i); /* get a loader */
468 if (lua_isnil(L, -1))
469 luaL_error(L, "module " LUA_QS " not found:%s",
470 name, lua_tostring(L, -2));
471 lua_pushstring(L, name);
472 lua_call(L, 1, 1); /* call it */
473 if (lua_isfunction(L, -1)) /* did it find module? */
474 break; /* module loaded successfully */
475 else if (lua_isstring(L, -1)) /* loader returned error message? */
476 lua_concat(L, 2); /* accumulate it */
477 else
478 lua_pop(L, 1);
479 }
480 lua_pushlightuserdata(L, sentinel);
481 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
482 lua_pushstring(L, name); /* pass name as argument to module */
483 lua_call(L, 1, 1); /* run loaded module */
484 if (!lua_isnil(L, -1)) /* non-nil return? */
485 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
486 lua_getfield(L, 2, name);
487 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
488 lua_pushboolean(L, 1); /* use true as result */
489 lua_pushvalue(L, -1); /* extra copy to be returned */
490 lua_setfield(L, 2, name); /* _LOADED[name] = true */
491 }
492 return 1;
493}
494
495/* }====================================================== */
496
497
498
499/*
500** {======================================================
501** 'module' function
502** =======================================================
503*/
504
505
506static void setfenv (lua_State *L) {
507 lua_Debug ar;
508 lua_getstack(L, 1, &ar);
509 lua_getinfo(L, "f", &ar);
510 lua_pushvalue(L, -2);
511 lua_setfenv(L, -2);
512 lua_pop(L, 1);
513}
514
515
516static void dooptions (lua_State *L, int n) {
517 int i;
518 for (i = 2; i <= n; i++) {
519 lua_pushvalue(L, i); /* get option (a function) */
520 lua_pushvalue(L, -2); /* module */
521 lua_call(L, 1, 0);
522 }
523}
524
525
526static void modinit (lua_State *L, const char *modname) {
527 const char *dot;
528 lua_pushvalue(L, -1);
529 lua_setfield(L, -2, "_M"); /* module._M = module */
530 lua_pushstring(L, modname);
531 lua_setfield(L, -2, "_NAME");
532 dot = strrchr(modname, '.'); /* look for last dot in module name */
533 if (dot == NULL) dot = modname;
534 else dot++;
535 /* set _PACKAGE as package name (full module name minus last part) */
536 lua_pushlstring(L, modname, dot - modname);
537 lua_setfield(L, -2, "_PACKAGE");
538}
539
540
541static int ll_module (lua_State *L) {
542 const char *modname = luaL_checkstring(L, 1);
543 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
544 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
545 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
546 if (!lua_istable(L, -1)) { /* not found? */
547 lua_pop(L, 1); /* remove previous result */
548 /* try global variable (and create one if it does not exist) */
549 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
550 return luaL_error(L, "name conflict for module " LUA_QS, modname);
551 lua_pushvalue(L, -1);
552 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
553 }
554 /* check whether table already has a _NAME field */
555 lua_getfield(L, -1, "_NAME");
556 if (!lua_isnil(L, -1)) /* is table an initialized module? */
557 lua_pop(L, 1);
558 else { /* no; initialize it */
559 lua_pop(L, 1);
560 modinit(L, modname);
561 }
562 lua_pushvalue(L, -1);
563 setfenv(L);
564 dooptions(L, loaded - 1);
565 return 0;
566}
567
568
569static int ll_seeall (lua_State *L) {
570 luaL_checktype(L, 1, LUA_TTABLE);
571 if (!lua_getmetatable(L, 1)) {
572 lua_createtable(L, 0, 1); /* create new metatable */
573 lua_pushvalue(L, -1);
574 lua_setmetatable(L, 1);
575 }
576 lua_pushvalue(L, LUA_GLOBALSINDEX);
577 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
578 return 0;
579}
580
581
582/* }====================================================== */
583
584
585
586/* auxiliary mark (for internal use) */
587#define AUXMARK "\1"
588
589static void setpath (lua_State *L, const char *fieldname, const char *envname,
590 const char *def) {
591 const char *path = getenv(envname);
592 if (path == NULL) /* no environment variable? */
593 lua_pushstring(L, def); /* use default */
594 else {
595 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
596 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
597 LUA_PATHSEP AUXMARK LUA_PATHSEP);
598 luaL_gsub(L, path, AUXMARK, def);
599 lua_remove(L, -2);
600 }
601 setprogdir(L);
602 lua_setfield(L, -2, fieldname);
603}
604
605
606static const luaL_Reg pk_funcs[] = {
607 {"loadlib", ll_loadlib},
608 {"seeall", ll_seeall},
609 {NULL, NULL}
610};
611
612
613static const luaL_Reg ll_funcs[] = {
614 {"module", ll_module},
615 {"require", ll_require},
616 {NULL, NULL}
617};
618
619
620static const lua_CFunction loaders[] =
621 {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
622
623
624LUALIB_API int luaopen_package (lua_State *L) {
625 int i;
626 /* create new type _LOADLIB */
627 luaL_newmetatable(L, "_LOADLIB");
628 lua_pushcfunction(L, gctm);
629 lua_setfield(L, -2, "__gc");
630 /* create `package' table */
631 luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
632#if defined(LUA_COMPAT_LOADLIB)
633 lua_getfield(L, -1, "loadlib");
634 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
635#endif
636 lua_pushvalue(L, -1);
637 lua_replace(L, LUA_ENVIRONINDEX);
638 /* create `loaders' table */
639 lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1);
640 /* fill it with pre-defined loaders */
641 for (i=0; loaders[i] != NULL; i++) {
642 lua_pushcfunction(L, loaders[i]);
643 lua_rawseti(L, -2, i+1);
644 }
645 lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
646 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
647 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
648 /* store config information */
649 lua_pushstring(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
650 LUA_EXECDIR "\n" LUA_IGMARK);
651 lua_setfield(L, -2, "config");
652 /* set field `loaded' */
653 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
654 lua_setfield(L, -2, "loaded");
655 /* set field `preload' */
656 lua_newtable(L);
657 lua_setfield(L, -2, "preload");
658 lua_pushvalue(L, LUA_GLOBALSINDEX);
659 luaL_register(L, NULL, ll_funcs); /* open lib into global table */
660 lua_pop(L, 1);
661 return 1; /* return 'package' table */
662}
663
diff --git a/lobject.c b/lobject.c
deleted file mode 100644
index a7ee87a6..00000000
--- a/lobject.c
+++ /dev/null
@@ -1,214 +0,0 @@
1/*
2** $Id: lobject.c,v 2.21 2006/01/10 12:50:00 roberto Exp roberto $
3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h
5*/
6
7#include <ctype.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define lobject_c
14#define LUA_CORE
15
16#include "lua.h"
17
18#include "ldo.h"
19#include "lmem.h"
20#include "lobject.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "lvm.h"
24
25
26
27const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
28
29
30/*
31** converts an integer to a "floating point byte", represented as
32** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
33** eeeee != 0 and (xxx) otherwise.
34*/
35int luaO_int2fb (unsigned int x) {
36 int e = 0; /* expoent */
37 while (x >= 16) {
38 x = (x+1) >> 1;
39 e++;
40 }
41 if (x < 8) return x;
42 else return ((e+1) << 3) | (cast_int(x) - 8);
43}
44
45
46/* converts back */
47int luaO_fb2int (int x) {
48 int e = (x >> 3) & 31;
49 if (e == 0) return x;
50 else return ((x & 7)+8) << (e - 1);
51}
52
53
54int luaO_log2 (unsigned int x) {
55 static const lu_byte log_2[256] = {
56 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
57 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
58 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
61 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
62 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
63 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
64 };
65 int l = -1;
66 while (x >= 256) { l += 8; x >>= 8; }
67 return l + log_2[x];
68
69}
70
71
72int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
73 if (ttype(t1) != ttype(t2)) return 0;
74 else switch (ttype(t1)) {
75 case LUA_TNIL:
76 return 1;
77 case LUA_TNUMBER:
78 return luai_numeq(nvalue(t1), nvalue(t2));
79 case LUA_TBOOLEAN:
80 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
81 case LUA_TLIGHTUSERDATA:
82 return pvalue(t1) == pvalue(t2);
83 default:
84 lua_assert(iscollectable(t1));
85 return gcvalue(t1) == gcvalue(t2);
86 }
87}
88
89
90int luaO_str2d (const char *s, lua_Number *result) {
91 char *endptr;
92 *result = lua_str2number(s, &endptr);
93 if (endptr == s) return 0; /* conversion failed */
94 if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
95 *result = cast_num(strtoul(s, &endptr, 16));
96 if (*endptr == '\0') return 1; /* most common case */
97 while (isspace(cast(unsigned char, *endptr))) endptr++;
98 if (*endptr != '\0') return 0; /* invalid trailing characters? */
99 return 1;
100}
101
102
103
104static void pushstr (lua_State *L, const char *str) {
105 setsvalue2s(L, L->top, luaS_new(L, str));
106 incr_top(L);
107}
108
109
110/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
111const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
112 int n = 1;
113 pushstr(L, "");
114 for (;;) {
115 const char *e = strchr(fmt, '%');
116 if (e == NULL) break;
117 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
118 incr_top(L);
119 switch (*(e+1)) {
120 case 's': {
121 const char *s = va_arg(argp, char *);
122 if (s == NULL) s = "(null)";
123 pushstr(L, s);
124 break;
125 }
126 case 'c': {
127 char buff[2];
128 buff[0] = cast(char, va_arg(argp, int));
129 buff[1] = '\0';
130 pushstr(L, buff);
131 break;
132 }
133 case 'd': {
134 setnvalue(L->top, cast_num(va_arg(argp, int)));
135 incr_top(L);
136 break;
137 }
138 case 'f': {
139 setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
140 incr_top(L);
141 break;
142 }
143 case 'p': {
144 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
145 sprintf(buff, "%p", va_arg(argp, void *));
146 pushstr(L, buff);
147 break;
148 }
149 case '%': {
150 pushstr(L, "%");
151 break;
152 }
153 default: {
154 char buff[3];
155 buff[0] = '%';
156 buff[1] = *(e+1);
157 buff[2] = '\0';
158 pushstr(L, buff);
159 break;
160 }
161 }
162 n += 2;
163 fmt = e+2;
164 }
165 pushstr(L, fmt);
166 luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
167 L->top -= n;
168 return svalue(L->top - 1);
169}
170
171
172const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
173 const char *msg;
174 va_list argp;
175 va_start(argp, fmt);
176 msg = luaO_pushvfstring(L, fmt, argp);
177 va_end(argp);
178 return msg;
179}
180
181
182void luaO_chunkid (char *out, const char *source, size_t bufflen) {
183 if (*source == '=') {
184 strncpy(out, source+1, bufflen); /* remove first char */
185 out[bufflen-1] = '\0'; /* ensures null termination */
186 }
187 else { /* out = "source", or "...source" */
188 if (*source == '@') {
189 size_t l;
190 source++; /* skip the `@' */
191 bufflen -= sizeof(" '...' ");
192 l = strlen(source);
193 strcpy(out, "");
194 if (l > bufflen) {
195 source += (l-bufflen); /* get last part of file name */
196 strcat(out, "...");
197 }
198 strcat(out, source);
199 }
200 else { /* out = [string "string"] */
201 size_t len = strcspn(source, "\n\r"); /* stop at first newline */
202 bufflen -= sizeof(" [string \"...\"] ");
203 if (len > bufflen) len = bufflen;
204 strcpy(out, "[string \"");
205 if (source[len] != '\0') { /* must truncate? */
206 strncat(out, source, len);
207 strcat(out, "...");
208 }
209 else
210 strcat(out, source);
211 strcat(out, "\"]");
212 }
213 }
214}
diff --git a/lobject.h b/lobject.h
deleted file mode 100644
index 76221587..00000000
--- a/lobject.h
+++ /dev/null
@@ -1,381 +0,0 @@
1/*
2** $Id: lobject.h,v 2.19 2006/01/10 12:51:53 roberto Exp roberto $
3** Type definitions for Lua objects
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lobject_h
9#define lobject_h
10
11
12#include <stdarg.h>
13
14
15#include "llimits.h"
16#include "lua.h"
17
18
19/* tags for values visible from Lua */
20#define LAST_TAG LUA_TTHREAD
21
22#define NUM_TAGS (LAST_TAG+1)
23
24
25/*
26** Extra tags for non-values
27*/
28#define LUA_TPROTO (LAST_TAG+1)
29#define LUA_TUPVAL (LAST_TAG+2)
30#define LUA_TDEADKEY (LAST_TAG+3)
31
32
33/*
34** Union of all collectable objects
35*/
36typedef union GCObject GCObject;
37
38
39/*
40** Common Header for all collectable objects (in macro form, to be
41** included in other objects)
42*/
43#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
44
45
46/*
47** Common header in struct form
48*/
49typedef struct GCheader {
50 CommonHeader;
51} GCheader;
52
53
54
55
56/*
57** Union of all Lua values
58*/
59typedef union {
60 GCObject *gc;
61 void *p;
62 lua_Number n;
63 int b;
64} Value;
65
66
67/*
68** Tagged Values
69*/
70
71#define TValuefields Value value; int tt
72
73typedef struct lua_TValue {
74 TValuefields;
75} TValue;
76
77
78/* Macros to test type */
79#define ttisnil(o) (ttype(o) == LUA_TNIL)
80#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
81#define ttisstring(o) (ttype(o) == LUA_TSTRING)
82#define ttistable(o) (ttype(o) == LUA_TTABLE)
83#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
84#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
85#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
86#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
87#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
88
89/* Macros to access values */
90#define ttype(o) ((o)->tt)
91#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
92#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
93#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
94#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
95#define tsvalue(o) (&rawtsvalue(o)->tsv)
96#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
97#define uvalue(o) (&rawuvalue(o)->uv)
98#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
99#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
100#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
101#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
102
103#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
104
105/*
106** for internal debug only
107*/
108#define checkconsistency(obj) \
109 lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
110
111#define checkliveness(g,obj) \
112 lua_assert(!iscollectable(obj) || \
113 ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
114
115
116/* Macros to set values */
117#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
118
119#define setnvalue(obj,x) \
120 { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
121
122#define setpvalue(obj,x) \
123 { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
124
125#define setbvalue(obj,x) \
126 { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
127
128#define setsvalue(L,obj,x) \
129 { TValue *i_o=(obj); \
130 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
131 checkliveness(G(L),i_o); }
132
133#define setuvalue(L,obj,x) \
134 { TValue *i_o=(obj); \
135 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
136 checkliveness(G(L),i_o); }
137
138#define setthvalue(L,obj,x) \
139 { TValue *i_o=(obj); \
140 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
141 checkliveness(G(L),i_o); }
142
143#define setclvalue(L,obj,x) \
144 { TValue *i_o=(obj); \
145 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
146 checkliveness(G(L),i_o); }
147
148#define sethvalue(L,obj,x) \
149 { TValue *i_o=(obj); \
150 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
151 checkliveness(G(L),i_o); }
152
153#define setptvalue(L,obj,x) \
154 { TValue *i_o=(obj); \
155 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
156 checkliveness(G(L),i_o); }
157
158
159
160
161#define setobj(L,obj1,obj2) \
162 { const TValue *o2=(obj2); TValue *o1=(obj1); \
163 o1->value = o2->value; o1->tt=o2->tt; \
164 checkliveness(G(L),o1); }
165
166
167/*
168** different types of sets, according to destination
169*/
170
171/* from stack to (same) stack */
172#define setobjs2s setobj
173/* to stack (not from same stack) */
174#define setobj2s setobj
175#define setsvalue2s setsvalue
176#define sethvalue2s sethvalue
177#define setptvalue2s setptvalue
178/* from table to same table */
179#define setobjt2t setobj
180/* to table */
181#define setobj2t setobj
182/* to new object */
183#define setobj2n setobj
184#define setsvalue2n setsvalue
185
186#define setttype(obj, tt) (ttype(obj) = (tt))
187
188
189#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
190
191
192
193typedef TValue *StkId; /* index to stack elements */
194
195
196/*
197** String headers for string table
198*/
199typedef union TString {
200 L_Umaxalign dummy; /* ensures maximum alignment for strings */
201 struct {
202 CommonHeader;
203 lu_byte reserved;
204 unsigned int hash;
205 size_t len;
206 } tsv;
207} TString;
208
209
210#define getstr(ts) cast(const char *, (ts) + 1)
211#define svalue(o) getstr(tsvalue(o))
212
213
214
215typedef union Udata {
216 L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
217 struct {
218 CommonHeader;
219 struct Table *metatable;
220 struct Table *env;
221 size_t len;
222 } uv;
223} Udata;
224
225
226
227
228/*
229** Function Prototypes
230*/
231typedef struct Proto {
232 CommonHeader;
233 TValue *k; /* constants used by the function */
234 Instruction *code;
235 struct Proto **p; /* functions defined inside the function */
236 int *lineinfo; /* map from opcodes to source lines */
237 struct LocVar *locvars; /* information about local variables */
238 TString **upvalues; /* upvalue names */
239 TString *source;
240 int sizeupvalues;
241 int sizek; /* size of `k' */
242 int sizecode;
243 int sizelineinfo;
244 int sizep; /* size of `p' */
245 int sizelocvars;
246 int linedefined;
247 int lastlinedefined;
248 GCObject *gclist;
249 lu_byte nups; /* number of upvalues */
250 lu_byte numparams;
251 lu_byte is_vararg;
252 lu_byte maxstacksize;
253} Proto;
254
255
256/* masks for new-style vararg */
257#define VARARG_HASARG 1
258#define VARARG_ISVARARG 2
259#define VARARG_NEEDSARG 4
260
261
262typedef struct LocVar {
263 TString *varname;
264 int startpc; /* first point where variable is active */
265 int endpc; /* first point where variable is dead */
266} LocVar;
267
268
269
270/*
271** Upvalues
272*/
273
274typedef struct UpVal {
275 CommonHeader;
276 TValue *v; /* points to stack or to its own value */
277 union {
278 TValue value; /* the value (when closed) */
279 struct { /* double linked list (when open) */
280 struct UpVal *prev;
281 struct UpVal *next;
282 } l;
283 } u;
284} UpVal;
285
286
287/*
288** Closures
289*/
290
291#define ClosureHeader \
292 CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
293 struct Table *env
294
295typedef struct CClosure {
296 ClosureHeader;
297 lua_CFunction f;
298 TValue upvalue[1];
299} CClosure;
300
301
302typedef struct LClosure {
303 ClosureHeader;
304 struct Proto *p;
305 UpVal *upvals[1];
306} LClosure;
307
308
309typedef union Closure {
310 CClosure c;
311 LClosure l;
312} Closure;
313
314
315#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
316#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
317
318
319/*
320** Tables
321*/
322
323typedef union TKey {
324 struct {
325 TValuefields;
326 struct Node *next; /* for chaining */
327 } nk;
328 TValue tvk;
329} TKey;
330
331
332typedef struct Node {
333 TValue i_val;
334 TKey i_key;
335} Node;
336
337
338typedef struct Table {
339 CommonHeader;
340 lu_byte flags; /* 1<<p means tagmethod(p) is not present */
341 lu_byte lsizenode; /* log2 of size of `node' array */
342 struct Table *metatable;
343 TValue *array; /* array part */
344 Node *node;
345 Node *lastfree; /* any free position is before this position */
346 GCObject *gclist;
347 int sizearray; /* size of `array' array */
348} Table;
349
350
351
352/*
353** `module' operation for hashing (size is always a power of 2)
354*/
355#define lmod(s,size) \
356 (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
357
358
359#define twoto(x) (1<<(x))
360#define sizenode(t) (twoto((t)->lsizenode))
361
362
363#define luaO_nilobject (&luaO_nilobject_)
364
365LUAI_DATA const TValue luaO_nilobject_;
366
367#define ceillog2(x) (luaO_log2((x)-1) + 1)
368
369LUAI_FUNC int luaO_log2 (unsigned int x);
370LUAI_FUNC int luaO_int2fb (unsigned int x);
371LUAI_FUNC int luaO_fb2int (int x);
372LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
373LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
374LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
375 va_list argp);
376LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
377LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
378
379
380#endif
381
diff --git a/lopcodes.c b/lopcodes.c
deleted file mode 100644
index 169a1730..00000000
--- a/lopcodes.c
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2** $Id: lopcodes.c,v 1.36 2005/10/13 12:22:05 roberto Exp roberto $
3** See Copyright Notice in lua.h
4*/
5
6
7#define lopcodes_c
8#define LUA_CORE
9
10
11#include "lopcodes.h"
12
13
14/* ORDER OP */
15
16const char *const luaP_opnames[NUM_OPCODES+1] = {
17 "MOVE",
18 "LOADK",
19 "LOADBOOL",
20 "LOADNIL",
21 "GETUPVAL",
22 "GETGLOBAL",
23 "GETTABLE",
24 "SETGLOBAL",
25 "SETUPVAL",
26 "SETTABLE",
27 "NEWTABLE",
28 "SELF",
29 "ADD",
30 "SUB",
31 "MUL",
32 "DIV",
33 "MOD",
34 "POW",
35 "UNM",
36 "NOT",
37 "LEN",
38 "CONCAT",
39 "JMP",
40 "EQ",
41 "LT",
42 "LE",
43 "TEST",
44 "TESTSET",
45 "CALL",
46 "TAILCALL",
47 "RETURN",
48 "FORLOOP",
49 "FORPREP",
50 "TFORLOOP",
51 "SETLIST",
52 "CLOSE",
53 "CLOSURE",
54 "VARARG",
55 NULL
56};
57
58
59#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
60
61const lu_byte luaP_opmodes[NUM_OPCODES] = {
62/* T A B C mode opcode */
63 opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
64 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
65 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
66 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
67 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
68 ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
69 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
70 ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
71 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
72 ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
73 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
74 ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
75 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
76 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
77 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
78 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
79 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
80 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
81 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
82 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
83 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
84 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
85 ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
86 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
87 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
88 ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
89 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
90 ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
91 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
92 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
93 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
94 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
95 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
96 ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
97 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
98 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
99 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
100 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
101};
102
diff --git a/lopcodes.h b/lopcodes.h
deleted file mode 100644
index dd811cac..00000000
--- a/lopcodes.h
+++ /dev/null
@@ -1,268 +0,0 @@
1/*
2** $Id: lopcodes.h,v 1.124 2005/12/02 18:42:08 roberto Exp roberto $
3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lopcodes_h
8#define lopcodes_h
9
10#include "llimits.h"
11
12
13/*===========================================================================
14 We assume that instructions are unsigned numbers.
15 All instructions have an opcode in the first 6 bits.
16 Instructions can have the following fields:
17 `A' : 8 bits
18 `B' : 9 bits
19 `C' : 9 bits
20 `Bx' : 18 bits (`B' and `C' together)
21 `sBx' : signed Bx
22
23 A signed argument is represented in excess K; that is, the number
24 value is the unsigned value minus K. K is exactly the maximum value
25 for that argument (so that -max is represented by 0, and +max is
26 represented by 2*max), which is half the maximum for the corresponding
27 unsigned argument.
28===========================================================================*/
29
30
31enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
32
33
34/*
35** size and position of opcode arguments.
36*/
37#define SIZE_C 9
38#define SIZE_B 9
39#define SIZE_Bx (SIZE_C + SIZE_B)
40#define SIZE_A 8
41
42#define SIZE_OP 6
43
44#define POS_OP 0
45#define POS_A (POS_OP + SIZE_OP)
46#define POS_C (POS_A + SIZE_A)
47#define POS_B (POS_C + SIZE_C)
48#define POS_Bx POS_C
49
50
51/*
52** limits for opcode arguments.
53** we use (signed) int to manipulate most arguments,
54** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
55*/
56#if SIZE_Bx < LUAI_BITSINT-1
57#define MAXARG_Bx ((1<<SIZE_Bx)-1)
58#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
59#else
60#define MAXARG_Bx MAX_INT
61#define MAXARG_sBx MAX_INT
62#endif
63
64
65#define MAXARG_A ((1<<SIZE_A)-1)
66#define MAXARG_B ((1<<SIZE_B)-1)
67#define MAXARG_C ((1<<SIZE_C)-1)
68
69
70/* creates a mask with `n' 1 bits at position `p' */
71#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
72
73/* creates a mask with `n' 0 bits at position `p' */
74#define MASK0(n,p) (~MASK1(n,p))
75
76/*
77** the following macros help to manipulate instructions
78*/
79
80#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
81#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
83
84#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
85#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
86 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
87
88#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
89#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
90 ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
91
92#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
93#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
94 ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
95
96#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
97#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
98 ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
99
100#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
101#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
102
103
104#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
105 | (cast(Instruction, a)<<POS_A) \
106 | (cast(Instruction, b)<<POS_B) \
107 | (cast(Instruction, c)<<POS_C))
108
109#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
110 | (cast(Instruction, a)<<POS_A) \
111 | (cast(Instruction, bc)<<POS_Bx))
112
113
114/*
115** Macros to operate RK indices
116*/
117
118/* this bit 1 means constant (0 means register) */
119#define BITRK (1 << (SIZE_B - 1))
120
121/* test whether value is a constant */
122#define ISK(x) ((x) & BITRK)
123
124/* gets the index of the constant */
125#define INDEXK(r) ((int)(r) & ~BITRK)
126
127#define MAXINDEXRK (BITRK - 1)
128
129/* code a constant index as a RK value */
130#define RKASK(x) ((x) | BITRK)
131
132
133/*
134** invalid register that fits in 8 bits
135*/
136#define NO_REG MAXARG_A
137
138
139/*
140** R(x) - register
141** Kst(x) - constant (in constant table)
142** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
143*/
144
145
146/*
147** grep "ORDER OP" if you change these enums
148*/
149
150typedef enum {
151/*----------------------------------------------------------------------
152name args description
153------------------------------------------------------------------------*/
154OP_MOVE,/* A B R(A) := R(B) */
155OP_LOADK,/* A Bx R(A) := Kst(Bx) */
156OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
157OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
158OP_GETUPVAL,/* A B R(A) := UpValue[B] */
159
160OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
161OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
162
163OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
164OP_SETUPVAL,/* A B UpValue[B] := R(A) */
165OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
166
167OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
168
169OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
170
171OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
172OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
173OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
174OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
175OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
176OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
177OP_UNM,/* A B R(A) := -R(B) */
178OP_NOT,/* A B R(A) := not R(B) */
179OP_LEN,/* A B R(A) := length of R(B) */
180
181OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
182
183OP_JMP,/* sBx pc+=sBx */
184
185OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
186OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
187OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
188
189OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
190OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
191
192OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
193OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
194OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
195
196OP_FORLOOP,/* A sBx R(A)+=R(A+2);
197 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
198OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
199
200OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
201 if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
202OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
203
204OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
205OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
206
207OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
208} OpCode;
209
210
211#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
212
213
214
215/*===========================================================================
216 Notes:
217 (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
218 and can be 0: OP_CALL then sets `top' to last_result+1, so
219 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
220
221 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222 set top (like in OP_CALL with C == 0).
223
224 (*) In OP_RETURN, if (B == 0) then return up to `top'
225
226 (*) In OP_SETLIST, if (B == 0) then B = `top';
227 if (C == 0) then next `instruction' is real C
228
229 (*) For comparisons, A specifies what condition the test should accept
230 (true or false).
231
232 (*) All `skips' (pc++) assume that next instruction is a jump
233===========================================================================*/
234
235
236/*
237** masks for instruction properties. The format is:
238** bits 0-1: op mode
239** bits 2-3: C arg mode
240** bits 4-5: B arg mode
241** bit 6: instruction set register A
242** bit 7: operator is a test
243*/
244
245enum OpArgMask {
246 OpArgN, /* argument is not used */
247 OpArgU, /* argument is used */
248 OpArgR, /* argument is a register or a jump offset */
249 OpArgK /* argument is a constant or register/constant */
250};
251
252LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
253
254#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
255#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
256#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
257#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
258#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
259
260
261LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
262
263
264/* number of list items to accumulate before a SETLIST instruction */
265#define LFIELDS_PER_FLUSH 50
266
267
268#endif
diff --git a/loslib.c b/loslib.c
deleted file mode 100644
index 3a1e8409..00000000
--- a/loslib.c
+++ /dev/null
@@ -1,233 +0,0 @@
1/*
2** $Id: loslib.c,v 1.18 2006/03/09 18:08:22 roberto Exp roberto $
3** Standard Operating System library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <locale.h>
10#include <stdlib.h>
11#include <string.h>
12#include <time.h>
13
14#define loslib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23static int os_pushresult (lua_State *L, int i, const char *filename) {
24 int en = errno; /* calls to Lua API may change this value */
25 if (i) {
26 lua_pushboolean(L, 1);
27 return 1;
28 }
29 else {
30 lua_pushnil(L);
31 lua_pushfstring(L, "%s: %s", filename, strerror(en));
32 lua_pushinteger(L, en);
33 return 3;
34 }
35}
36
37
38static int os_execute (lua_State *L) {
39 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
40 return 1;
41}
42
43
44static int os_remove (lua_State *L) {
45 const char *filename = luaL_checkstring(L, 1);
46 return os_pushresult(L, remove(filename) == 0, filename);
47}
48
49
50static int os_rename (lua_State *L) {
51 const char *fromname = luaL_checkstring(L, 1);
52 const char *toname = luaL_checkstring(L, 2);
53 return os_pushresult(L, rename(fromname, toname) == 0, fromname);
54}
55
56
57static int os_tmpname (lua_State *L) {
58 char buff[LUA_TMPNAMBUFSIZE];
59 int err;
60 lua_tmpnam(buff, err);
61 if (err)
62 return luaL_error(L, "unable to generate a unique filename");
63 lua_pushstring(L, buff);
64 return 1;
65}
66
67
68static int os_getenv (lua_State *L) {
69 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
70 return 1;
71}
72
73
74static int os_clock (lua_State *L) {
75 lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
76 return 1;
77}
78
79
80/*
81** {======================================================
82** Time/Date operations
83** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
84** wday=%w+1, yday=%j, isdst=? }
85** =======================================================
86*/
87
88static void setfield (lua_State *L, const char *key, int value) {
89 lua_pushinteger(L, value);
90 lua_setfield(L, -2, key);
91}
92
93static void setboolfield (lua_State *L, const char *key, int value) {
94 if (value < 0) /* undefined? */
95 return; /* does not set field */
96 lua_pushboolean(L, value);
97 lua_setfield(L, -2, key);
98}
99
100static int getboolfield (lua_State *L, const char *key) {
101 int res;
102 lua_getfield(L, -1, key);
103 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
104 lua_pop(L, 1);
105 return res;
106}
107
108
109static int getfield (lua_State *L, const char *key, int d) {
110 int res;
111 lua_getfield(L, -1, key);
112 if (lua_isnumber(L, -1))
113 res = (int)lua_tointeger(L, -1);
114 else {
115 if (d < 0)
116 return luaL_error(L, "field " LUA_QS " missing in date table", key);
117 res = d;
118 }
119 lua_pop(L, 1);
120 return res;
121}
122
123
124static int os_date (lua_State *L) {
125 const char *s = luaL_optstring(L, 1, "%c");
126 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
127 struct tm *stm;
128 if (*s == '!') { /* UTC? */
129 stm = gmtime(&t);
130 s++; /* skip `!' */
131 }
132 else
133 stm = localtime(&t);
134 if (stm == NULL) /* invalid date? */
135 lua_pushnil(L);
136 else if (strcmp(s, "*t") == 0) {
137 lua_createtable(L, 0, 9); /* 9 = number of fields */
138 setfield(L, "sec", stm->tm_sec);
139 setfield(L, "min", stm->tm_min);
140 setfield(L, "hour", stm->tm_hour);
141 setfield(L, "day", stm->tm_mday);
142 setfield(L, "month", stm->tm_mon+1);
143 setfield(L, "year", stm->tm_year+1900);
144 setfield(L, "wday", stm->tm_wday+1);
145 setfield(L, "yday", stm->tm_yday+1);
146 setboolfield(L, "isdst", stm->tm_isdst);
147 }
148 else {
149 char b[256];
150 if (strftime(b, sizeof(b), s, stm))
151 lua_pushstring(L, b);
152 else
153 return luaL_error(L, LUA_QL("date") " format too long");
154 }
155 return 1;
156}
157
158
159static int os_time (lua_State *L) {
160 time_t t;
161 if (lua_isnoneornil(L, 1)) /* called without args? */
162 t = time(NULL); /* get current time */
163 else {
164 struct tm ts;
165 luaL_checktype(L, 1, LUA_TTABLE);
166 lua_settop(L, 1); /* make sure table is at the top */
167 ts.tm_sec = getfield(L, "sec", 0);
168 ts.tm_min = getfield(L, "min", 0);
169 ts.tm_hour = getfield(L, "hour", 12);
170 ts.tm_mday = getfield(L, "day", -1);
171 ts.tm_mon = getfield(L, "month", -1) - 1;
172 ts.tm_year = getfield(L, "year", -1) - 1900;
173 ts.tm_isdst = getboolfield(L, "isdst");
174 t = mktime(&ts);
175 }
176 if (t == (time_t)(-1))
177 lua_pushnil(L);
178 else
179 lua_pushnumber(L, (lua_Number)t);
180 return 1;
181}
182
183
184static int os_difftime (lua_State *L) {
185 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
186 (time_t)(luaL_optnumber(L, 2, 0))));
187 return 1;
188}
189
190/* }====================================================== */
191
192
193static int os_setlocale (lua_State *L) {
194 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
195 LC_NUMERIC, LC_TIME};
196 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
197 "numeric", "time", NULL};
198 const char *l = luaL_optstring(L, 1, NULL);
199 int op = luaL_checkoption(L, 2, "all", catnames);
200 lua_pushstring(L, setlocale(cat[op], l));
201 return 1;
202}
203
204
205static int os_exit (lua_State *L) {
206 exit(luaL_optint(L, 1, EXIT_SUCCESS));
207 return 0; /* to avoid warnings */
208}
209
210static const luaL_Reg syslib[] = {
211 {"clock", os_clock},
212 {"date", os_date},
213 {"difftime", os_difftime},
214 {"execute", os_execute},
215 {"exit", os_exit},
216 {"getenv", os_getenv},
217 {"remove", os_remove},
218 {"rename", os_rename},
219 {"setlocale", os_setlocale},
220 {"time", os_time},
221 {"tmpname", os_tmpname},
222 {NULL, NULL}
223};
224
225/* }====================================================== */
226
227
228
229LUALIB_API int luaopen_os (lua_State *L) {
230 luaL_register(L, LUA_OSLIBNAME, syslib);
231 return 1;
232}
233
diff --git a/lparser.c b/lparser.c
deleted file mode 100644
index f98eb258..00000000
--- a/lparser.c
+++ /dev/null
@@ -1,1337 +0,0 @@
1/*
2** $Id: lparser.c,v 2.41 2006/03/09 18:15:48 roberto Exp roberto $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lparser_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lcode.h"
16#include "ldebug.h"
17#include "ldo.h"
18#include "lfunc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lparser.h"
24#include "lstate.h"
25#include "lstring.h"
26#include "ltable.h"
27
28
29
30#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
31
32#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
33
34#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
35
36
37/*
38** nodes for block list (list of active blocks)
39*/
40typedef struct BlockCnt {
41 struct BlockCnt *previous; /* chain */
42 int breaklist; /* list of jumps out of this loop */
43 lu_byte nactvar; /* # active locals outside the breakable structure */
44 lu_byte upval; /* true if some variable in the block is an upvalue */
45 lu_byte isbreakable; /* true if `block' is a loop */
46} BlockCnt;
47
48
49
50/*
51** prototypes for recursive non-terminal functions
52*/
53static void chunk (LexState *ls);
54static void expr (LexState *ls, expdesc *v);
55
56
57static void anchor_token (LexState *ls) {
58 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
59 TString *ts = ls->t.seminfo.ts;
60 luaX_newstring(ls, getstr(ts), ts->tsv.len);
61 }
62}
63
64
65static void error_expected (LexState *ls, int token) {
66 luaX_syntaxerror(ls,
67 luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
68}
69
70
71static void errorlimit (FuncState *fs, int limit, const char *what) {
72 const char *msg = (fs->f->linedefined == 0) ?
73 luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
74 luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
75 fs->f->linedefined, limit, what);
76 luaX_lexerror(fs->ls, msg, 0);
77}
78
79
80static int testnext (LexState *ls, int c) {
81 if (ls->t.token == c) {
82 luaX_next(ls);
83 return 1;
84 }
85 else return 0;
86}
87
88
89static void check (LexState *ls, int c) {
90 if (ls->t.token != c)
91 error_expected(ls, c);
92}
93
94static void checknext (LexState *ls, int c) {
95 check(ls, c);
96 luaX_next(ls);
97}
98
99
100#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
101
102
103
104static void check_match (LexState *ls, int what, int who, int where) {
105 if (!testnext(ls, what)) {
106 if (where == ls->linenumber)
107 error_expected(ls, what);
108 else {
109 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
110 LUA_QS " expected (to close " LUA_QS " at line %d)",
111 luaX_token2str(ls, what), luaX_token2str(ls, who), where));
112 }
113 }
114}
115
116
117static TString *str_checkname (LexState *ls) {
118 TString *ts;
119 check(ls, TK_NAME);
120 ts = ls->t.seminfo.ts;
121 luaX_next(ls);
122 return ts;
123}
124
125
126static void init_exp (expdesc *e, expkind k, int i) {
127 e->f = e->t = NO_JUMP;
128 e->k = k;
129 e->u.s.info = i;
130}
131
132
133static void codestring (LexState *ls, expdesc *e, TString *s) {
134 init_exp(e, VK, luaK_stringK(ls->fs, s));
135}
136
137
138static void checkname(LexState *ls, expdesc *e) {
139 codestring(ls, e, str_checkname(ls));
140}
141
142
143static int registerlocalvar (LexState *ls, TString *varname) {
144 FuncState *fs = ls->fs;
145 Proto *f = fs->f;
146 int oldsize = f->sizelocvars;
147 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
148 LocVar, SHRT_MAX, "too many local variables");
149 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
150 f->locvars[fs->nlocvars].varname = varname;
151 luaC_objbarrier(ls->L, f, varname);
152 return fs->nlocvars++;
153}
154
155
156#define new_localvarliteral(ls,v,n) \
157 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
158
159
160static void new_localvar (LexState *ls, TString *name, int n) {
161 FuncState *fs = ls->fs;
162 luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
163 fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
164}
165
166
167static void adjustlocalvars (LexState *ls, int nvars) {
168 FuncState *fs = ls->fs;
169 fs->nactvar = cast_byte(fs->nactvar + nvars);
170 for (; nvars; nvars--) {
171 getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
172 }
173}
174
175
176static void removevars (LexState *ls, int tolevel) {
177 FuncState *fs = ls->fs;
178 while (fs->nactvar > tolevel)
179 getlocvar(fs, --fs->nactvar).endpc = fs->pc;
180}
181
182
183static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
184 int i;
185 Proto *f = fs->f;
186 int oldsize = f->sizeupvalues;
187 for (i=0; i<f->nups; i++) {
188 if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
189 lua_assert(f->upvalues[i] == name);
190 return i;
191 }
192 }
193 /* new one */
194 luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
195 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
196 TString *, MAX_INT, "");
197 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
198 f->upvalues[f->nups] = name;
199 luaC_objbarrier(fs->L, f, name);
200 lua_assert(v->k == VLOCAL || v->k == VUPVAL);
201 fs->upvalues[f->nups].k = cast_byte(v->k);
202 fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
203 return f->nups++;
204}
205
206
207static int searchvar (FuncState *fs, TString *n) {
208 int i;
209 for (i=fs->nactvar-1; i >= 0; i--) {
210 if (n == getlocvar(fs, i).varname)
211 return i;
212 }
213 return -1; /* not found */
214}
215
216
217static void markupval (FuncState *fs, int level) {
218 BlockCnt *bl = fs->bl;
219 while (bl && bl->nactvar > level) bl = bl->previous;
220 if (bl) bl->upval = 1;
221}
222
223
224static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
225 if (fs == NULL) { /* no more levels? */
226 init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
227 return VGLOBAL;
228 }
229 else {
230 int v = searchvar(fs, n); /* look up at current level */
231 if (v >= 0) {
232 init_exp(var, VLOCAL, v);
233 if (!base)
234 markupval(fs, v); /* local will be used as an upval */
235 return VLOCAL;
236 }
237 else { /* not found at current level; try upper one */
238 if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
239 return VGLOBAL;
240 var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
241 var->k = VUPVAL; /* upvalue in this level */
242 return VUPVAL;
243 }
244 }
245}
246
247
248static void singlevar (LexState *ls, expdesc *var) {
249 TString *varname = str_checkname(ls);
250 FuncState *fs = ls->fs;
251 if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
252 var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
253}
254
255
256static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
257 FuncState *fs = ls->fs;
258 int extra = nvars - nexps;
259 if (hasmultret(e->k)) {
260 extra++; /* includes call itself */
261 if (extra < 0) extra = 0;
262 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
263 if (extra > 1) luaK_reserveregs(fs, extra-1);
264 }
265 else {
266 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
267 if (extra > 0) {
268 int reg = fs->freereg;
269 luaK_reserveregs(fs, extra);
270 luaK_nil(fs, reg, extra);
271 }
272 }
273}
274
275
276static void enterlevel (LexState *ls) {
277 if (++ls->L->nCcalls > LUAI_MAXCCALLS)
278 luaX_lexerror(ls, "chunk has too many syntax levels", 0);
279}
280
281
282#define leavelevel(ls) ((ls)->L->nCcalls--)
283
284
285static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
286 bl->breaklist = NO_JUMP;
287 bl->isbreakable = isbreakable;
288 bl->nactvar = fs->nactvar;
289 bl->upval = 0;
290 bl->previous = fs->bl;
291 fs->bl = bl;
292 lua_assert(fs->freereg == fs->nactvar);
293}
294
295
296static void leaveblock (FuncState *fs) {
297 BlockCnt *bl = fs->bl;
298 fs->bl = bl->previous;
299 removevars(fs->ls, bl->nactvar);
300 if (bl->upval)
301 luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
302 /* a block either controls scope or breaks (never both) */
303 lua_assert(!bl->isbreakable || !bl->upval);
304 lua_assert(bl->nactvar == fs->nactvar);
305 fs->freereg = fs->nactvar; /* free registers */
306 luaK_patchtohere(fs, bl->breaklist);
307}
308
309
310static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
311 FuncState *fs = ls->fs;
312 Proto *f = fs->f;
313 int oldsize = f->sizep;
314 int i;
315 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
316 MAXARG_Bx, "constant table overflow");
317 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
318 f->p[fs->np++] = func->f;
319 luaC_objbarrier(ls->L, f, func->f);
320 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
321 for (i=0; i<func->f->nups; i++) {
322 OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
323 luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
324 }
325}
326
327
328static void open_func (LexState *ls, FuncState *fs) {
329 lua_State *L = ls->L;
330 Proto *f = luaF_newproto(L);
331 fs->f = f;
332 fs->prev = ls->fs; /* linked list of funcstates */
333 fs->ls = ls;
334 fs->L = L;
335 ls->fs = fs;
336 fs->pc = 0;
337 fs->lasttarget = -1;
338 fs->jpc = NO_JUMP;
339 fs->freereg = 0;
340 fs->nk = 0;
341 fs->np = 0;
342 fs->nlocvars = 0;
343 fs->nactvar = 0;
344 fs->bl = NULL;
345 f->source = ls->source;
346 f->maxstacksize = 2; /* registers 0/1 are always valid */
347 fs->h = luaH_new(L, 0, 0);
348 /* anchor table of constants and prototype (to avoid being collected) */
349 sethvalue2s(L, L->top, fs->h);
350 incr_top(L);
351 setptvalue2s(L, L->top, f);
352 incr_top(L);
353}
354
355
356static void close_func (LexState *ls) {
357 lua_State *L = ls->L;
358 FuncState *fs = ls->fs;
359 Proto *f = fs->f;
360 removevars(ls, 0);
361 luaK_ret(fs, 0, 0); /* final return */
362 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
363 f->sizecode = fs->pc;
364 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
365 f->sizelineinfo = fs->pc;
366 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
367 f->sizek = fs->nk;
368 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
369 f->sizep = fs->np;
370 luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
371 f->sizelocvars = fs->nlocvars;
372 luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
373 f->sizeupvalues = f->nups;
374 lua_assert(luaG_checkcode(f));
375 lua_assert(fs->bl == NULL);
376 ls->fs = fs->prev;
377 L->top -= 2; /* remove table and prototype from the stack */
378 /* last token read was anchored in defunct function; must reanchor it */
379 if (fs) anchor_token(ls);
380}
381
382
383Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
384 struct LexState lexstate;
385 struct FuncState funcstate;
386 lexstate.buff = buff;
387 luaX_setinput(L, &lexstate, z, luaS_new(L, name));
388 open_func(&lexstate, &funcstate);
389 funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
390 luaX_next(&lexstate); /* read first token */
391 chunk(&lexstate);
392 check(&lexstate, TK_EOS);
393 close_func(&lexstate);
394 lua_assert(funcstate.prev == NULL);
395 lua_assert(funcstate.f->nups == 0);
396 lua_assert(lexstate.fs == NULL);
397 return funcstate.f;
398}
399
400
401
402/*============================================================*/
403/* GRAMMAR RULES */
404/*============================================================*/
405
406
407static void field (LexState *ls, expdesc *v) {
408 /* field -> ['.' | ':'] NAME */
409 FuncState *fs = ls->fs;
410 expdesc key;
411 luaK_exp2anyreg(fs, v);
412 luaX_next(ls); /* skip the dot or colon */
413 checkname(ls, &key);
414 luaK_indexed(fs, v, &key);
415}
416
417
418static void yindex (LexState *ls, expdesc *v) {
419 /* index -> '[' expr ']' */
420 luaX_next(ls); /* skip the '[' */
421 expr(ls, v);
422 luaK_exp2val(ls->fs, v);
423 checknext(ls, ']');
424}
425
426
427/*
428** {======================================================================
429** Rules for Constructors
430** =======================================================================
431*/
432
433
434struct ConsControl {
435 expdesc v; /* last list item read */
436 expdesc *t; /* table descriptor */
437 int nh; /* total number of `record' elements */
438 int na; /* total number of array elements */
439 int tostore; /* number of array elements pending to be stored */
440};
441
442
443static void recfield (LexState *ls, struct ConsControl *cc) {
444 /* recfield -> (NAME | `['exp1`]') = exp1 */
445 FuncState *fs = ls->fs;
446 int reg = ls->fs->freereg;
447 expdesc key, val;
448 int rkkey;
449 if (ls->t.token == TK_NAME) {
450 luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
451 checkname(ls, &key);
452 }
453 else /* ls->t.token == '[' */
454 yindex(ls, &key);
455 cc->nh++;
456 checknext(ls, '=');
457 rkkey = luaK_exp2RK(fs, &key);
458 expr(ls, &val);
459 luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
460 fs->freereg = reg; /* free registers */
461}
462
463
464static void closelistfield (FuncState *fs, struct ConsControl *cc) {
465 if (cc->v.k == VVOID) return; /* there is no list item */
466 luaK_exp2nextreg(fs, &cc->v);
467 cc->v.k = VVOID;
468 if (cc->tostore == LFIELDS_PER_FLUSH) {
469 luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
470 cc->tostore = 0; /* no more items pending */
471 }
472}
473
474
475static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
476 if (cc->tostore == 0) return;
477 if (hasmultret(cc->v.k)) {
478 luaK_setmultret(fs, &cc->v);
479 luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
480 cc->na--; /* do not count last expression (unknown number of elements) */
481 }
482 else {
483 if (cc->v.k != VVOID)
484 luaK_exp2nextreg(fs, &cc->v);
485 luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
486 }
487}
488
489
490static void listfield (LexState *ls, struct ConsControl *cc) {
491 expr(ls, &cc->v);
492 luaY_checklimit(ls->fs, cc->na, MAXARG_Bx, "items in a constructor");
493 cc->na++;
494 cc->tostore++;
495}
496
497
498static void constructor (LexState *ls, expdesc *t) {
499 /* constructor -> ?? */
500 FuncState *fs = ls->fs;
501 int line = ls->linenumber;
502 int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
503 struct ConsControl cc;
504 cc.na = cc.nh = cc.tostore = 0;
505 cc.t = t;
506 init_exp(t, VRELOCABLE, pc);
507 init_exp(&cc.v, VVOID, 0); /* no value (yet) */
508 luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
509 checknext(ls, '{');
510 do {
511 lua_assert(cc.v.k == VVOID || cc.tostore > 0);
512 if (ls->t.token == '}') break;
513 closelistfield(fs, &cc);
514 switch(ls->t.token) {
515 case TK_NAME: { /* may be listfields or recfields */
516 luaX_lookahead(ls);
517 if (ls->lookahead.token != '=') /* expression? */
518 listfield(ls, &cc);
519 else
520 recfield(ls, &cc);
521 break;
522 }
523 case '[': { /* constructor_item -> recfield */
524 recfield(ls, &cc);
525 break;
526 }
527 default: { /* constructor_part -> listfield */
528 listfield(ls, &cc);
529 break;
530 }
531 }
532 } while (testnext(ls, ',') || testnext(ls, ';'));
533 check_match(ls, '}', '{', line);
534 lastlistfield(fs, &cc);
535 SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
536 SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
537}
538
539/* }====================================================================== */
540
541
542
543static void parlist (LexState *ls) {
544 /* parlist -> [ param { `,' param } ] */
545 FuncState *fs = ls->fs;
546 Proto *f = fs->f;
547 int nparams = 0;
548 f->is_vararg = 0;
549 if (ls->t.token != ')') { /* is `parlist' not empty? */
550 do {
551 switch (ls->t.token) {
552 case TK_NAME: { /* param -> NAME */
553 new_localvar(ls, str_checkname(ls), nparams++);
554 break;
555 }
556 case TK_DOTS: { /* param -> `...' */
557 luaX_next(ls);
558#if defined(LUA_COMPAT_VARARG)
559 /* use `arg' as default name */
560 new_localvarliteral(ls, "arg", nparams++);
561 f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
562#endif
563 f->is_vararg |= VARARG_ISVARARG;
564 break;
565 }
566 default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
567 }
568 } while (!f->is_vararg && testnext(ls, ','));
569 }
570 adjustlocalvars(ls, nparams);
571 f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
572 luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
573}
574
575
576static void body (LexState *ls, expdesc *e, int needself, int line) {
577 /* body -> `(' parlist `)' chunk END */
578 FuncState new_fs;
579 open_func(ls, &new_fs);
580 new_fs.f->linedefined = line;
581 checknext(ls, '(');
582 if (needself) {
583 new_localvarliteral(ls, "self", 0);
584 adjustlocalvars(ls, 1);
585 }
586 parlist(ls);
587 checknext(ls, ')');
588 chunk(ls);
589 new_fs.f->lastlinedefined = ls->linenumber;
590 check_match(ls, TK_END, TK_FUNCTION, line);
591 close_func(ls);
592 pushclosure(ls, &new_fs, e);
593}
594
595
596static int explist1 (LexState *ls, expdesc *v) {
597 /* explist1 -> expr { `,' expr } */
598 int n = 1; /* at least one expression */
599 expr(ls, v);
600 while (testnext(ls, ',')) {
601 luaK_exp2nextreg(ls->fs, v);
602 expr(ls, v);
603 n++;
604 }
605 return n;
606}
607
608
609static void funcargs (LexState *ls, expdesc *f) {
610 FuncState *fs = ls->fs;
611 expdesc args;
612 int base, nparams;
613 int line = ls->linenumber;
614 switch (ls->t.token) {
615 case '(': { /* funcargs -> `(' [ explist1 ] `)' */
616 if (line != ls->lastline)
617 luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
618 luaX_next(ls);
619 if (ls->t.token == ')') /* arg list is empty? */
620 args.k = VVOID;
621 else {
622 explist1(ls, &args);
623 luaK_setmultret(fs, &args);
624 }
625 check_match(ls, ')', '(', line);
626 break;
627 }
628 case '{': { /* funcargs -> constructor */
629 constructor(ls, &args);
630 break;
631 }
632 case TK_STRING: { /* funcargs -> STRING */
633 codestring(ls, &args, ls->t.seminfo.ts);
634 luaX_next(ls); /* must use `seminfo' before `next' */
635 break;
636 }
637 default: {
638 luaX_syntaxerror(ls, "function arguments expected");
639 return;
640 }
641 }
642 lua_assert(f->k == VNONRELOC);
643 base = f->u.s.info; /* base register for call */
644 if (hasmultret(args.k))
645 nparams = LUA_MULTRET; /* open call */
646 else {
647 if (args.k != VVOID)
648 luaK_exp2nextreg(fs, &args); /* close last argument */
649 nparams = fs->freereg - (base+1);
650 }
651 init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
652 luaK_fixline(fs, line);
653 fs->freereg = base+1; /* call remove function and arguments and leaves
654 (unless changed) one result */
655}
656
657
658
659
660/*
661** {======================================================================
662** Expression parsing
663** =======================================================================
664*/
665
666
667static void prefixexp (LexState *ls, expdesc *v) {
668 /* prefixexp -> NAME | '(' expr ')' */
669 switch (ls->t.token) {
670 case '(': {
671 int line = ls->linenumber;
672 luaX_next(ls);
673 expr(ls, v);
674 check_match(ls, ')', '(', line);
675 luaK_dischargevars(ls->fs, v);
676 return;
677 }
678 case TK_NAME: {
679 singlevar(ls, v);
680 return;
681 }
682 default: {
683 luaX_syntaxerror(ls, "unexpected symbol");
684 return;
685 }
686 }
687}
688
689
690static void primaryexp (LexState *ls, expdesc *v) {
691 /* primaryexp ->
692 prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
693 FuncState *fs = ls->fs;
694 prefixexp(ls, v);
695 for (;;) {
696 switch (ls->t.token) {
697 case '.': { /* field */
698 field(ls, v);
699 break;
700 }
701 case '[': { /* `[' exp1 `]' */
702 expdesc key;
703 luaK_exp2anyreg(fs, v);
704 yindex(ls, &key);
705 luaK_indexed(fs, v, &key);
706 break;
707 }
708 case ':': { /* `:' NAME funcargs */
709 expdesc key;
710 luaX_next(ls);
711 checkname(ls, &key);
712 luaK_self(fs, v, &key);
713 funcargs(ls, v);
714 break;
715 }
716 case '(': case TK_STRING: case '{': { /* funcargs */
717 luaK_exp2nextreg(fs, v);
718 funcargs(ls, v);
719 break;
720 }
721 default: return;
722 }
723 }
724}
725
726
727static void simpleexp (LexState *ls, expdesc *v) {
728 /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
729 constructor | FUNCTION body | primaryexp */
730 switch (ls->t.token) {
731 case TK_NUMBER: {
732 init_exp(v, VKNUM, 0);
733 v->u.nval = ls->t.seminfo.r;
734 break;
735 }
736 case TK_STRING: {
737 codestring(ls, v, ls->t.seminfo.ts);
738 break;
739 }
740 case TK_NIL: {
741 init_exp(v, VNIL, 0);
742 break;
743 }
744 case TK_TRUE: {
745 init_exp(v, VTRUE, 0);
746 break;
747 }
748 case TK_FALSE: {
749 init_exp(v, VFALSE, 0);
750 break;
751 }
752 case TK_DOTS: { /* vararg */
753 FuncState *fs = ls->fs;
754 check_condition(ls, fs->f->is_vararg,
755 "cannot use " LUA_QL("...") " outside a vararg function");
756 fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
757 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
758 break;
759 }
760 case '{': { /* constructor */
761 constructor(ls, v);
762 return;
763 }
764 case TK_FUNCTION: {
765 luaX_next(ls);
766 body(ls, v, 0, ls->linenumber);
767 return;
768 }
769 default: {
770 primaryexp(ls, v);
771 return;
772 }
773 }
774 luaX_next(ls);
775}
776
777
778static UnOpr getunopr (int op) {
779 switch (op) {
780 case TK_NOT: return OPR_NOT;
781 case '-': return OPR_MINUS;
782 case '#': return OPR_LEN;
783 default: return OPR_NOUNOPR;
784 }
785}
786
787
788static BinOpr getbinopr (int op) {
789 switch (op) {
790 case '+': return OPR_ADD;
791 case '-': return OPR_SUB;
792 case '*': return OPR_MUL;
793 case '/': return OPR_DIV;
794 case '%': return OPR_MOD;
795 case '^': return OPR_POW;
796 case TK_CONCAT: return OPR_CONCAT;
797 case TK_NE: return OPR_NE;
798 case TK_EQ: return OPR_EQ;
799 case '<': return OPR_LT;
800 case TK_LE: return OPR_LE;
801 case '>': return OPR_GT;
802 case TK_GE: return OPR_GE;
803 case TK_AND: return OPR_AND;
804 case TK_OR: return OPR_OR;
805 default: return OPR_NOBINOPR;
806 }
807}
808
809
810static const struct {
811 lu_byte left; /* left priority for each binary operator */
812 lu_byte right; /* right priority */
813} priority[] = { /* ORDER OPR */
814 {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
815 {10, 9}, {5, 4}, /* power and concat (right associative) */
816 {3, 3}, {3, 3}, /* equality and inequality */
817 {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
818 {2, 2}, {1, 1} /* logical (and/or) */
819};
820
821#define UNARY_PRIORITY 8 /* priority for unary operators */
822
823
824/*
825** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
826** where `binop' is any binary operator with a priority higher than `limit'
827*/
828static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
829 BinOpr op;
830 UnOpr uop;
831 enterlevel(ls);
832 uop = getunopr(ls->t.token);
833 if (uop != OPR_NOUNOPR) {
834 luaX_next(ls);
835 subexpr(ls, v, UNARY_PRIORITY);
836 luaK_prefix(ls->fs, uop, v);
837 }
838 else simpleexp(ls, v);
839 /* expand while operators have priorities higher than `limit' */
840 op = getbinopr(ls->t.token);
841 while (op != OPR_NOBINOPR && priority[op].left > limit) {
842 expdesc v2;
843 BinOpr nextop;
844 luaX_next(ls);
845 luaK_infix(ls->fs, op, v);
846 /* read sub-expression with higher priority */
847 nextop = subexpr(ls, &v2, priority[op].right);
848 luaK_posfix(ls->fs, op, v, &v2);
849 op = nextop;
850 }
851 leavelevel(ls);
852 return op; /* return first untreated operator */
853}
854
855
856static void expr (LexState *ls, expdesc *v) {
857 subexpr(ls, v, 0);
858}
859
860/* }==================================================================== */
861
862
863
864/*
865** {======================================================================
866** Rules for Statements
867** =======================================================================
868*/
869
870
871static int block_follow (int token) {
872 switch (token) {
873 case TK_ELSE: case TK_ELSEIF: case TK_END:
874 case TK_UNTIL: case TK_EOS:
875 return 1;
876 default: return 0;
877 }
878}
879
880
881static void block (LexState *ls) {
882 /* block -> chunk */
883 FuncState *fs = ls->fs;
884 BlockCnt bl;
885 enterblock(fs, &bl, 0);
886 chunk(ls);
887 lua_assert(bl.breaklist == NO_JUMP);
888 leaveblock(fs);
889}
890
891
892/*
893** structure to chain all variables in the left-hand side of an
894** assignment
895*/
896struct LHS_assign {
897 struct LHS_assign *prev;
898 expdesc v; /* variable (global, local, upvalue, or indexed) */
899};
900
901
902/*
903** check whether, in an assignment to a local variable, the local variable
904** is needed in a previous assignment (to a table). If so, save original
905** local value in a safe place and use this safe copy in the previous
906** assignment.
907*/
908static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
909 FuncState *fs = ls->fs;
910 int extra = fs->freereg; /* eventual position to save local variable */
911 int conflict = 0;
912 for (; lh; lh = lh->prev) {
913 if (lh->v.k == VINDEXED) {
914 if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
915 conflict = 1;
916 lh->v.u.s.info = extra; /* previous assignment will use safe copy */
917 }
918 if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
919 conflict = 1;
920 lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
921 }
922 }
923 }
924 if (conflict) {
925 luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
926 luaK_reserveregs(fs, 1);
927 }
928}
929
930
931static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
932 expdesc e;
933 check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
934 "syntax error");
935 if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
936 struct LHS_assign nv;
937 nv.prev = lh;
938 primaryexp(ls, &nv.v);
939 if (nv.v.k == VLOCAL)
940 check_conflict(ls, lh, &nv.v);
941 assignment(ls, &nv, nvars+1);
942 }
943 else { /* assignment -> `=' explist1 */
944 int nexps;
945 checknext(ls, '=');
946 nexps = explist1(ls, &e);
947 if (nexps != nvars) {
948 adjust_assign(ls, nvars, nexps, &e);
949 if (nexps > nvars)
950 ls->fs->freereg -= nexps - nvars; /* remove extra values */
951 }
952 else {
953 luaK_setoneret(ls->fs, &e); /* close last expression */
954 luaK_storevar(ls->fs, &lh->v, &e);
955 return; /* avoid default */
956 }
957 }
958 init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
959 luaK_storevar(ls->fs, &lh->v, &e);
960}
961
962
963static int cond (LexState *ls) {
964 /* cond -> exp */
965 expdesc v;
966 expr(ls, &v); /* read condition */
967 if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
968 luaK_goiftrue(ls->fs, &v);
969 return v.f;
970}
971
972
973static void breakstat (LexState *ls) {
974 FuncState *fs = ls->fs;
975 BlockCnt *bl = fs->bl;
976 int upval = 0;
977 while (bl && !bl->isbreakable) {
978 upval |= bl->upval;
979 bl = bl->previous;
980 }
981 if (!bl)
982 luaX_syntaxerror(ls, "no loop to break");
983 if (upval)
984 luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
985 luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
986}
987
988
989static void whilestat (LexState *ls, int line) {
990 /* whilestat -> WHILE cond DO block END */
991 FuncState *fs = ls->fs;
992 int whileinit;
993 int condexit;
994 BlockCnt bl;
995 luaX_next(ls); /* skip WHILE */
996 whileinit = luaK_getlabel(fs);
997 condexit = cond(ls);
998 enterblock(fs, &bl, 1);
999 checknext(ls, TK_DO);
1000 block(ls);
1001 luaK_patchlist(fs, luaK_jump(fs), whileinit);
1002 check_match(ls, TK_END, TK_WHILE, line);
1003 leaveblock(fs);
1004 luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
1005}
1006
1007
1008static void repeatstat (LexState *ls, int line) {
1009 /* repeatstat -> REPEAT block UNTIL cond */
1010 int condexit;
1011 FuncState *fs = ls->fs;
1012 int repeat_init = luaK_getlabel(fs);
1013 BlockCnt bl1, bl2;
1014 enterblock(fs, &bl1, 1); /* loop block */
1015 enterblock(fs, &bl2, 0); /* scope block */
1016 luaX_next(ls); /* skip REPEAT */
1017 chunk(ls);
1018 check_match(ls, TK_UNTIL, TK_REPEAT, line);
1019 condexit = cond(ls); /* read condition (inside scope block) */
1020 if (!bl2.upval) { /* no upvalues? */
1021 leaveblock(fs); /* finish scope */
1022 luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
1023 }
1024 else { /* complete semantics when there are upvalues */
1025 breakstat(ls); /* if condition then break */
1026 luaK_patchtohere(ls->fs, condexit); /* else... */
1027 leaveblock(fs); /* finish scope... */
1028 luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
1029 }
1030 leaveblock(fs); /* finish loop */
1031}
1032
1033
1034static int exp1 (LexState *ls) {
1035 expdesc e;
1036 int k;
1037 expr(ls, &e);
1038 k = e.k;
1039 luaK_exp2nextreg(ls->fs, &e);
1040 return k;
1041}
1042
1043
1044static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1045 /* forbody -> DO block */
1046 BlockCnt bl;
1047 FuncState *fs = ls->fs;
1048 int prep, endfor;
1049 adjustlocalvars(ls, 3); /* control variables */
1050 checknext(ls, TK_DO);
1051 prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
1052 enterblock(fs, &bl, 0); /* scope for declared variables */
1053 adjustlocalvars(ls, nvars);
1054 luaK_reserveregs(fs, nvars);
1055 block(ls);
1056 leaveblock(fs); /* end of scope for declared variables */
1057 luaK_patchtohere(fs, prep);
1058 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
1059 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
1060 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
1061 luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
1062}
1063
1064
1065static void fornum (LexState *ls, TString *varname, int line) {
1066 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1067 FuncState *fs = ls->fs;
1068 int base = fs->freereg;
1069 new_localvarliteral(ls, "(for index)", 0);
1070 new_localvarliteral(ls, "(for limit)", 1);
1071 new_localvarliteral(ls, "(for step)", 2);
1072 new_localvar(ls, varname, 3);
1073 checknext(ls, '=');
1074 exp1(ls); /* initial value */
1075 checknext(ls, ',');
1076 exp1(ls); /* limit */
1077 if (testnext(ls, ','))
1078 exp1(ls); /* optional step */
1079 else { /* default step = 1 */
1080 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1081 luaK_reserveregs(fs, 1);
1082 }
1083 forbody(ls, base, line, 1, 1);
1084}
1085
1086
1087static void forlist (LexState *ls, TString *indexname) {
1088 /* forlist -> NAME {,NAME} IN explist1 forbody */
1089 FuncState *fs = ls->fs;
1090 expdesc e;
1091 int nvars = 0;
1092 int line;
1093 int base = fs->freereg;
1094 /* create control variables */
1095 new_localvarliteral(ls, "(for generator)", nvars++);
1096 new_localvarliteral(ls, "(for state)", nvars++);
1097 new_localvarliteral(ls, "(for control)", nvars++);
1098 /* create declared variables */
1099 new_localvar(ls, indexname, nvars++);
1100 while (testnext(ls, ','))
1101 new_localvar(ls, str_checkname(ls), nvars++);
1102 checknext(ls, TK_IN);
1103 line = ls->linenumber;
1104 adjust_assign(ls, 3, explist1(ls, &e), &e);
1105 luaK_checkstack(fs, 3); /* extra space to call generator */
1106 forbody(ls, base, line, nvars - 3, 0);
1107}
1108
1109
1110static void forstat (LexState *ls, int line) {
1111 /* forstat -> FOR (fornum | forlist) END */
1112 FuncState *fs = ls->fs;
1113 TString *varname;
1114 BlockCnt bl;
1115 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1116 luaX_next(ls); /* skip `for' */
1117 varname = str_checkname(ls); /* first variable name */
1118 switch (ls->t.token) {
1119 case '=': fornum(ls, varname, line); break;
1120 case ',': case TK_IN: forlist(ls, varname); break;
1121 default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
1122 }
1123 check_match(ls, TK_END, TK_FOR, line);
1124 leaveblock(fs); /* loop scope (`break' jumps to this point) */
1125}
1126
1127
1128static int test_then_block (LexState *ls) {
1129 /* test_then_block -> [IF | ELSEIF] cond THEN block */
1130 int condexit;
1131 luaX_next(ls); /* skip IF or ELSEIF */
1132 condexit = cond(ls);
1133 checknext(ls, TK_THEN);
1134 block(ls); /* `then' part */
1135 return condexit;
1136}
1137
1138
1139static void ifstat (LexState *ls, int line) {
1140 /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
1141 FuncState *fs = ls->fs;
1142 int flist;
1143 int escapelist = NO_JUMP;
1144 flist = test_then_block(ls); /* IF cond THEN block */
1145 while (ls->t.token == TK_ELSEIF) {
1146 luaK_concat(fs, &escapelist, luaK_jump(fs));
1147 luaK_patchtohere(fs, flist);
1148 flist = test_then_block(ls); /* ELSEIF cond THEN block */
1149 }
1150 if (ls->t.token == TK_ELSE) {
1151 luaK_concat(fs, &escapelist, luaK_jump(fs));
1152 luaK_patchtohere(fs, flist);
1153 luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
1154 block(ls); /* `else' part */
1155 }
1156 else
1157 luaK_concat(fs, &escapelist, flist);
1158 luaK_patchtohere(fs, escapelist);
1159 check_match(ls, TK_END, TK_IF, line);
1160}
1161
1162
1163static void localfunc (LexState *ls) {
1164 expdesc v, b;
1165 FuncState *fs = ls->fs;
1166 new_localvar(ls, str_checkname(ls), 0);
1167 init_exp(&v, VLOCAL, fs->freereg);
1168 luaK_reserveregs(fs, 1);
1169 adjustlocalvars(ls, 1);
1170 body(ls, &b, 0, ls->linenumber);
1171 luaK_storevar(fs, &v, &b);
1172 /* debug information will only see the variable after this point! */
1173 getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
1174}
1175
1176
1177static void localstat (LexState *ls) {
1178 /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
1179 int nvars = 0;
1180 int nexps;
1181 expdesc e;
1182 do {
1183 new_localvar(ls, str_checkname(ls), nvars++);
1184 } while (testnext(ls, ','));
1185 if (testnext(ls, '='))
1186 nexps = explist1(ls, &e);
1187 else {
1188 e.k = VVOID;
1189 nexps = 0;
1190 }
1191 adjust_assign(ls, nvars, nexps, &e);
1192 adjustlocalvars(ls, nvars);
1193}
1194
1195
1196static int funcname (LexState *ls, expdesc *v) {
1197 /* funcname -> NAME {field} [`:' NAME] */
1198 int needself = 0;
1199 singlevar(ls, v);
1200 while (ls->t.token == '.')
1201 field(ls, v);
1202 if (ls->t.token == ':') {
1203 needself = 1;
1204 field(ls, v);
1205 }
1206 return needself;
1207}
1208
1209
1210static void funcstat (LexState *ls, int line) {
1211 /* funcstat -> FUNCTION funcname body */
1212 int needself;
1213 expdesc v, b;
1214 luaX_next(ls); /* skip FUNCTION */
1215 needself = funcname(ls, &v);
1216 body(ls, &b, needself, line);
1217 luaK_storevar(ls->fs, &v, &b);
1218 luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
1219}
1220
1221
1222static void exprstat (LexState *ls) {
1223 /* stat -> func | assignment */
1224 FuncState *fs = ls->fs;
1225 struct LHS_assign v;
1226 primaryexp(ls, &v.v);
1227 if (v.v.k == VCALL) /* stat -> func */
1228 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1229 else { /* stat -> assignment */
1230 v.prev = NULL;
1231 assignment(ls, &v, 1);
1232 }
1233}
1234
1235
1236static void retstat (LexState *ls) {
1237 /* stat -> RETURN explist */
1238 FuncState *fs = ls->fs;
1239 expdesc e;
1240 int first, nret; /* registers with returned values */
1241 luaX_next(ls); /* skip RETURN */
1242 if (block_follow(ls->t.token) || ls->t.token == ';')
1243 first = nret = 0; /* return no values */
1244 else {
1245 nret = explist1(ls, &e); /* optional return values */
1246 if (hasmultret(e.k)) {
1247 luaK_setmultret(fs, &e);
1248 if (e.k == VCALL && nret == 1) { /* tail call? */
1249 SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1250 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1251 }
1252 first = fs->nactvar;
1253 nret = LUA_MULTRET; /* return all values */
1254 }
1255 else {
1256 if (nret == 1) /* only one single value? */
1257 first = luaK_exp2anyreg(fs, &e);
1258 else {
1259 luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
1260 first = fs->nactvar; /* return all `active' values */
1261 lua_assert(nret == fs->freereg - first);
1262 }
1263 }
1264 }
1265 luaK_ret(fs, first, nret);
1266}
1267
1268
1269static int statement (LexState *ls) {
1270 int line = ls->linenumber; /* may be needed for error messages */
1271 switch (ls->t.token) {
1272 case TK_IF: { /* stat -> ifstat */
1273 ifstat(ls, line);
1274 return 0;
1275 }
1276 case TK_WHILE: { /* stat -> whilestat */
1277 whilestat(ls, line);
1278 return 0;
1279 }
1280 case TK_DO: { /* stat -> DO block END */
1281 luaX_next(ls); /* skip DO */
1282 block(ls);
1283 check_match(ls, TK_END, TK_DO, line);
1284 return 0;
1285 }
1286 case TK_FOR: { /* stat -> forstat */
1287 forstat(ls, line);
1288 return 0;
1289 }
1290 case TK_REPEAT: { /* stat -> repeatstat */
1291 repeatstat(ls, line);
1292 return 0;
1293 }
1294 case TK_FUNCTION: {
1295 funcstat(ls, line); /* stat -> funcstat */
1296 return 0;
1297 }
1298 case TK_LOCAL: { /* stat -> localstat */
1299 luaX_next(ls); /* skip LOCAL */
1300 if (testnext(ls, TK_FUNCTION)) /* local function? */
1301 localfunc(ls);
1302 else
1303 localstat(ls);
1304 return 0;
1305 }
1306 case TK_RETURN: { /* stat -> retstat */
1307 retstat(ls);
1308 return 1; /* must be last statement */
1309 }
1310 case TK_BREAK: { /* stat -> breakstat */
1311 luaX_next(ls); /* skip BREAK */
1312 breakstat(ls);
1313 return 1; /* must be last statement */
1314 }
1315 default: {
1316 exprstat(ls);
1317 return 0; /* to avoid warnings */
1318 }
1319 }
1320}
1321
1322
1323static void chunk (LexState *ls) {
1324 /* chunk -> { stat [`;'] } */
1325 int islast = 0;
1326 enterlevel(ls);
1327 while (!islast && !block_follow(ls->t.token)) {
1328 islast = statement(ls);
1329 testnext(ls, ';');
1330 lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
1331 ls->fs->freereg >= ls->fs->nactvar);
1332 ls->fs->freereg = ls->fs->nactvar; /* free registers */
1333 }
1334 leavelevel(ls);
1335}
1336
1337/* }====================================================================== */
diff --git a/lparser.h b/lparser.h
deleted file mode 100644
index 7e1d487d..00000000
--- a/lparser.h
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2** $Id: lparser.h,v 1.56 2005/10/03 14:02:40 roberto Exp roberto $
3** Lua Parser
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lparser_h
8#define lparser_h
9
10#include "llimits.h"
11#include "lobject.h"
12#include "lzio.h"
13
14
15/*
16** Expression descriptor
17*/
18
19typedef enum {
20 VVOID, /* no value */
21 VNIL,
22 VTRUE,
23 VFALSE,
24 VK, /* info = index of constant in `k' */
25 VKNUM, /* nval = numerical value */
26 VLOCAL, /* info = local register */
27 VUPVAL, /* info = index of upvalue in `upvalues' */
28 VGLOBAL, /* info = index of table; aux = index of global name in `k' */
29 VINDEXED, /* info = table register; aux = index register (or `k') */
30 VJMP, /* info = instruction pc */
31 VRELOCABLE, /* info = instruction pc */
32 VNONRELOC, /* info = result register */
33 VCALL, /* info = instruction pc */
34 VVARARG /* info = instruction pc */
35} expkind;
36
37typedef struct expdesc {
38 expkind k;
39 union {
40 struct { int info, aux; } s;
41 lua_Number nval;
42 } u;
43 int t; /* patch list of `exit when true' */
44 int f; /* patch list of `exit when false' */
45} expdesc;
46
47
48typedef struct upvaldesc {
49 lu_byte k;
50 lu_byte info;
51} upvaldesc;
52
53
54struct BlockCnt; /* defined in lparser.c */
55
56
57/* state needed to generate code for a given function */
58typedef struct FuncState {
59 Proto *f; /* current function header */
60 Table *h; /* table to find (and reuse) elements in `k' */
61 struct FuncState *prev; /* enclosing function */
62 struct LexState *ls; /* lexical state */
63 struct lua_State *L; /* copy of the Lua state */
64 struct BlockCnt *bl; /* chain of current blocks */
65 int pc; /* next position to code (equivalent to `ncode') */
66 int lasttarget; /* `pc' of last `jump target' */
67 int jpc; /* list of pending jumps to `pc' */
68 int freereg; /* first free register */
69 int nk; /* number of elements in `k' */
70 int np; /* number of elements in `p' */
71 short nlocvars; /* number of elements in `locvars' */
72 lu_byte nactvar; /* number of active local variables */
73 upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
74 unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
75} FuncState;
76
77
78LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
79 const char *name);
80
81
82#endif
diff --git a/lstate.c b/lstate.c
deleted file mode 100644
index 8da02ed5..00000000
--- a/lstate.c
+++ /dev/null
@@ -1,214 +0,0 @@
1/*
2** $Id: lstate.c,v 2.35 2005/10/06 20:46:25 roberto Exp roberto $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lstate_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "ldebug.h"
16#include "ldo.h"
17#include "lfunc.h"
18#include "lgc.h"
19#include "llex.h"
20#include "lmem.h"
21#include "lstate.h"
22#include "lstring.h"
23#include "ltable.h"
24#include "ltm.h"
25
26
27#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
28#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
29#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
30
31
32/*
33** Main thread combines a thread state and the global state
34*/
35typedef struct LG {
36 lua_State l;
37 global_State g;
38} LG;
39
40
41
42static void stack_init (lua_State *L1, lua_State *L) {
43 /* initialize CallInfo array */
44 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
45 L1->ci = L1->base_ci;
46 L1->size_ci = BASIC_CI_SIZE;
47 L1->end_ci = L1->base_ci + L1->size_ci - 1;
48 /* initialize stack array */
49 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
50 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
51 L1->top = L1->stack;
52 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
53 /* initialize first ci */
54 L1->ci->func = L1->top;
55 setnilvalue(L1->top++); /* `function' entry for this `ci' */
56 L1->base = L1->ci->base = L1->top;
57 L1->ci->top = L1->top + LUA_MINSTACK;
58}
59
60
61static void freestack (lua_State *L, lua_State *L1) {
62 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
63 luaM_freearray(L, L1->stack, L1->stacksize, TValue);
64}
65
66
67/*
68** open parts that may cause memory-allocation errors
69*/
70static void f_luaopen (lua_State *L, void *ud) {
71 global_State *g = G(L);
72 UNUSED(ud);
73 stack_init(L, L); /* init stack */
74 sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
75 sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
76 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
77 luaT_init(L);
78 luaX_init(L);
79 luaS_fix(luaS_newliteral(L, MEMERRMSG));
80 g->GCthreshold = 4*g->totalbytes;
81}
82
83
84static void preinit_state (lua_State *L, global_State *g) {
85 G(L) = g;
86 L->stack = NULL;
87 L->stacksize = 0;
88 L->errorJmp = NULL;
89 L->hook = NULL;
90 L->hookmask = 0;
91 L->basehookcount = 0;
92 L->allowhook = 1;
93 resethookcount(L);
94 L->openupval = NULL;
95 L->size_ci = 0;
96 L->nCcalls = 0;
97 L->status = 0;
98 L->base_ci = L->ci = NULL;
99 L->savedpc = NULL;
100 L->errfunc = 0;
101 setnilvalue(gt(L));
102}
103
104
105static void close_state (lua_State *L) {
106 global_State *g = G(L);
107 luaF_close(L, L->stack); /* close all upvalues for this thread */
108 luaC_freeall(L); /* collect all objects */
109 lua_assert(g->rootgc == obj2gco(L));
110 lua_assert(g->strt.nuse == 0);
111 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
112 luaZ_freebuffer(L, &g->buff);
113 freestack(L, L);
114 lua_assert(g->totalbytes == sizeof(LG));
115 (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
116}
117
118
119lua_State *luaE_newthread (lua_State *L) {
120 lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
121 luaC_link(L, obj2gco(L1), LUA_TTHREAD);
122 preinit_state(L1, G(L));
123 stack_init(L1, L); /* init stack */
124 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
125 L1->hookmask = L->hookmask;
126 L1->basehookcount = L->basehookcount;
127 L1->hook = L->hook;
128 resethookcount(L1);
129 lua_assert(iswhite(obj2gco(L1)));
130 return L1;
131}
132
133
134void luaE_freethread (lua_State *L, lua_State *L1) {
135 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
136 lua_assert(L1->openupval == NULL);
137 luai_userstatefree(L1);
138 freestack(L, L1);
139 luaM_freemem(L, fromstate(L1), state_size(lua_State));
140}
141
142
143LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
144 int i;
145 lua_State *L;
146 global_State *g;
147 void *l = (*f)(ud, NULL, 0, state_size(LG));
148 if (l == NULL) return NULL;
149 L = tostate(l);
150 g = &((LG *)L)->g;
151 L->next = NULL;
152 L->tt = LUA_TTHREAD;
153 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
154 L->marked = luaC_white(g);
155 set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
156 preinit_state(L, g);
157 g->frealloc = f;
158 g->ud = ud;
159 g->mainthread = L;
160 g->uvhead.u.l.prev = &g->uvhead;
161 g->uvhead.u.l.next = &g->uvhead;
162 g->GCthreshold = 0; /* mark it as unfinished state */
163 g->strt.size = 0;
164 g->strt.nuse = 0;
165 g->strt.hash = NULL;
166 setnilvalue(registry(L));
167 luaZ_initbuffer(L, &g->buff);
168 g->panic = NULL;
169 g->gcstate = GCSpause;
170 g->rootgc = obj2gco(L);
171 g->sweepstrgc = 0;
172 g->sweepgc = &g->rootgc;
173 g->gray = NULL;
174 g->grayagain = NULL;
175 g->weak = NULL;
176 g->tmudata = NULL;
177 g->totalbytes = sizeof(LG);
178 g->gcpause = LUAI_GCPAUSE;
179 g->gcstepmul = LUAI_GCMUL;
180 g->gcdept = 0;
181 for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
182 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
183 /* memory allocation error: free partial state */
184 close_state(L);
185 L = NULL;
186 }
187 else
188 luai_userstateopen(L);
189 return L;
190}
191
192
193static void callallgcTM (lua_State *L, void *ud) {
194 UNUSED(ud);
195 luaC_callGCTM(L); /* call GC metamethods for all udata */
196}
197
198
199LUA_API void lua_close (lua_State *L) {
200 L = G(L)->mainthread; /* only the main thread can be closed */
201 lua_lock(L);
202 luaF_close(L, L->stack); /* close all upvalues for this thread */
203 luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
204 L->errfunc = 0; /* no error function during GC metamethods */
205 do { /* repeat until no more errors */
206 L->ci = L->base_ci;
207 L->base = L->top = L->ci->base;
208 L->nCcalls = 0;
209 } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
210 lua_assert(G(L)->tmudata == NULL);
211 luai_userstateclose(L);
212 close_state(L);
213}
214
diff --git a/lstate.h b/lstate.h
deleted file mode 100644
index 1ed893b4..00000000
--- a/lstate.h
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2** $Id: lstate.h,v 2.23 2005/07/09 13:22:34 roberto Exp roberto $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstate_h
8#define lstate_h
9
10#include "lua.h"
11
12#include "lobject.h"
13#include "ltm.h"
14#include "lzio.h"
15
16
17
18struct lua_longjmp; /* defined in ldo.c */
19
20
21/* table of globals */
22#define gt(L) (&L->l_gt)
23
24/* registry */
25#define registry(L) (&G(L)->l_registry)
26
27
28/* extra stack space to handle TM calls and some other extras */
29#define EXTRA_STACK 5
30
31
32#define BASIC_CI_SIZE 8
33
34#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
35
36
37
38typedef struct stringtable {
39 GCObject **hash;
40 lu_int32 nuse; /* number of elements */
41 int size;
42} stringtable;
43
44
45/*
46** informations about a call
47*/
48typedef struct CallInfo {
49 StkId base; /* base for this function */
50 StkId func; /* function index in the stack */
51 StkId top; /* top for this function */
52 const Instruction *savedpc;
53 int nresults; /* expected number of results from this function */
54 int tailcalls; /* number of tail calls lost under this entry */
55} CallInfo;
56
57
58
59#define curr_func(L) (clvalue(L->ci->func))
60#define ci_func(ci) (clvalue((ci)->func))
61#define f_isLua(ci) (!ci_func(ci)->c.isC)
62#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
63
64
65/*
66** `global state', shared by all threads of this state
67*/
68typedef struct global_State {
69 stringtable strt; /* hash table for strings */
70 lua_Alloc frealloc; /* function to reallocate memory */
71 void *ud; /* auxiliary data to `frealloc' */
72 lu_byte currentwhite;
73 lu_byte gcstate; /* state of garbage collector */
74 int sweepstrgc; /* position of sweep in `strt' */
75 GCObject *rootgc; /* list of all collectable objects */
76 GCObject **sweepgc; /* position of sweep in `rootgc' */
77 GCObject *gray; /* list of gray objects */
78 GCObject *grayagain; /* list of objects to be traversed atomically */
79 GCObject *weak; /* list of weak tables (to be cleared) */
80 GCObject *tmudata; /* last element of list of userdata to be GC */
81 Mbuffer buff; /* temporary buffer for string concatentation */
82 lu_mem GCthreshold;
83 lu_mem totalbytes; /* number of bytes currently allocated */
84 lu_mem estimate; /* an estimate of number of bytes actually in use */
85 lu_mem gcdept; /* how much GC is `behind schedule' */
86 int gcpause; /* size of pause between successive GCs */
87 int gcstepmul; /* GC `granularity' */
88 lua_CFunction panic; /* to be called in unprotected errors */
89 TValue l_registry;
90 struct lua_State *mainthread;
91 UpVal uvhead; /* head of double-linked list of all open upvalues */
92 struct Table *mt[NUM_TAGS]; /* metatables for basic types */
93 TString *tmname[TM_N]; /* array with tag-method names */
94} global_State;
95
96
97/*
98** `per thread' state
99*/
100struct lua_State {
101 CommonHeader;
102 lu_byte status;
103 StkId top; /* first free slot in the stack */
104 StkId base; /* base of current function */
105 global_State *l_G;
106 CallInfo *ci; /* call info for current function */
107 const Instruction *savedpc; /* `savedpc' of current function */
108 StkId stack_last; /* last free slot in the stack */
109 StkId stack; /* stack base */
110 CallInfo *end_ci; /* points after end of ci array*/
111 CallInfo *base_ci; /* array of CallInfo's */
112 int stacksize;
113 int size_ci; /* size of array `base_ci' */
114 unsigned short nCcalls; /* number of nested C calls */
115 lu_byte hookmask;
116 lu_byte allowhook;
117 int basehookcount;
118 int hookcount;
119 lua_Hook hook;
120 TValue l_gt; /* table of globals */
121 TValue env; /* temporary place for environments */
122 GCObject *openupval; /* list of open upvalues in this stack */
123 GCObject *gclist;
124 struct lua_longjmp *errorJmp; /* current error recover point */
125 ptrdiff_t errfunc; /* current error handling function (stack index) */
126};
127
128
129#define G(L) (L->l_G)
130
131
132/*
133** Union of all collectable objects
134*/
135union GCObject {
136 GCheader gch;
137 union TString ts;
138 union Udata u;
139 union Closure cl;
140 struct Table h;
141 struct Proto p;
142 struct UpVal uv;
143 struct lua_State th; /* thread */
144};
145
146
147/* macros to convert a GCObject into a specific value */
148#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
149#define gco2ts(o) (&rawgco2ts(o)->tsv)
150#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
151#define gco2u(o) (&rawgco2u(o)->uv)
152#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
153#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
154#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
155#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
156#define ngcotouv(o) \
157 check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
158#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
159
160/* macro to convert any Lua object into a GCObject */
161#define obj2gco(v) (cast(GCObject *, (v)))
162
163
164LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
165LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
166
167#endif
168
diff --git a/lstring.c b/lstring.c
deleted file mode 100644
index 08dbe87f..00000000
--- a/lstring.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2** $Id: lstring.c,v 2.7 2005/02/18 12:40:02 roberto Exp roberto $
3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lstring_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lmem.h"
16#include "lobject.h"
17#include "lstate.h"
18#include "lstring.h"
19
20
21
22void luaS_resize (lua_State *L, int newsize) {
23 GCObject **newhash;
24 stringtable *tb;
25 int i;
26 if (G(L)->gcstate == GCSsweepstring)
27 return; /* cannot resize during GC traverse */
28 newhash = luaM_newvector(L, newsize, GCObject *);
29 tb = &G(L)->strt;
30 for (i=0; i<newsize; i++) newhash[i] = NULL;
31 /* rehash */
32 for (i=0; i<tb->size; i++) {
33 GCObject *p = tb->hash[i];
34 while (p) { /* for each node in the list */
35 GCObject *next = p->gch.next; /* save next */
36 unsigned int h = gco2ts(p)->hash;
37 int h1 = lmod(h, newsize); /* new position */
38 lua_assert(cast_int(h%newsize) == lmod(h, newsize));
39 p->gch.next = newhash[h1]; /* chain it */
40 newhash[h1] = p;
41 p = next;
42 }
43 }
44 luaM_freearray(L, tb->hash, tb->size, TString *);
45 tb->size = newsize;
46 tb->hash = newhash;
47}
48
49
50static TString *newlstr (lua_State *L, const char *str, size_t l,
51 unsigned int h) {
52 TString *ts;
53 stringtable *tb;
54 if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
55 luaM_toobig(L);
56 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
57 ts->tsv.len = l;
58 ts->tsv.hash = h;
59 ts->tsv.marked = luaC_white(G(L));
60 ts->tsv.tt = LUA_TSTRING;
61 ts->tsv.reserved = 0;
62 memcpy(ts+1, str, l*sizeof(char));
63 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
64 tb = &G(L)->strt;
65 h = lmod(h, tb->size);
66 ts->tsv.next = tb->hash[h]; /* chain new entry */
67 tb->hash[h] = obj2gco(ts);
68 tb->nuse++;
69 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
70 luaS_resize(L, tb->size*2); /* too crowded */
71 return ts;
72}
73
74
75TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
76 GCObject *o;
77 unsigned int h = cast(unsigned int, l); /* seed */
78 size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
79 size_t l1;
80 for (l1=l; l1>=step; l1-=step) /* compute hash */
81 h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
82 for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
83 o != NULL;
84 o = o->gch.next) {
85 TString *ts = rawgco2ts(o);
86 if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
87 /* string may be dead */
88 if (isdead(G(L), o)) changewhite(o);
89 return ts;
90 }
91 }
92 return newlstr(L, str, l, h); /* not found */
93}
94
95
96Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
97 Udata *u;
98 if (s > MAX_SIZET - sizeof(Udata))
99 luaM_toobig(L);
100 u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
101 u->uv.marked = luaC_white(G(L)); /* is not finalized */
102 u->uv.tt = LUA_TUSERDATA;
103 u->uv.len = s;
104 u->uv.metatable = NULL;
105 u->uv.env = e;
106 /* chain it on udata list (after main thread) */
107 u->uv.next = G(L)->mainthread->next;
108 G(L)->mainthread->next = obj2gco(u);
109 return u;
110}
111
diff --git a/lstring.h b/lstring.h
deleted file mode 100644
index 29bdcb9d..00000000
--- a/lstring.h
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2** $Id: lstring.h,v 1.42 2005/02/23 17:30:22 roberto Exp roberto $
3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lstring_h
8#define lstring_h
9
10
11#include "lgc.h"
12#include "lobject.h"
13#include "lstate.h"
14
15
16#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
17
18#define sizeudata(u) (sizeof(union Udata)+(u)->len)
19
20#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
21#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
22 (sizeof(s)/sizeof(char))-1))
23
24#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
25
26LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
27LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
28LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
29
30
31#endif
diff --git a/lstrlib.c b/lstrlib.c
deleted file mode 100644
index b6eda2cf..00000000
--- a/lstrlib.c
+++ /dev/null
@@ -1,868 +0,0 @@
1/*
2** $Id: lstrlib.c,v 1.131 2006/04/12 20:13:52 roberto Exp roberto $
3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <stddef.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define lstrlib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23/* macro to `unsign' a character */
24#define uchar(c) ((unsigned char)(c))
25
26
27
28static int str_len (lua_State *L) {
29 size_t l;
30 luaL_checklstring(L, 1, &l);
31 lua_pushinteger(L, l);
32 return 1;
33}
34
35
36static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
37 /* relative string position: negative means back from end */
38 return (pos>=0) ? pos : (ptrdiff_t)len+pos+1;
39}
40
41
42static int str_sub (lua_State *L) {
43 size_t l;
44 const char *s = luaL_checklstring(L, 1, &l);
45 ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
46 ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
47 if (start < 1) start = 1;
48 if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
49 if (start <= end)
50 lua_pushlstring(L, s+start-1, end-start+1);
51 else lua_pushliteral(L, "");
52 return 1;
53}
54
55
56static int str_reverse (lua_State *L) {
57 size_t l;
58 luaL_Buffer b;
59 const char *s = luaL_checklstring(L, 1, &l);
60 luaL_buffinit(L, &b);
61 while (l--) luaL_addchar(&b, s[l]);
62 luaL_pushresult(&b);
63 return 1;
64}
65
66
67static int str_lower (lua_State *L) {
68 size_t l;
69 size_t i;
70 luaL_Buffer b;
71 const char *s = luaL_checklstring(L, 1, &l);
72 luaL_buffinit(L, &b);
73 for (i=0; i<l; i++)
74 luaL_addchar(&b, tolower(uchar(s[i])));
75 luaL_pushresult(&b);
76 return 1;
77}
78
79
80static int str_upper (lua_State *L) {
81 size_t l;
82 size_t i;
83 luaL_Buffer b;
84 const char *s = luaL_checklstring(L, 1, &l);
85 luaL_buffinit(L, &b);
86 for (i=0; i<l; i++)
87 luaL_addchar(&b, toupper(uchar(s[i])));
88 luaL_pushresult(&b);
89 return 1;
90}
91
92static int str_rep (lua_State *L) {
93 size_t l;
94 luaL_Buffer b;
95 const char *s = luaL_checklstring(L, 1, &l);
96 int n = luaL_checkint(L, 2);
97 luaL_buffinit(L, &b);
98 while (n-- > 0)
99 luaL_addlstring(&b, s, l);
100 luaL_pushresult(&b);
101 return 1;
102}
103
104
105static int str_byte (lua_State *L) {
106 size_t l;
107 const char *s = luaL_checklstring(L, 1, &l);
108 ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
109 ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
110 int n, i;
111 if (posi <= 0) posi = 1;
112 if ((size_t)pose > l) pose = l;
113 if (posi > pose) return 0; /* empty interval; return no values */
114 n = (int)(pose - posi + 1);
115 if (posi + n <= pose) /* overflow? */
116 luaL_error(L, "string slice too long");
117 luaL_checkstack(L, n, "string slice too long");
118 for (i=0; i<n; i++)
119 lua_pushinteger(L, uchar(s[posi+i-1]));
120 return n;
121}
122
123
124static int str_char (lua_State *L) {
125 int n = lua_gettop(L); /* number of arguments */
126 int i;
127 luaL_Buffer b;
128 luaL_buffinit(L, &b);
129 for (i=1; i<=n; i++) {
130 int c = luaL_checkint(L, i);
131 luaL_argcheck(L, uchar(c) == c, i, "invalid value");
132 luaL_addchar(&b, uchar(c));
133 }
134 luaL_pushresult(&b);
135 return 1;
136}
137
138
139static int writer (lua_State *L, const void* b, size_t size, void* B) {
140 (void)L;
141 luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
142 return 0;
143}
144
145
146static int str_dump (lua_State *L) {
147 luaL_Buffer b;
148 luaL_checktype(L, 1, LUA_TFUNCTION);
149 lua_settop(L, 1);
150 luaL_buffinit(L,&b);
151 if (lua_dump(L, writer, &b) != 0)
152 luaL_error(L, "unable to dump given function");
153 luaL_pushresult(&b);
154 return 1;
155}
156
157
158
159/*
160** {======================================================
161** PATTERN MATCHING
162** =======================================================
163*/
164
165
166#define CAP_UNFINISHED (-1)
167#define CAP_POSITION (-2)
168
169typedef struct MatchState {
170 const char *src_init; /* init of source string */
171 const char *src_end; /* end (`\0') of source string */
172 lua_State *L;
173 int level; /* total number of captures (finished or unfinished) */
174 struct {
175 const char *init;
176 ptrdiff_t len;
177 } capture[LUA_MAXCAPTURES];
178} MatchState;
179
180
181#define L_ESC '%'
182#define SPECIALS "^$*+?.([%-"
183
184
185static int check_capture (MatchState *ms, int l) {
186 l -= '1';
187 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
188 return luaL_error(ms->L, "invalid capture index");
189 return l;
190}
191
192
193static int capture_to_close (MatchState *ms) {
194 int level = ms->level;
195 for (level--; level>=0; level--)
196 if (ms->capture[level].len == CAP_UNFINISHED) return level;
197 return luaL_error(ms->L, "invalid pattern capture");
198}
199
200
201static const char *classend (MatchState *ms, const char *p) {
202 switch (*p++) {
203 case L_ESC: {
204 if (*p == '\0')
205 luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
206 return p+1;
207 }
208 case '[': {
209 if (*p == '^') p++;
210 do { /* look for a `]' */
211 if (*p == '\0')
212 luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
213 if (*(p++) == L_ESC && *p != '\0')
214 p++; /* skip escapes (e.g. `%]') */
215 } while (*p != ']');
216 return p+1;
217 }
218 default: {
219 return p;
220 }
221 }
222}
223
224
225static int match_class (int c, int cl) {
226 int res;
227 switch (tolower(cl)) {
228 case 'a' : res = isalpha(c); break;
229 case 'c' : res = iscntrl(c); break;
230 case 'd' : res = isdigit(c); break;
231 case 'l' : res = islower(c); break;
232 case 'p' : res = ispunct(c); break;
233 case 's' : res = isspace(c); break;
234 case 'u' : res = isupper(c); break;
235 case 'w' : res = isalnum(c); break;
236 case 'x' : res = isxdigit(c); break;
237 case 'z' : res = (c == 0); break;
238 default: return (cl == c);
239 }
240 return (islower(cl) ? res : !res);
241}
242
243
244static int matchbracketclass (int c, const char *p, const char *ec) {
245 int sig = 1;
246 if (*(p+1) == '^') {
247 sig = 0;
248 p++; /* skip the `^' */
249 }
250 while (++p < ec) {
251 if (*p == L_ESC) {
252 p++;
253 if (match_class(c, uchar(*p)))
254 return sig;
255 }
256 else if ((*(p+1) == '-') && (p+2 < ec)) {
257 p+=2;
258 if (uchar(*(p-2)) <= c && c <= uchar(*p))
259 return sig;
260 }
261 else if (uchar(*p) == c) return sig;
262 }
263 return !sig;
264}
265
266
267static int singlematch (int c, const char *p, const char *ep) {
268 switch (*p) {
269 case '.': return 1; /* matches any char */
270 case L_ESC: return match_class(c, uchar(*(p+1)));
271 case '[': return matchbracketclass(c, p, ep-1);
272 default: return (uchar(*p) == c);
273 }
274}
275
276
277static const char *match (MatchState *ms, const char *s, const char *p);
278
279
280static const char *matchbalance (MatchState *ms, const char *s,
281 const char *p) {
282 if (*p == 0 || *(p+1) == 0)
283 luaL_error(ms->L, "unbalanced pattern");
284 if (*s != *p) return NULL;
285 else {
286 int b = *p;
287 int e = *(p+1);
288 int cont = 1;
289 while (++s < ms->src_end) {
290 if (*s == e) {
291 if (--cont == 0) return s+1;
292 }
293 else if (*s == b) cont++;
294 }
295 }
296 return NULL; /* string ends out of balance */
297}
298
299
300static const char *max_expand (MatchState *ms, const char *s,
301 const char *p, const char *ep) {
302 ptrdiff_t i = 0; /* counts maximum expand for item */
303 while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
304 i++;
305 /* keeps trying to match with the maximum repetitions */
306 while (i>=0) {
307 const char *res = match(ms, (s+i), ep+1);
308 if (res) return res;
309 i--; /* else didn't match; reduce 1 repetition to try again */
310 }
311 return NULL;
312}
313
314
315static const char *min_expand (MatchState *ms, const char *s,
316 const char *p, const char *ep) {
317 for (;;) {
318 const char *res = match(ms, s, ep+1);
319 if (res != NULL)
320 return res;
321 else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
322 s++; /* try with one more repetition */
323 else return NULL;
324 }
325}
326
327
328static const char *start_capture (MatchState *ms, const char *s,
329 const char *p, int what) {
330 const char *res;
331 int level = ms->level;
332 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
333 ms->capture[level].init = s;
334 ms->capture[level].len = what;
335 ms->level = level+1;
336 if ((res=match(ms, s, p)) == NULL) /* match failed? */
337 ms->level--; /* undo capture */
338 return res;
339}
340
341
342static const char *end_capture (MatchState *ms, const char *s,
343 const char *p) {
344 int l = capture_to_close(ms);
345 const char *res;
346 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
347 if ((res = match(ms, s, p)) == NULL) /* match failed? */
348 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
349 return res;
350}
351
352
353static const char *match_capture (MatchState *ms, const char *s, int l) {
354 size_t len;
355 l = check_capture(ms, l);
356 len = ms->capture[l].len;
357 if ((size_t)(ms->src_end-s) >= len &&
358 memcmp(ms->capture[l].init, s, len) == 0)
359 return s+len;
360 else return NULL;
361}
362
363
364static const char *match (MatchState *ms, const char *s, const char *p) {
365 init: /* using goto's to optimize tail recursion */
366 switch (*p) {
367 case '(': { /* start capture */
368 if (*(p+1) == ')') /* position capture? */
369 return start_capture(ms, s, p+2, CAP_POSITION);
370 else
371 return start_capture(ms, s, p+1, CAP_UNFINISHED);
372 }
373 case ')': { /* end capture */
374 return end_capture(ms, s, p+1);
375 }
376 case L_ESC: {
377 switch (*(p+1)) {
378 case 'b': { /* balanced string? */
379 s = matchbalance(ms, s, p+2);
380 if (s == NULL) return NULL;
381 p+=4; goto init; /* else return match(ms, s, p+4); */
382 }
383 case 'f': { /* frontier? */
384 const char *ep; char previous;
385 p += 2;
386 if (*p != '[')
387 luaL_error(ms->L, "missing " LUA_QL("[") " after "
388 LUA_QL("%%f") " in pattern");
389 ep = classend(ms, p); /* points to what is next */
390 previous = (s == ms->src_init) ? '\0' : *(s-1);
391 if (matchbracketclass(uchar(previous), p, ep-1) ||
392 !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
393 p=ep; goto init; /* else return match(ms, s, ep); */
394 }
395 default: {
396 if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
397 s = match_capture(ms, s, uchar(*(p+1)));
398 if (s == NULL) return NULL;
399 p+=2; goto init; /* else return match(ms, s, p+2) */
400 }
401 goto dflt; /* case default */
402 }
403 }
404 }
405 case '\0': { /* end of pattern */
406 return s; /* match succeeded */
407 }
408 case '$': {
409 if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
410 return (s == ms->src_end) ? s : NULL; /* check end of string */
411 else goto dflt;
412 }
413 default: dflt: { /* it is a pattern item */
414 const char *ep = classend(ms, p); /* points to what is next */
415 int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
416 switch (*ep) {
417 case '?': { /* optional */
418 const char *res;
419 if (m && ((res=match(ms, s+1, ep+1)) != NULL))
420 return res;
421 p=ep+1; goto init; /* else return match(ms, s, ep+1); */
422 }
423 case '*': { /* 0 or more repetitions */
424 return max_expand(ms, s, p, ep);
425 }
426 case '+': { /* 1 or more repetitions */
427 return (m ? max_expand(ms, s+1, p, ep) : NULL);
428 }
429 case '-': { /* 0 or more repetitions (minimum) */
430 return min_expand(ms, s, p, ep);
431 }
432 default: {
433 if (!m) return NULL;
434 s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
435 }
436 }
437 }
438 }
439}
440
441
442
443static const char *lmemfind (const char *s1, size_t l1,
444 const char *s2, size_t l2) {
445 if (l2 == 0) return s1; /* empty strings are everywhere */
446 else if (l2 > l1) return NULL; /* avoids a negative `l1' */
447 else {
448 const char *init; /* to search for a `*s2' inside `s1' */
449 l2--; /* 1st char will be checked by `memchr' */
450 l1 = l1-l2; /* `s2' cannot be found after that */
451 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
452 init++; /* 1st char is already checked */
453 if (memcmp(init, s2+1, l2) == 0)
454 return init-1;
455 else { /* correct `l1' and `s1' to try again */
456 l1 -= init-s1;
457 s1 = init;
458 }
459 }
460 return NULL; /* not found */
461 }
462}
463
464
465static void push_onecapture (MatchState *ms, int i, const char *s,
466 const char *e) {
467 if (i >= ms->level) {
468 if (i == 0) /* ms->level == 0, too */
469 lua_pushlstring(ms->L, s, e - s); /* add whole match */
470 else
471 luaL_error(ms->L, "invalid capture index");
472 }
473 else {
474 ptrdiff_t l = ms->capture[i].len;
475 if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
476 if (l == CAP_POSITION)
477 lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
478 else
479 lua_pushlstring(ms->L, ms->capture[i].init, l);
480 }
481}
482
483
484static int push_captures (MatchState *ms, const char *s, const char *e) {
485 int i;
486 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
487 luaL_checkstack(ms->L, nlevels, "too many captures");
488 for (i = 0; i < nlevels; i++)
489 push_onecapture(ms, i, s, e);
490 return nlevels; /* number of strings pushed */
491}
492
493
494static int str_find_aux (lua_State *L, int find) {
495 size_t l1, l2;
496 const char *s = luaL_checklstring(L, 1, &l1);
497 const char *p = luaL_checklstring(L, 2, &l2);
498 ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
499 if (init < 0) init = 0;
500 else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
501 if (find && (lua_toboolean(L, 4) || /* explicit request? */
502 strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
503 /* do a plain search */
504 const char *s2 = lmemfind(s+init, l1-init, p, l2);
505 if (s2) {
506 lua_pushinteger(L, s2-s+1);
507 lua_pushinteger(L, s2-s+l2);
508 return 2;
509 }
510 }
511 else {
512 MatchState ms;
513 int anchor = (*p == '^') ? (p++, 1) : 0;
514 const char *s1=s+init;
515 ms.L = L;
516 ms.src_init = s;
517 ms.src_end = s+l1;
518 do {
519 const char *res;
520 ms.level = 0;
521 if ((res=match(&ms, s1, p)) != NULL) {
522 if (find) {
523 lua_pushinteger(L, s1-s+1); /* start */
524 lua_pushinteger(L, res-s); /* end */
525 return push_captures(&ms, NULL, 0) + 2;
526 }
527 else
528 return push_captures(&ms, s1, res);
529 }
530 } while (s1++ < ms.src_end && !anchor);
531 }
532 lua_pushnil(L); /* not found */
533 return 1;
534}
535
536
537static int str_find (lua_State *L) {
538 return str_find_aux(L, 1);
539}
540
541
542static int str_match (lua_State *L) {
543 return str_find_aux(L, 0);
544}
545
546
547static int gmatch_aux (lua_State *L) {
548 MatchState ms;
549 size_t ls;
550 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
551 const char *p = lua_tostring(L, lua_upvalueindex(2));
552 const char *src;
553 ms.L = L;
554 ms.src_init = s;
555 ms.src_end = s+ls;
556 for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
557 src <= ms.src_end;
558 src++) {
559 const char *e;
560 ms.level = 0;
561 if ((e = match(&ms, src, p)) != NULL) {
562 lua_Integer newstart = e-s;
563 if (e == src) newstart++; /* empty match? go at least one position */
564 lua_pushinteger(L, newstart);
565 lua_replace(L, lua_upvalueindex(3));
566 return push_captures(&ms, src, e);
567 }
568 }
569 return 0; /* not found */
570}
571
572
573static int gmatch (lua_State *L) {
574 luaL_checkstring(L, 1);
575 luaL_checkstring(L, 2);
576 lua_settop(L, 2);
577 lua_pushinteger(L, 0);
578 lua_pushcclosure(L, gmatch_aux, 3);
579 return 1;
580}
581
582
583static int gfind_nodef (lua_State *L) {
584 return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
585 LUA_QL("string.gmatch"));
586}
587
588
589static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
590 const char *e) {
591 size_t l, i;
592 const char *news = lua_tolstring(ms->L, 3, &l);
593 for (i = 0; i < l; i++) {
594 if (news[i] != L_ESC)
595 luaL_addchar(b, news[i]);
596 else {
597 i++; /* skip ESC */
598 if (!isdigit(uchar(news[i])))
599 luaL_addchar(b, news[i]);
600 else if (news[i] == '0')
601 luaL_addlstring(b, s, e - s);
602 else {
603 push_onecapture(ms, news[i] - '1', s, e);
604 luaL_addvalue(b); /* add capture to accumulated result */
605 }
606 }
607 }
608}
609
610
611static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
612 const char *e) {
613 lua_State *L = ms->L;
614 switch (lua_type(L, 3)) {
615 case LUA_TNUMBER:
616 case LUA_TSTRING: {
617 add_s(ms, b, s, e);
618 return;
619 }
620 case LUA_TFUNCTION: {
621 int n;
622 lua_pushvalue(L, 3);
623 n = push_captures(ms, s, e);
624 lua_call(L, n, 1);
625 break;
626 }
627 case LUA_TTABLE: {
628 push_onecapture(ms, 0, s, e);
629 lua_gettable(L, 3);
630 break;
631 }
632 default: {
633 luaL_argerror(L, 3, "string/function/table expected");
634 return;
635 }
636 }
637 if (!lua_toboolean(L, -1)) { /* nil or false? */
638 lua_pop(L, 1);
639 lua_pushlstring(L, s, e - s); /* keep original text */
640 }
641 else if (!lua_isstring(L, -1))
642 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
643 luaL_addvalue(b); /* add result to accumulator */
644}
645
646
647static int str_gsub (lua_State *L) {
648 size_t srcl;
649 const char *src = luaL_checklstring(L, 1, &srcl);
650 const char *p = luaL_checkstring(L, 2);
651 int max_s = luaL_optint(L, 4, srcl+1);
652 int anchor = (*p == '^') ? (p++, 1) : 0;
653 int n = 0;
654 MatchState ms;
655 luaL_Buffer b;
656 luaL_buffinit(L, &b);
657 ms.L = L;
658 ms.src_init = src;
659 ms.src_end = src+srcl;
660 while (n < max_s) {
661 const char *e;
662 ms.level = 0;
663 e = match(&ms, src, p);
664 if (e) {
665 n++;
666 add_value(&ms, &b, src, e);
667 }
668 if (e && e>src) /* non empty match? */
669 src = e; /* skip it */
670 else if (src < ms.src_end)
671 luaL_addchar(&b, *src++);
672 else break;
673 if (anchor) break;
674 }
675 luaL_addlstring(&b, src, ms.src_end-src);
676 luaL_pushresult(&b);
677 lua_pushinteger(L, n); /* number of substitutions */
678 return 2;
679}
680
681/* }====================================================== */
682
683
684/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
685#define MAX_ITEM 512
686/* valid flags in a format specification */
687#define FLAGS "-+ #0"
688/*
689** maximum size of each format specification (such as '%-099.99d')
690** (+10 accounts for %99.99x plus margin of error)
691*/
692#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
693
694
695static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
696 size_t l;
697 const char *s = luaL_checklstring(L, arg, &l);
698 luaL_addchar(b, '"');
699 while (l--) {
700 switch (*s) {
701 case '"': case '\\': case '\n': {
702 luaL_addchar(b, '\\');
703 luaL_addchar(b, *s);
704 break;
705 }
706 case '\r': {
707 luaL_addlstring(b, "\\r", 2);
708 break;
709 }
710 case '\0': {
711 luaL_addlstring(b, "\\000", 4);
712 break;
713 }
714 default: {
715 luaL_addchar(b, *s);
716 break;
717 }
718 }
719 s++;
720 }
721 luaL_addchar(b, '"');
722}
723
724static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
725 const char *p = strfrmt;
726 while (strchr(FLAGS, *p)) p++; /* skip flags */
727 if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
728 luaL_error(L, "invalid format (repeated flags)");
729 if (isdigit(uchar(*p))) p++; /* skip width */
730 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
731 if (*p == '.') {
732 p++;
733 if (isdigit(uchar(*p))) p++; /* skip precision */
734 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
735 }
736 if (isdigit(uchar(*p)))
737 luaL_error(L, "invalid format (width or precision too long)");
738 *(form++) = '%';
739 strncpy(form, strfrmt, p - strfrmt + 1);
740 form += p - strfrmt + 1;
741 *form = '\0';
742 return p;
743}
744
745
746static void addintlen (char *form) {
747 size_t l = strlen(form);
748 char spec = form[l - 1];
749 strcpy(form + l - 1, LUA_INTFRMLEN);
750 form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
751 form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
752}
753
754
755static int str_format (lua_State *L) {
756 int arg = 1;
757 size_t sfl;
758 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
759 const char *strfrmt_end = strfrmt+sfl;
760 luaL_Buffer b;
761 luaL_buffinit(L, &b);
762 while (strfrmt < strfrmt_end) {
763 if (*strfrmt != L_ESC)
764 luaL_addchar(&b, *strfrmt++);
765 else if (*++strfrmt == L_ESC)
766 luaL_addchar(&b, *strfrmt++); /* %% */
767 else { /* format item */
768 char form[MAX_FORMAT]; /* to store the format (`%...') */
769 char buff[MAX_ITEM]; /* to store the formatted item */
770 arg++;
771 strfrmt = scanformat(L, strfrmt, form);
772 switch (*strfrmt++) {
773 case 'c': {
774 sprintf(buff, form, (int)luaL_checknumber(L, arg));
775 break;
776 }
777 case 'd': case 'i': {
778 addintlen(form);
779 sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
780 break;
781 }
782 case 'o': case 'u': case 'x': case 'X': {
783 addintlen(form);
784 sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
785 break;
786 }
787 case 'e': case 'E': case 'f':
788 case 'g': case 'G': {
789 sprintf(buff, form, (double)luaL_checknumber(L, arg));
790 break;
791 }
792 case 'q': {
793 addquoted(L, &b, arg);
794 continue; /* skip the 'addsize' at the end */
795 }
796 case 's': {
797 size_t l;
798 const char *s = luaL_checklstring(L, arg, &l);
799 if (!strchr(form, '.') && l >= 100) {
800 /* no precision and string is too long to be formatted;
801 keep original string */
802 lua_pushvalue(L, arg);
803 luaL_addvalue(&b);
804 continue; /* skip the `addsize' at the end */
805 }
806 else {
807 sprintf(buff, form, s);
808 break;
809 }
810 }
811 default: { /* also treat cases `pnLlh' */
812 return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
813 LUA_QL("format"), *(strfrmt - 1));
814 }
815 }
816 luaL_addlstring(&b, buff, strlen(buff));
817 }
818 }
819 luaL_pushresult(&b);
820 return 1;
821}
822
823
824static const luaL_Reg strlib[] = {
825 {"byte", str_byte},
826 {"char", str_char},
827 {"dump", str_dump},
828 {"find", str_find},
829 {"format", str_format},
830 {"gfind", gfind_nodef},
831 {"gmatch", gmatch},
832 {"gsub", str_gsub},
833 {"len", str_len},
834 {"lower", str_lower},
835 {"match", str_match},
836 {"rep", str_rep},
837 {"reverse", str_reverse},
838 {"sub", str_sub},
839 {"upper", str_upper},
840 {NULL, NULL}
841};
842
843
844static void createmetatable (lua_State *L) {
845 lua_createtable(L, 0, 1); /* create metatable for strings */
846 lua_pushliteral(L, ""); /* dummy string */
847 lua_pushvalue(L, -2);
848 lua_setmetatable(L, -2); /* set string metatable */
849 lua_pop(L, 1); /* pop dummy string */
850 lua_pushvalue(L, -2); /* string library... */
851 lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
852 lua_pop(L, 1); /* pop metatable */
853}
854
855
856/*
857** Open string library
858*/
859LUALIB_API int luaopen_string (lua_State *L) {
860 luaL_register(L, LUA_STRLIBNAME, strlib);
861#if defined(LUA_COMPAT_GFIND)
862 lua_getfield(L, -1, "gmatch");
863 lua_setfield(L, -2, "gfind");
864#endif
865 createmetatable(L);
866 return 1;
867}
868
diff --git a/ltable.c b/ltable.c
deleted file mode 100644
index b68d1486..00000000
--- a/ltable.c
+++ /dev/null
@@ -1,588 +0,0 @@
1/*
2** $Id: ltable.c,v 2.31 2006/01/10 13:13:06 roberto Exp roberto $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7
8/*
9** Implementation of tables (aka arrays, objects, or hash tables).
10** Tables keep its elements in two parts: an array part and a hash part.
11** Non-negative integer keys are all candidates to be kept in the array
12** part. The actual size of the array is the largest `n' such that at
13** least half the slots between 0 and n are in use.
14** Hash uses a mix of chained scatter table with Brent's variation.
15** A main invariant of these tables is that, if an element is not
16** in its main position (i.e. the `original' position that its hash gives
17** to it), then the colliding element is in its own main position.
18** Hence even when the load factor reaches 100%, performance remains good.
19*/
20
21#include <math.h>
22#include <string.h>
23
24#define ltable_c
25#define LUA_CORE
26
27#include "lua.h"
28
29#include "ldebug.h"
30#include "ldo.h"
31#include "lgc.h"
32#include "lmem.h"
33#include "lobject.h"
34#include "lstate.h"
35#include "ltable.h"
36
37
38/*
39** max size of array part is 2^MAXBITS
40*/
41#if LUAI_BITSINT > 26
42#define MAXBITS 26
43#else
44#define MAXBITS (LUAI_BITSINT-2)
45#endif
46
47#define MAXASIZE (1 << MAXBITS)
48
49
50#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
51
52#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
53#define hashboolean(t,p) hashpow2(t, p)
54
55
56/*
57** for some types, it is better to avoid modulus by power of 2, as
58** they tend to have many 2 factors.
59*/
60#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
61
62
63#define hashpointer(t,p) hashmod(t, IntPoint(p))
64
65
66/*
67** number of ints inside a lua_Number
68*/
69#define numints cast_int(sizeof(lua_Number)/sizeof(int))
70
71
72
73#define dummynode (&dummynode_)
74
75static const Node dummynode_ = {
76 {{NULL}, LUA_TNIL}, /* value */
77 {{{NULL}, LUA_TNIL, NULL}} /* key */
78};
79
80
81/*
82** hash for lua_Numbers
83*/
84static Node *hashnum (const Table *t, lua_Number n) {
85 unsigned int a[numints];
86 int i;
87 n += 1; /* normalize number (avoid -0) */
88 lua_assert(sizeof(a) <= sizeof(n));
89 memcpy(a, &n, sizeof(a));
90 for (i = 1; i < numints; i++) a[0] += a[i];
91 return hashmod(t, a[0]);
92}
93
94
95
96/*
97** returns the `main' position of an element in a table (that is, the index
98** of its hash value)
99*/
100static Node *mainposition (const Table *t, const TValue *key) {
101 switch (ttype(key)) {
102 case LUA_TNUMBER:
103 return hashnum(t, nvalue(key));
104 case LUA_TSTRING:
105 return hashstr(t, rawtsvalue(key));
106 case LUA_TBOOLEAN:
107 return hashboolean(t, bvalue(key));
108 case LUA_TLIGHTUSERDATA:
109 return hashpointer(t, pvalue(key));
110 default:
111 return hashpointer(t, gcvalue(key));
112 }
113}
114
115
116/*
117** returns the index for `key' if `key' is an appropriate key to live in
118** the array part of the table, -1 otherwise.
119*/
120static int arrayindex (const TValue *key) {
121 if (ttisnumber(key)) {
122 lua_Number n = nvalue(key);
123 int k;
124 lua_number2int(k, n);
125 if (luai_numeq(cast_num(k), n))
126 return k;
127 }
128 return -1; /* `key' did not match some condition */
129}
130
131
132/*
133** returns the index of a `key' for table traversals. First goes all
134** elements in the array part, then elements in the hash part. The
135** beginning of a traversal is signalled by -1.
136*/
137static int findindex (lua_State *L, Table *t, StkId key) {
138 int i;
139 if (ttisnil(key)) return -1; /* first iteration */
140 i = arrayindex(key);
141 if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
142 return i-1; /* yes; that's the index (corrected to C) */
143 else {
144 Node *n = mainposition(t, key);
145 do { /* check whether `key' is somewhere in the chain */
146 /* key may be dead already, but it is ok to use it in `next' */
147 if (luaO_rawequalObj(key2tval(n), key) ||
148 (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
149 gcvalue(gkey(n)) == gcvalue(key))) {
150 i = cast_int(n - gnode(t, 0)); /* key index in hash table */
151 /* hash elements are numbered after array ones */
152 return i + t->sizearray;
153 }
154 else n = gnext(n);
155 } while (n);
156 luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
157 return 0; /* to avoid warnings */
158 }
159}
160
161
162int luaH_next (lua_State *L, Table *t, StkId key) {
163 int i = findindex(L, t, key); /* find original element */
164 for (i++; i < t->sizearray; i++) { /* try first array part */
165 if (!ttisnil(&t->array[i])) { /* a non-nil value? */
166 setnvalue(key, cast_num(i+1));
167 setobj2s(L, key+1, &t->array[i]);
168 return 1;
169 }
170 }
171 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
172 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
173 setobj2s(L, key, key2tval(gnode(t, i)));
174 setobj2s(L, key+1, gval(gnode(t, i)));
175 return 1;
176 }
177 }
178 return 0; /* no more elements */
179}
180
181
182/*
183** {=============================================================
184** Rehash
185** ==============================================================
186*/
187
188
189static int computesizes (int nums[], int *narray) {
190 int i;
191 int twotoi; /* 2^i */
192 int a = 0; /* number of elements smaller than 2^i */
193 int na = 0; /* number of elements to go to array part */
194 int n = 0; /* optimal size for array part */
195 for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
196 if (nums[i] > 0) {
197 a += nums[i];
198 if (a > twotoi/2) { /* more than half elements present? */
199 n = twotoi; /* optimal size (till now) */
200 na = a; /* all elements smaller than n will go to array part */
201 }
202 }
203 if (a == *narray) break; /* all elements already counted */
204 }
205 *narray = n;
206 lua_assert(*narray/2 <= na && na <= *narray);
207 return na;
208}
209
210
211static int countint (const TValue *key, int *nums) {
212 int k = arrayindex(key);
213 if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
214 nums[ceillog2(k)]++; /* count as such */
215 return 1;
216 }
217 else
218 return 0;
219}
220
221
222static int numusearray (const Table *t, int *nums) {
223 int lg;
224 int ttlg; /* 2^lg */
225 int ause = 0; /* summation of `nums' */
226 int i = 1; /* count to traverse all array keys */
227 for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
228 int lc = 0; /* counter */
229 int lim = ttlg;
230 if (lim > t->sizearray) {
231 lim = t->sizearray; /* adjust upper limit */
232 if (i > lim)
233 break; /* no more elements to count */
234 }
235 /* count elements in range (2^(lg-1), 2^lg] */
236 for (; i <= lim; i++) {
237 if (!ttisnil(&t->array[i-1]))
238 lc++;
239 }
240 nums[lg] += lc;
241 ause += lc;
242 }
243 return ause;
244}
245
246
247static int numusehash (const Table *t, int *nums, int *pnasize) {
248 int totaluse = 0; /* total number of elements */
249 int ause = 0; /* summation of `nums' */
250 int i = sizenode(t);
251 while (i--) {
252 Node *n = &t->node[i];
253 if (!ttisnil(gval(n))) {
254 ause += countint(key2tval(n), nums);
255 totaluse++;
256 }
257 }
258 *pnasize += ause;
259 return totaluse;
260}
261
262
263static void setarrayvector (lua_State *L, Table *t, int size) {
264 int i;
265 luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
266 for (i=t->sizearray; i<size; i++)
267 setnilvalue(&t->array[i]);
268 t->sizearray = size;
269}
270
271
272static void setnodevector (lua_State *L, Table *t, int size) {
273 int lsize;
274 if (size == 0) { /* no elements to hash part? */
275 t->node = cast(Node *, dummynode); /* use common `dummynode' */
276 lsize = 0;
277 }
278 else {
279 int i;
280 lsize = ceillog2(size);
281 if (lsize > MAXBITS)
282 luaG_runerror(L, "table overflow");
283 size = twoto(lsize);
284 t->node = luaM_newvector(L, size, Node);
285 for (i=0; i<size; i++) {
286 Node *n = gnode(t, i);
287 gnext(n) = NULL;
288 setnilvalue(gkey(n));
289 setnilvalue(gval(n));
290 }
291 }
292 t->lsizenode = cast_byte(lsize);
293 t->lastfree = gnode(t, size); /* all positions are free */
294}
295
296
297static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
298 int i;
299 int oldasize = t->sizearray;
300 int oldhsize = t->lsizenode;
301 Node *nold = t->node; /* save old hash ... */
302 if (nasize > oldasize) /* array part must grow? */
303 setarrayvector(L, t, nasize);
304 /* create new hash part with appropriate size */
305 setnodevector(L, t, nhsize);
306 if (nasize < oldasize) { /* array part must shrink? */
307 t->sizearray = nasize;
308 /* re-insert elements from vanishing slice */
309 for (i=nasize; i<oldasize; i++) {
310 if (!ttisnil(&t->array[i]))
311 setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
312 }
313 /* shrink array */
314 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
315 }
316 /* re-insert elements from hash part */
317 for (i = twoto(oldhsize) - 1; i >= 0; i--) {
318 Node *old = nold+i;
319 if (!ttisnil(gval(old)))
320 setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
321 }
322 if (nold != dummynode)
323 luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
324}
325
326
327void luaH_resizearray (lua_State *L, Table *t, int nasize) {
328 int nsize = (t->node == dummynode) ? 0 : sizenode(t);
329 resize(L, t, nasize, nsize);
330}
331
332
333static void rehash (lua_State *L, Table *t, const TValue *ek) {
334 int nasize, na;
335 int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
336 int i;
337 int totaluse;
338 for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
339 nasize = numusearray(t, nums); /* count keys in array part */
340 totaluse = nasize; /* all those keys are integer keys */
341 totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
342 /* count extra key */
343 nasize += countint(ek, nums);
344 totaluse++;
345 /* compute new size for array part */
346 na = computesizes(nums, &nasize);
347 /* resize the table to new computed sizes */
348 resize(L, t, nasize, totaluse - na);
349}
350
351
352
353/*
354** }=============================================================
355*/
356
357
358Table *luaH_new (lua_State *L, int narray, int nhash) {
359 Table *t = luaM_new(L, Table);
360 luaC_link(L, obj2gco(t), LUA_TTABLE);
361 t->metatable = NULL;
362 t->flags = cast_byte(~0);
363 /* temporary values (kept only if some malloc fails) */
364 t->array = NULL;
365 t->sizearray = 0;
366 t->lsizenode = 0;
367 t->node = cast(Node *, dummynode);
368 setarrayvector(L, t, narray);
369 setnodevector(L, t, nhash);
370 return t;
371}
372
373
374void luaH_free (lua_State *L, Table *t) {
375 if (t->node != dummynode)
376 luaM_freearray(L, t->node, sizenode(t), Node);
377 luaM_freearray(L, t->array, t->sizearray, TValue);
378 luaM_free(L, t);
379}
380
381
382static Node *getfreepos (Table *t) {
383 while (t->lastfree-- > t->node) {
384 if (ttisnil(gkey(t->lastfree)))
385 return t->lastfree;
386 }
387 return NULL; /* could not find a free place */
388}
389
390
391
392/*
393** inserts a new key into a hash table; first, check whether key's main
394** position is free. If not, check whether colliding node is in its main
395** position or not: if it is not, move colliding node to an empty place and
396** put new key in its main position; otherwise (colliding node is in its main
397** position), new key goes to an empty position.
398*/
399static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
400 Node *mp = mainposition(t, key);
401 if (!ttisnil(gval(mp)) || mp == dummynode) {
402 Node *othern;
403 Node *n = getfreepos(t); /* get a free place */
404 if (n == NULL) { /* cannot find a free place? */
405 rehash(L, t, key); /* grow table */
406 return luaH_set(L, t, key); /* re-insert key into grown table */
407 }
408 lua_assert(n != dummynode);
409 othern = mainposition(t, key2tval(mp));
410 if (othern != mp) { /* is colliding node out of its main position? */
411 /* yes; move colliding node into free position */
412 while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
413 gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
414 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
415 gnext(mp) = NULL; /* now `mp' is free */
416 setnilvalue(gval(mp));
417 }
418 else { /* colliding node is in its own main position */
419 /* new node will go into free position */
420 gnext(n) = gnext(mp); /* chain new position */
421 gnext(mp) = n;
422 mp = n;
423 }
424 }
425 gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
426 luaC_barriert(L, t, key);
427 lua_assert(ttisnil(gval(mp)));
428 return gval(mp);
429}
430
431
432/*
433** search function for integers
434*/
435const TValue *luaH_getnum (Table *t, int key) {
436 /* (1 <= key && key <= t->sizearray) */
437 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
438 return &t->array[key-1];
439 else {
440 lua_Number nk = cast_num(key);
441 Node *n = hashnum(t, nk);
442 do { /* check whether `key' is somewhere in the chain */
443 if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
444 return gval(n); /* that's it */
445 else n = gnext(n);
446 } while (n);
447 return luaO_nilobject;
448 }
449}
450
451
452/*
453** search function for strings
454*/
455const TValue *luaH_getstr (Table *t, TString *key) {
456 Node *n = hashstr(t, key);
457 do { /* check whether `key' is somewhere in the chain */
458 if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
459 return gval(n); /* that's it */
460 else n = gnext(n);
461 } while (n);
462 return luaO_nilobject;
463}
464
465
466/*
467** main search function
468*/
469const TValue *luaH_get (Table *t, const TValue *key) {
470 switch (ttype(key)) {
471 case LUA_TNIL: return luaO_nilobject;
472 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
473 case LUA_TNUMBER: {
474 int k;
475 lua_Number n = nvalue(key);
476 lua_number2int(k, n);
477 if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
478 return luaH_getnum(t, k); /* use specialized version */
479 /* else go through */
480 }
481 default: {
482 Node *n = mainposition(t, key);
483 do { /* check whether `key' is somewhere in the chain */
484 if (luaO_rawequalObj(key2tval(n), key))
485 return gval(n); /* that's it */
486 else n = gnext(n);
487 } while (n);
488 return luaO_nilobject;
489 }
490 }
491}
492
493
494TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
495 const TValue *p = luaH_get(t, key);
496 t->flags = 0;
497 if (p != luaO_nilobject)
498 return cast(TValue *, p);
499 else {
500 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
501 else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
502 luaG_runerror(L, "table index is NaN");
503 return newkey(L, t, key);
504 }
505}
506
507
508TValue *luaH_setnum (lua_State *L, Table *t, int key) {
509 const TValue *p = luaH_getnum(t, key);
510 if (p != luaO_nilobject)
511 return cast(TValue *, p);
512 else {
513 TValue k;
514 setnvalue(&k, cast_num(key));
515 return newkey(L, t, &k);
516 }
517}
518
519
520TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
521 const TValue *p = luaH_getstr(t, key);
522 if (p != luaO_nilobject)
523 return cast(TValue *, p);
524 else {
525 TValue k;
526 setsvalue(L, &k, key);
527 return newkey(L, t, &k);
528 }
529}
530
531
532static int unbound_search (Table *t, unsigned int j) {
533 unsigned int i = j; /* i is zero or a present index */
534 j++;
535 /* find `i' and `j' such that i is present and j is not */
536 while (!ttisnil(luaH_getnum(t, j))) {
537 i = j;
538 j *= 2;
539 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
540 /* table was built with bad purposes: resort to linear search */
541 i = 1;
542 while (!ttisnil(luaH_getnum(t, i))) i++;
543 return i - 1;
544 }
545 }
546 /* now do a binary search between them */
547 while (j - i > 1) {
548 unsigned int m = (i+j)/2;
549 if (ttisnil(luaH_getnum(t, m))) j = m;
550 else i = m;
551 }
552 return i;
553}
554
555
556/*
557** Try to find a boundary in table `t'. A `boundary' is an integer index
558** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
559*/
560int luaH_getn (Table *t) {
561 unsigned int j = t->sizearray;
562 if (j > 0 && ttisnil(&t->array[j - 1])) {
563 /* there is a boundary in the array part: (binary) search for it */
564 unsigned int i = 0;
565 while (j - i > 1) {
566 unsigned int m = (i+j)/2;
567 if (ttisnil(&t->array[m - 1])) j = m;
568 else i = m;
569 }
570 return i;
571 }
572 /* else must find a boundary in hash part */
573 else if (t->node == dummynode) /* hash part is empty? */
574 return j; /* that is easy... */
575 else return unbound_search(t, j);
576}
577
578
579
580#if defined(LUA_DEBUG)
581
582Node *luaH_mainposition (const Table *t, const TValue *key) {
583 return mainposition(t, key);
584}
585
586int luaH_isdummy (Node *n) { return n == dummynode; }
587
588#endif
diff --git a/ltable.h b/ltable.h
deleted file mode 100644
index e87597fd..00000000
--- a/ltable.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2** $Id: ltable.h,v 2.9 2006/01/10 12:51:53 roberto Exp roberto $
3** Lua tables (hash)
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltable_h
8#define ltable_h
9
10#include "lobject.h"
11
12
13#define gnode(t,i) (&(t)->node[i])
14#define gkey(n) (&(n)->i_key.nk)
15#define gval(n) (&(n)->i_val)
16#define gnext(n) ((n)->i_key.nk.next)
17
18#define key2tval(n) (&(n)->i_key.tvk)
19
20
21LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
22LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
23LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
24LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
25LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
26LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
27LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
28LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
29LUAI_FUNC void luaH_free (lua_State *L, Table *t);
30LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
31LUAI_FUNC int luaH_getn (Table *t);
32
33
34#if defined(LUA_DEBUG)
35LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
36LUAI_FUNC int luaH_isdummy (Node *n);
37#endif
38
39
40#endif
diff --git a/ltablib.c b/ltablib.c
deleted file mode 100644
index c2323eb2..00000000
--- a/ltablib.c
+++ /dev/null
@@ -1,278 +0,0 @@
1/*
2** $Id: ltablib.c,v 1.37 2005/10/21 13:47:42 roberto Exp roberto $
3** Library for Table Manipulation
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define ltablib_c
11#define LUA_LIB
12
13#include "lua.h"
14
15#include "lauxlib.h"
16#include "lualib.h"
17
18
19#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
20
21
22static int foreachi (lua_State *L) {
23 int i;
24 int n = aux_getn(L, 1);
25 luaL_checktype(L, 2, LUA_TFUNCTION);
26 for (i=1; i <= n; i++) {
27 lua_pushvalue(L, 2); /* function */
28 lua_pushinteger(L, i); /* 1st argument */
29 lua_rawgeti(L, 1, i); /* 2nd argument */
30 lua_call(L, 2, 1);
31 if (!lua_isnil(L, -1))
32 return 1;
33 lua_pop(L, 1); /* remove nil result */
34 }
35 return 0;
36}
37
38
39static int foreach (lua_State *L) {
40 luaL_checktype(L, 1, LUA_TTABLE);
41 luaL_checktype(L, 2, LUA_TFUNCTION);
42 lua_pushnil(L); /* first key */
43 while (lua_next(L, 1)) {
44 lua_pushvalue(L, 2); /* function */
45 lua_pushvalue(L, -3); /* key */
46 lua_pushvalue(L, -3); /* value */
47 lua_call(L, 2, 1);
48 if (!lua_isnil(L, -1))
49 return 1;
50 lua_pop(L, 2); /* remove value and result */
51 }
52 return 0;
53}
54
55
56static int maxn (lua_State *L) {
57 lua_Number max = 0;
58 luaL_checktype(L, 1, LUA_TTABLE);
59 lua_pushnil(L); /* first key */
60 while (lua_next(L, 1)) {
61 lua_pop(L, 1); /* remove value */
62 if (lua_type(L, -1) == LUA_TNUMBER) {
63 lua_Number v = lua_tonumber(L, -1);
64 if (v > max) max = v;
65 }
66 }
67 lua_pushnumber(L, max);
68 return 1;
69}
70
71
72static int getn (lua_State *L) {
73 lua_pushinteger(L, aux_getn(L, 1));
74 return 1;
75}
76
77
78static int setn (lua_State *L) {
79 luaL_checktype(L, 1, LUA_TTABLE);
80#ifndef luaL_setn
81 luaL_setn(L, 1, luaL_checkint(L, 2));
82#else
83 luaL_error(L, LUA_QL("setn") " is obsolete");
84#endif
85 lua_pushvalue(L, 1);
86 return 1;
87}
88
89
90static int tinsert (lua_State *L) {
91 int e = aux_getn(L, 1) + 1; /* first empty element */
92 int pos; /* where to insert new element */
93 switch (lua_gettop(L)) {
94 case 2: { /* called with only 2 arguments */
95 pos = e; /* insert new element at the end */
96 break;
97 }
98 case 3: {
99 int i;
100 pos = luaL_checkint(L, 2); /* 2nd argument is the position */
101 if (pos > e) e = pos; /* `grow' array if necessary */
102 for (i = e; i > pos; i--) { /* move up elements */
103 lua_rawgeti(L, 1, i-1);
104 lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
105 }
106 break;
107 }
108 default: {
109 return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
110 }
111 }
112 luaL_setn(L, 1, e); /* new size */
113 lua_rawseti(L, 1, pos); /* t[pos] = v */
114 return 0;
115}
116
117
118static int tremove (lua_State *L) {
119 int e = aux_getn(L, 1);
120 int pos = luaL_optint(L, 2, e);
121 if (e == 0) return 0; /* table is `empty' */
122 luaL_setn(L, 1, e - 1); /* t.n = n-1 */
123 lua_rawgeti(L, 1, pos); /* result = t[pos] */
124 for ( ;pos<e; pos++) {
125 lua_rawgeti(L, 1, pos+1);
126 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
127 }
128 lua_pushnil(L);
129 lua_rawseti(L, 1, e); /* t[e] = nil */
130 return 1;
131}
132
133
134static int tconcat (lua_State *L) {
135 luaL_Buffer b;
136 size_t lsep;
137 int i, last;
138 const char *sep = luaL_optlstring(L, 2, "", &lsep);
139 luaL_checktype(L, 1, LUA_TTABLE);
140 i = luaL_optint(L, 3, 1);
141 last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
142 luaL_buffinit(L, &b);
143 for (; i <= last; i++) {
144 lua_rawgeti(L, 1, i);
145 luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");
146 luaL_addvalue(&b);
147 if (i != last)
148 luaL_addlstring(&b, sep, lsep);
149 }
150 luaL_pushresult(&b);
151 return 1;
152}
153
154
155
156/*
157** {======================================================
158** Quicksort
159** (based on `Algorithms in MODULA-3', Robert Sedgewick;
160** Addison-Wesley, 1993.)
161*/
162
163
164static void set2 (lua_State *L, int i, int j) {
165 lua_rawseti(L, 1, i);
166 lua_rawseti(L, 1, j);
167}
168
169static int sort_comp (lua_State *L, int a, int b) {
170 if (!lua_isnil(L, 2)) { /* function? */
171 int res;
172 lua_pushvalue(L, 2);
173 lua_pushvalue(L, a-1); /* -1 to compensate function */
174 lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
175 lua_call(L, 2, 1);
176 res = lua_toboolean(L, -1);
177 lua_pop(L, 1);
178 return res;
179 }
180 else /* a < b? */
181 return lua_lessthan(L, a, b);
182}
183
184static void auxsort (lua_State *L, int l, int u) {
185 while (l < u) { /* for tail recursion */
186 int i, j;
187 /* sort elements a[l], a[(l+u)/2] and a[u] */
188 lua_rawgeti(L, 1, l);
189 lua_rawgeti(L, 1, u);
190 if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
191 set2(L, l, u); /* swap a[l] - a[u] */
192 else
193 lua_pop(L, 2);
194 if (u-l == 1) break; /* only 2 elements */
195 i = (l+u)/2;
196 lua_rawgeti(L, 1, i);
197 lua_rawgeti(L, 1, l);
198 if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
199 set2(L, i, l);
200 else {
201 lua_pop(L, 1); /* remove a[l] */
202 lua_rawgeti(L, 1, u);
203 if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
204 set2(L, i, u);
205 else
206 lua_pop(L, 2);
207 }
208 if (u-l == 2) break; /* only 3 elements */
209 lua_rawgeti(L, 1, i); /* Pivot */
210 lua_pushvalue(L, -1);
211 lua_rawgeti(L, 1, u-1);
212 set2(L, i, u-1);
213 /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
214 i = l; j = u-1;
215 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
216 /* repeat ++i until a[i] >= P */
217 while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
218 if (i>u) luaL_error(L, "invalid order function for sorting");
219 lua_pop(L, 1); /* remove a[i] */
220 }
221 /* repeat --j until a[j] <= P */
222 while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
223 if (j<l) luaL_error(L, "invalid order function for sorting");
224 lua_pop(L, 1); /* remove a[j] */
225 }
226 if (j<i) {
227 lua_pop(L, 3); /* pop pivot, a[i], a[j] */
228 break;
229 }
230 set2(L, i, j);
231 }
232 lua_rawgeti(L, 1, u-1);
233 lua_rawgeti(L, 1, i);
234 set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
235 /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
236 /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
237 if (i-l < u-i) {
238 j=l; i=i-1; l=i+2;
239 }
240 else {
241 j=i+1; i=u; u=j-2;
242 }
243 auxsort(L, j, i); /* call recursively the smaller one */
244 } /* repeat the routine for the larger one */
245}
246
247static int sort (lua_State *L) {
248 int n = aux_getn(L, 1);
249 luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
250 if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
251 luaL_checktype(L, 2, LUA_TFUNCTION);
252 lua_settop(L, 2); /* make sure there is two arguments */
253 auxsort(L, 1, n);
254 return 0;
255}
256
257/* }====================================================== */
258
259
260static const luaL_Reg tab_funcs[] = {
261 {"concat", tconcat},
262 {"foreach", foreach},
263 {"foreachi", foreachi},
264 {"getn", getn},
265 {"maxn", maxn},
266 {"insert", tinsert},
267 {"remove", tremove},
268 {"setn", setn},
269 {"sort", sort},
270 {NULL, NULL}
271};
272
273
274LUALIB_API int luaopen_table (lua_State *L) {
275 luaL_register(L, LUA_TABLIBNAME, tab_funcs);
276 return 1;
277}
278
diff --git a/ltests.c b/ltests.c
deleted file mode 100644
index 7ae9ba6f..00000000
--- a/ltests.c
+++ /dev/null
@@ -1,1145 +0,0 @@
1/*
2** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp roberto $
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 <limits.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define ltests_c
15#define LUA_CORE
16
17#include "lua.h"
18
19#include "lapi.h"
20#include "lauxlib.h"
21#include "lcode.h"
22#include "ldebug.h"
23#include "ldo.h"
24#include "lfunc.h"
25#include "lmem.h"
26#include "lopcodes.h"
27#include "lstate.h"
28#include "lstring.h"
29#include "ltable.h"
30#include "lualib.h"
31
32
33
34/*
35** The whole module only makes sense with LUA_DEBUG on
36*/
37#if defined(LUA_DEBUG)
38
39
40int Trick = 0;
41
42
43static lua_State *lua_state = NULL;
44
45int islocked = 0;
46
47
48#define obj_at(L,k) (L->ci->base+(k) - 1)
49
50
51static void setnameval (lua_State *L, const char *name, int val) {
52 lua_pushstring(L, name);
53 lua_pushinteger(L, val);
54 lua_settable(L, -3);
55}
56
57
58/*
59** {======================================================================
60** Controlled version for realloc.
61** =======================================================================
62*/
63
64#define MARK 0x55 /* 01010101 (a nice pattern) */
65
66#ifndef EXTERNMEMCHECK
67/* full memory check */
68#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
69#define MARKSIZE 16 /* size of marks after each block */
70#define blockhead(b) (cast(char *, b) - HEADER)
71#define setsize(newblock, size) (*cast(size_t *, newblock) = size)
72#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
73#define fillmem(mem,size) memset(mem, -MARK, size)
74#else
75/* external memory check: don't do it twice */
76#define HEADER 0
77#define MARKSIZE 0
78#define blockhead(b) (b)
79#define setsize(newblock, size) /* empty */
80#define checkblocksize(b,size) (1)
81#define fillmem(mem,size) /* empty */
82#endif
83
84
85Memcontrol memcontrol = {0L, 0L, 0L, 0L};
86
87
88static void *checkblock (void *block, size_t size) {
89 void *b = blockhead(block);
90 int i;
91 for (i=0;i<MARKSIZE;i++)
92 lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
93 return b;
94}
95
96
97static void freeblock (Memcontrol *mc, void *block, size_t size) {
98 if (block) {
99 lua_assert(checkblocksize(block, size));
100 block = checkblock(block, size);
101 fillmem(block, size+HEADER+MARKSIZE); /* erase block */
102 free(block); /* free original block */
103 mc->numblocks--;
104 mc->total -= size;
105 }
106}
107
108
109void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) {
110 Memcontrol *mc = cast(Memcontrol *, ud);
111 lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
112 if (mc->memlimit == 0) { /* first time? */
113 char *limit = getenv("MEMLIMIT"); /* initialize memory limit */
114 mc->memlimit = limit ? strtoul(limit, NULL, 10) : ULONG_MAX;
115 }
116 if (size == 0) {
117 freeblock(mc, block, oldsize);
118 return NULL;
119 }
120 else if (size > oldsize && mc->total+size-oldsize > mc->memlimit)
121 return NULL; /* to test memory allocation errors */
122 else {
123 void *newblock;
124 int i;
125 size_t realsize = HEADER+size+MARKSIZE;
126 size_t commonsize = (oldsize < size) ? oldsize : size;
127 if (realsize < size) return NULL; /* overflow! */
128 newblock = malloc(realsize); /* alloc a new block */
129 if (newblock == NULL) return NULL;
130 if (block) {
131 memcpy(cast(char *, newblock)+HEADER, block, commonsize);
132 freeblock(mc, block, oldsize); /* erase (and check) old copy */
133 }
134 /* initialize new part of the block with something `weird' */
135 fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
136 mc->total += size;
137 if (mc->total > mc->maxmem)
138 mc->maxmem = mc->total;
139 mc->numblocks++;
140 setsize(newblock, size);
141 for (i=0;i<MARKSIZE;i++)
142 *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
143 return cast(char *, newblock)+HEADER;
144 }
145}
146
147
148/* }====================================================================== */
149
150
151
152/*
153** {======================================================
154** Functions to check memory consistency
155** =======================================================
156*/
157
158static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
159 if (isdead(g,t)) return 0;
160 if (g->gcstate == GCSpropagate)
161 return !isblack(f) || !iswhite(t);
162 else if (g->gcstate == GCSfinalize)
163 return iswhite(f);
164 else
165 return 1;
166}
167
168
169static void printobj (global_State *g, GCObject *o) {
170 int i = 0;
171 GCObject *p;
172 for (p = g->rootgc; p != o && p != NULL; p = p->gch.next) i++;
173 if (p == NULL) i = -1;
174 printf("%d:%s(%p)-%c(%02X)", i, luaT_typenames[o->gch.tt], (void *)o,
175 isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', o->gch.marked);
176}
177
178
179static int testobjref (global_State *g, GCObject *f, GCObject *t) {
180 int r = testobjref1(g,f,t);
181 if (!r) {
182 printf("%d(%02X) - ", g->gcstate, g->currentwhite);
183 printobj(g, f);
184 printf("\t-> ");
185 printobj(g, t);
186 printf("\n");
187 }
188 return r;
189}
190
191#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t)))
192
193#define checkvalref(g,f,t) lua_assert(!iscollectable(t) || \
194 ((ttype(t) == (t)->value.gc->gch.tt) && testobjref(g,f,gcvalue(t))))
195
196
197
198static void checktable (global_State *g, Table *h) {
199 int i;
200 int weakkey = 0;
201 int weakvalue = 0;
202 const TValue *mode;
203 GCObject *hgc = obj2gco(h);
204 if (h->metatable)
205 checkobjref(g, hgc, h->metatable);
206 mode = gfasttm(g, h->metatable, TM_MODE);
207 if (mode && ttisstring(mode)) { /* is there a weak mode? */
208 weakkey = (strchr(svalue(mode), 'k') != NULL);
209 weakvalue = (strchr(svalue(mode), 'v') != NULL);
210 }
211 i = h->sizearray;
212 while (i--)
213 checkvalref(g, hgc, &h->array[i]);
214 i = sizenode(h);
215 while (i--) {
216 Node *n = gnode(h, i);
217 if (!ttisnil(gval(n))) {
218 lua_assert(!ttisnil(gkey(n)));
219 checkvalref(g, hgc, gkey(n));
220 checkvalref(g, hgc, gval(n));
221 }
222 }
223}
224
225
226/*
227** All marks are conditional because a GC may happen while the
228** prototype is still being created
229*/
230static void checkproto (global_State *g, Proto *f) {
231 int i;
232 GCObject *fgc = obj2gco(f);
233 if (f->source) checkobjref(g, fgc, f->source);
234 for (i=0; i<f->sizek; i++) {
235 if (ttisstring(f->k+i))
236 checkobjref(g, fgc, rawtsvalue(f->k+i));
237 }
238 for (i=0; i<f->sizeupvalues; i++) {
239 if (f->upvalues[i])
240 checkobjref(g, fgc, f->upvalues[i]);
241 }
242 for (i=0; i<f->sizep; i++) {
243 if (f->p[i])
244 checkobjref(g, fgc, f->p[i]);
245 }
246 for (i=0; i<f->sizelocvars; i++) {
247 if (f->locvars[i].varname)
248 checkobjref(g, fgc, f->locvars[i].varname);
249 }
250}
251
252
253
254static void checkclosure (global_State *g, Closure *cl) {
255 GCObject *clgc = obj2gco(cl);
256 checkobjref(g, clgc, cl->l.env);
257 if (cl->c.isC) {
258 int i;
259 for (i=0; i<cl->c.nupvalues; i++)
260 checkvalref(g, clgc, &cl->c.upvalue[i]);
261 }
262 else {
263 int i;
264 lua_assert(cl->l.nupvalues == cl->l.p->nups);
265 checkobjref(g, clgc, cl->l.p);
266 for (i=0; i<cl->l.nupvalues; i++) {
267 if (cl->l.upvals[i]) {
268 lua_assert(cl->l.upvals[i]->tt == LUA_TUPVAL);
269 checkobjref(g, clgc, cl->l.upvals[i]);
270 }
271 }
272 }
273}
274
275
276static void checkstack (global_State *g, lua_State *L1) {
277 StkId o;
278 CallInfo *ci;
279 GCObject *uvo;
280 lua_assert(!isdead(g, obj2gco(L1)));
281 for (uvo = L1->openupval; uvo != NULL; uvo = uvo->gch.next) {
282 UpVal *uv = gco2uv(uvo);
283 lua_assert(uv->v != &uv->u.value); /* must be open */
284 lua_assert(!isblack(uvo)); /* open upvalues cannot be black */
285 }
286 checkliveness(g, gt(L1));
287 if (L1->base_ci) {
288 for (ci = L1->base_ci; ci <= L1->ci; ci++) {
289 lua_assert(ci->top <= L1->stack_last);
290 lua_assert(lua_checkpc(L1, ci));
291 }
292 }
293 else lua_assert(L1->size_ci == 0);
294 if (L1->stack) {
295 for (o = L1->stack; o < L1->top; o++)
296 checkliveness(g, o);
297 }
298 else lua_assert(L1->stacksize == 0);
299}
300
301
302static void checkobject (global_State *g, GCObject *o) {
303 if (isdead(g, o))
304/* lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);*/
305{ if (!(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep))
306printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marked);
307}
308 else {
309 if (g->gcstate == GCSfinalize)
310 lua_assert(iswhite(o));
311 switch (o->gch.tt) {
312 case LUA_TUPVAL: {
313 UpVal *uv = gco2uv(o);
314 lua_assert(uv->v == &uv->u.value); /* must be closed */
315 lua_assert(!isgray(o)); /* closed upvalues are never gray */
316 checkvalref(g, o, uv->v);
317 break;
318 }
319 case LUA_TUSERDATA: {
320 Table *mt = gco2u(o)->metatable;
321 if (mt) checkobjref(g, o, mt);
322 break;
323 }
324 case LUA_TTABLE: {
325 checktable(g, gco2h(o));
326 break;
327 }
328 case LUA_TTHREAD: {
329 checkstack(g, gco2th(o));
330 break;
331 }
332 case LUA_TFUNCTION: {
333 checkclosure(g, gco2cl(o));
334 break;
335 }
336 case LUA_TPROTO: {
337 checkproto(g, gco2p(o));
338 break;
339 }
340 default: lua_assert(0);
341 }
342 }
343}
344
345
346int lua_checkpc (lua_State *L, pCallInfo ci) {
347 if (ci == L->base_ci || !f_isLua(ci)) return 1;
348 else {
349 Proto *p = ci_func(ci)->l.p;
350 if (ci < L->ci)
351 return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
352 else
353 return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
354 }
355}
356
357
358int lua_checkmemory (lua_State *L) {
359 global_State *g = G(L);
360 GCObject *o;
361 UpVal *uv;
362 checkstack(g, g->mainthread);
363 for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next)
364 checkobject(g, o);
365 for (o = o->gch.next; o != NULL; o = o->gch.next) {
366 lua_assert(o->gch.tt == LUA_TUSERDATA);
367 checkobject(g, o);
368 }
369 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
370 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
371 lua_assert(uv->v != &uv->u.value); /* must be open */
372 lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never black */
373 checkvalref(g, obj2gco(uv), uv->v);
374 }
375 return 0;
376}
377
378/* }====================================================== */
379
380
381
382/*
383** {======================================================
384** Disassembler
385** =======================================================
386*/
387
388
389static char *buildop (Proto *p, int pc, char *buff) {
390 Instruction i = p->code[pc];
391 OpCode o = GET_OPCODE(i);
392 const char *name = luaP_opnames[o];
393 int line = getline(p, pc);
394 sprintf(buff, "(%4d) %4d - ", line, pc);
395 switch (getOpMode(o)) {
396 case iABC:
397 sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
398 GETARG_A(i), GETARG_B(i), GETARG_C(i));
399 break;
400 case iABx:
401 sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
402 break;
403 case iAsBx:
404 sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
405 break;
406 }
407 return buff;
408}
409
410
411#if 0
412void luaI_printcode (Proto *pt, int size) {
413 int pc;
414 for (pc=0; pc<size; pc++) {
415 char buff[100];
416 printf("%s\n", buildop(pt, pc, buff));
417 }
418 printf("-------\n");
419}
420#endif
421
422
423static int listcode (lua_State *L) {
424 int pc;
425 Proto *p;
426 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
427 1, "Lua function expected");
428 p = clvalue(obj_at(L, 1))->l.p;
429 lua_newtable(L);
430 setnameval(L, "maxstack", p->maxstacksize);
431 setnameval(L, "numparams", p->numparams);
432 for (pc=0; pc<p->sizecode; pc++) {
433 char buff[100];
434 lua_pushinteger(L, pc+1);
435 lua_pushstring(L, buildop(p, pc, buff));
436 lua_settable(L, -3);
437 }
438 return 1;
439}
440
441
442static int listk (lua_State *L) {
443 Proto *p;
444 int i;
445 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
446 1, "Lua function expected");
447 p = clvalue(obj_at(L, 1))->l.p;
448 lua_createtable(L, p->sizek, 0);
449 for (i=0; i<p->sizek; i++) {
450 luaA_pushobject(L, p->k+i);
451 lua_rawseti(L, -2, i+1);
452 }
453 return 1;
454}
455
456
457static int listlocals (lua_State *L) {
458 Proto *p;
459 int pc = luaL_checkint(L, 2) - 1;
460 int i = 0;
461 const char *name;
462 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
463 1, "Lua function expected");
464 p = clvalue(obj_at(L, 1))->l.p;
465 while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
466 lua_pushstring(L, name);
467 return i-1;
468}
469
470/* }====================================================== */
471
472
473
474
475static int get_limits (lua_State *L) {
476 lua_createtable(L, 0, 5);
477 setnameval(L, "BITS_INT", LUAI_BITSINT);
478 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
479 setnameval(L, "MAXVARS", LUAI_MAXVARS);
480 setnameval(L, "MAXSTACK", MAXSTACK);
481 setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
482 setnameval(L, "NUM_OPCODES", NUM_OPCODES);
483 return 1;
484}
485
486
487static int mem_query (lua_State *L) {
488 if (lua_isnone(L, 1)) {
489 lua_pushinteger(L, memcontrol.total);
490 lua_pushinteger(L, memcontrol.numblocks);
491 lua_pushinteger(L, memcontrol.maxmem);
492 return 3;
493 }
494 else {
495 memcontrol.memlimit = luaL_checkint(L, 1);
496 return 0;
497 }
498}
499
500
501static int settrick (lua_State *L) {
502 Trick = lua_tointeger(L, 1);
503 return 0;
504}
505
506
507/*static int set_gcstate (lua_State *L) {
508 static const char *const state[] = {"propagate", "sweep", "finalize"};
509 return 0;
510}*/
511
512
513static int get_gccolor (lua_State *L) {
514 TValue *o;
515 luaL_checkany(L, 1);
516 o = obj_at(L, 1);
517 if (!iscollectable(o))
518 lua_pushstring(L, "no collectable");
519 else
520 lua_pushstring(L, iswhite(gcvalue(o)) ? "white" :
521 isblack(gcvalue(o)) ? "black" : "grey");
522 return 1;
523}
524
525
526static int gcstate (lua_State *L) {
527 switch(G(L)->gcstate) {
528 case GCSpropagate: lua_pushstring(L, "propagate"); break;
529 case GCSsweepstring: lua_pushstring(L, "sweep strings"); break;
530 case GCSsweep: lua_pushstring(L, "sweep"); break;
531 case GCSfinalize: lua_pushstring(L, "finalize"); break;
532 }
533 return 1;
534}
535
536
537static int hash_query (lua_State *L) {
538 if (lua_isnone(L, 2)) {
539 luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
540 lua_pushinteger(L, tsvalue(obj_at(L, 1))->hash);
541 }
542 else {
543 TValue *o = obj_at(L, 1);
544 Table *t;
545 luaL_checktype(L, 2, LUA_TTABLE);
546 t = hvalue(obj_at(L, 2));
547 lua_pushinteger(L, luaH_mainposition(t, o) - t->node);
548 }
549 return 1;
550}
551
552
553static int stacklevel (lua_State *L) {
554 unsigned long a = 0;
555 lua_pushinteger(L, (L->top - L->stack));
556 lua_pushinteger(L, (L->stack_last - L->stack));
557 lua_pushinteger(L, (L->ci - L->base_ci));
558 lua_pushinteger(L, (L->end_ci - L->base_ci));
559 lua_pushinteger(L, (unsigned long)&a);
560 return 5;
561}
562
563
564static int table_query (lua_State *L) {
565 const Table *t;
566 int i = luaL_optint(L, 2, -1);
567 luaL_checktype(L, 1, LUA_TTABLE);
568 t = hvalue(obj_at(L, 1));
569 if (i == -1) {
570 lua_pushinteger(L, t->sizearray);
571 lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t));
572 lua_pushinteger(L, t->lastfree - t->node);
573 }
574 else if (i < t->sizearray) {
575 lua_pushinteger(L, i);
576 luaA_pushobject(L, &t->array[i]);
577 lua_pushnil(L);
578 }
579 else if ((i -= t->sizearray) < sizenode(t)) {
580 if (!ttisnil(gval(gnode(t, i))) ||
581 ttisnil(gkey(gnode(t, i))) ||
582 ttisnumber(gkey(gnode(t, i)))) {
583 luaA_pushobject(L, key2tval(gnode(t, i)));
584 }
585 else
586 lua_pushliteral(L, "<undef>");
587 luaA_pushobject(L, gval(gnode(t, i)));
588 if (gnext(&t->node[i]))
589 lua_pushinteger(L, gnext(&t->node[i]) - t->node);
590 else
591 lua_pushnil(L);
592 }
593 return 3;
594}
595
596
597static int string_query (lua_State *L) {
598 stringtable *tb = &G(L)->strt;
599 int s = luaL_optint(L, 2, 0) - 1;
600 if (s==-1) {
601 lua_pushinteger(L ,tb->nuse);
602 lua_pushinteger(L ,tb->size);
603 return 2;
604 }
605 else if (s < tb->size) {
606 GCObject *ts;
607 int n = 0;
608 for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
609 setsvalue2s(L, L->top, gco2ts(ts));
610 incr_top(L);
611 n++;
612 }
613 return n;
614 }
615 return 0;
616}
617
618
619static int tref (lua_State *L) {
620 int level = lua_gettop(L);
621 int lock = luaL_optint(L, 2, 1);
622 luaL_checkany(L, 1);
623 lua_pushvalue(L, 1);
624 lua_pushinteger(L, lua_ref(L, lock));
625 lua_assert(lua_gettop(L) == level+1); /* +1 for result */
626 return 1;
627}
628
629static int getref (lua_State *L) {
630 int level = lua_gettop(L);
631 lua_getref(L, luaL_checkint(L, 1));
632 lua_assert(lua_gettop(L) == level+1);
633 return 1;
634}
635
636static int unref (lua_State *L) {
637 int level = lua_gettop(L);
638 lua_unref(L, luaL_checkint(L, 1));
639 lua_assert(lua_gettop(L) == level);
640 return 0;
641}
642
643
644static int upvalue (lua_State *L) {
645 int n = luaL_checkint(L, 2);
646 luaL_checktype(L, 1, LUA_TFUNCTION);
647 if (lua_isnone(L, 3)) {
648 const char *name = lua_getupvalue(L, 1, n);
649 if (name == NULL) return 0;
650 lua_pushstring(L, name);
651 return 2;
652 }
653 else {
654 const char *name = lua_setupvalue(L, 1, n);
655 lua_pushstring(L, name);
656 return 1;
657 }
658}
659
660
661static int newuserdata (lua_State *L) {
662 size_t size = luaL_checkint(L, 1);
663 char *p = cast(char *, lua_newuserdata(L, size));
664 while (size--) *p++ = '\0';
665 return 1;
666}
667
668
669static int pushuserdata (lua_State *L) {
670 lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
671 return 1;
672}
673
674
675static int udataval (lua_State *L) {
676 lua_pushinteger(L, cast(long, lua_touserdata(L, 1)));
677 return 1;
678}
679
680
681static int doonnewstack (lua_State *L) {
682 lua_State *L1 = lua_newthread(L);
683 size_t l;
684 const char *s = luaL_checklstring(L, 1, &l);
685 int status = luaL_loadbuffer(L1, s, l, s);
686 if (status == 0)
687 status = lua_pcall(L1, 0, 0, 0);
688 lua_pushinteger(L, status);
689 return 1;
690}
691
692
693static int s2d (lua_State *L) {
694 lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
695 return 1;
696}
697
698
699static int d2s (lua_State *L) {
700 double d = luaL_checknumber(L, 1);
701 lua_pushlstring(L, cast(char *, &d), sizeof(d));
702 return 1;
703}
704
705
706static int num2int (lua_State *L) {
707 lua_pushinteger(L, lua_tointeger(L, 1));
708 return 1;
709}
710
711
712static int newstate (lua_State *L) {
713 void *ud;
714 lua_Alloc f = lua_getallocf(L, &ud);
715 lua_State *L1 = lua_newstate(f, ud);
716 if (L1)
717 lua_pushinteger(L, (unsigned long)L1);
718 else
719 lua_pushnil(L);
720 return 1;
721}
722
723
724static int loadlib (lua_State *L) {
725 static const luaL_Reg libs[] = {
726 {"baselibopen", luaopen_base},
727 {"dblibopen", luaopen_debug},
728 {"iolibopen", luaopen_io},
729 {"mathlibopen", luaopen_math},
730 {"strlibopen", luaopen_string},
731 {"tablibopen", luaopen_table},
732 {"packageopen", luaopen_package},
733 {NULL, NULL}
734 };
735 lua_State *L1 = cast(lua_State *,
736 cast(unsigned long, luaL_checknumber(L, 1)));
737 lua_pushvalue(L1, LUA_GLOBALSINDEX);
738 luaL_register(L1, NULL, libs);
739 return 0;
740}
741
742static int closestate (lua_State *L) {
743 lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
744 lua_close(L1);
745 return 0;
746}
747
748static int doremote (lua_State *L) {
749 lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
750 size_t lcode;
751 const char *code = luaL_checklstring(L, 2, &lcode);
752 int status;
753 lua_settop(L1, 0);
754 status = luaL_loadbuffer(L1, code, lcode, code);
755 if (status == 0)
756 status = lua_pcall(L1, 0, LUA_MULTRET, 0);
757 if (status != 0) {
758 lua_pushnil(L);
759 lua_pushinteger(L, status);
760 lua_pushstring(L, lua_tostring(L1, -1));
761 return 3;
762 }
763 else {
764 int i = 0;
765 while (!lua_isnone(L1, ++i))
766 lua_pushstring(L, lua_tostring(L1, i));
767 lua_pop(L1, i-1);
768 return i-1;
769 }
770}
771
772
773static int log2_aux (lua_State *L) {
774 lua_pushinteger(L, luaO_log2(luaL_checkint(L, 1)));
775 return 1;
776}
777
778static int int2fb_aux (lua_State *L) {
779 int b = luaO_int2fb(luaL_checkint(L, 1));
780 lua_pushinteger(L, b);
781 lua_pushinteger(L, luaO_fb2int(b));
782 return 2;
783}
784
785
786
787/*
788** {======================================================
789** function to test the API with C. It interprets a kind of assembler
790** language with calls to the API, so the test can be driven by Lua code
791** =======================================================
792*/
793
794static const char *const delimits = " \t\n,;";
795
796static void skip (const char **pc) {
797 while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
798}
799
800static int getnum_aux (lua_State *L, const char **pc) {
801 int res = 0;
802 int sig = 1;
803 skip(pc);
804 if (**pc == '.') {
805 res = cast_int(lua_tonumber(L, -1));
806 lua_pop(L, 1);
807 (*pc)++;
808 return res;
809 }
810 else if (**pc == '-') {
811 sig = -1;
812 (*pc)++;
813 }
814 while (isdigit(cast_int(**pc))) res = res*10 + (*(*pc)++) - '0';
815 return sig*res;
816}
817
818static const char *getname_aux (char *buff, const char **pc) {
819 int i = 0;
820 skip(pc);
821 while (**pc != '\0' && !strchr(delimits, **pc))
822 buff[i++] = *(*pc)++;
823 buff[i] = '\0';
824 return buff;
825}
826
827
828static int getindex_aux (lua_State *L, const char **pc) {
829 skip(pc);
830 switch (*(*pc)++) {
831 case 'R': return LUA_REGISTRYINDEX;
832 case 'G': return LUA_GLOBALSINDEX;
833 case 'E': return LUA_ENVIRONINDEX;
834 case 'U': return lua_upvalueindex(getnum_aux(L, pc));
835 default: (*pc)--; return getnum_aux(L, pc);
836 }
837}
838
839#define EQ(s1) (strcmp(s1, inst) == 0)
840
841#define getnum (getnum_aux(L, &pc))
842#define getname (getname_aux(buff, &pc))
843#define getindex (getindex_aux(L, &pc))
844
845
846static int testC (lua_State *L) {
847 char buff[30];
848 lua_State *L1;
849 const char *pc;
850 if (lua_isnumber(L, 1)) {
851 L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
852 pc = luaL_checkstring(L, 2);
853 }
854 else {
855 L1 = L;
856 pc = luaL_checkstring(L, 1);
857 }
858 for (;;) {
859 const char *inst = getname;
860 if EQ("") return 0;
861 else if EQ("isnumber") {
862 lua_pushinteger(L1, lua_isnumber(L1, getindex));
863 }
864 else if EQ("isstring") {
865 lua_pushinteger(L1, lua_isstring(L1, getindex));
866 }
867 else if EQ("istable") {
868 lua_pushinteger(L1, lua_istable(L1, getindex));
869 }
870 else if EQ("iscfunction") {
871 lua_pushinteger(L1, lua_iscfunction(L1, getindex));
872 }
873 else if EQ("isfunction") {
874 lua_pushinteger(L1, lua_isfunction(L1, getindex));
875 }
876 else if EQ("isuserdata") {
877 lua_pushinteger(L1, lua_isuserdata(L1, getindex));
878 }
879 else if EQ("isudataval") {
880 lua_pushinteger(L1, lua_islightuserdata(L1, getindex));
881 }
882 else if EQ("isnil") {
883 lua_pushinteger(L1, lua_isnil(L1, getindex));
884 }
885 else if EQ("isnull") {
886 lua_pushinteger(L1, lua_isnone(L1, getindex));
887 }
888 else if EQ("tonumber") {
889 lua_pushnumber(L1, lua_tonumber(L1, getindex));
890 }
891 else if EQ("tostring") {
892 const char *s = lua_tostring(L1, getindex);
893 lua_pushstring(L1, s);
894 }
895 else if EQ("objsize") {
896 lua_pushinteger(L1, lua_objlen(L1, getindex));
897 }
898 else if EQ("tocfunction") {
899 lua_pushcfunction(L1, lua_tocfunction(L1, getindex));
900 }
901 else if EQ("return") {
902 return getnum;
903 }
904 else if EQ("gettop") {
905 lua_pushinteger(L1, lua_gettop(L1));
906 }
907 else if EQ("settop") {
908 lua_settop(L1, getnum);
909 }
910 else if EQ("pop") {
911 lua_pop(L1, getnum);
912 }
913 else if EQ("pushnum") {
914 lua_pushinteger(L1, getnum);
915 }
916 else if EQ("pushstring") {
917 lua_pushstring(L1, getname);
918 }
919 else if EQ("pushnil") {
920 lua_pushnil(L1);
921 }
922 else if EQ("pushbool") {
923 lua_pushboolean(L1, getnum);
924 }
925 else if EQ("newuserdata") {
926 lua_newuserdata(L1, getnum);
927 }
928 else if EQ("tobool") {
929 lua_pushinteger(L1, lua_toboolean(L1, getindex));
930 }
931 else if EQ("pushvalue") {
932 lua_pushvalue(L1, getindex);
933 }
934 else if EQ("pushcclosure") {
935 lua_pushcclosure(L1, testC, getnum);
936 }
937 else if EQ("remove") {
938 lua_remove(L1, getnum);
939 }
940 else if EQ("insert") {
941 lua_insert(L1, getnum);
942 }
943 else if EQ("replace") {
944 lua_replace(L1, getindex);
945 }
946 else if EQ("gettable") {
947 lua_gettable(L1, getindex);
948 }
949 else if EQ("settable") {
950 lua_settable(L1, getindex);
951 }
952 else if EQ("next") {
953 lua_next(L1, -2);
954 }
955 else if EQ("concat") {
956 lua_concat(L1, getnum);
957 }
958 else if EQ("lessthan") {
959 int a = getindex;
960 lua_pushboolean(L1, lua_lessthan(L1, a, getindex));
961 }
962 else if EQ("equal") {
963 int a = getindex;
964 lua_pushboolean(L1, lua_equal(L1, a, getindex));
965 }
966 else if EQ("rawcall") {
967 int narg = getnum;
968 int nres = getnum;
969 lua_call(L1, narg, nres);
970 }
971 else if EQ("call") {
972 int narg = getnum;
973 int nres = getnum;
974 lua_pcall(L1, narg, nres, 0);
975 }
976 else if EQ("loadstring") {
977 size_t sl;
978 const char *s = luaL_checklstring(L1, getnum, &sl);
979 luaL_loadbuffer(L1, s, sl, s);
980 }
981 else if EQ("loadfile") {
982 luaL_loadfile(L1, luaL_checkstring(L1, getnum));
983 }
984 else if EQ("setmetatable") {
985 lua_setmetatable(L1, getindex);
986 }
987 else if EQ("getmetatable") {
988 if (lua_getmetatable(L1, getindex) == 0)
989 lua_pushnil(L1);
990 }
991 else if EQ("type") {
992 lua_pushstring(L1, luaL_typename(L1, getnum));
993 }
994 else if EQ("getn") {
995 int i = getindex;
996 lua_pushinteger(L1, luaL_getn(L1, i));
997 }
998#ifndef luaL_setn
999 else if EQ("setn") {
1000 int i = getindex;
1001 int n = cast_int(lua_tonumber(L1, -1));
1002 luaL_setn(L1, i, n);
1003 lua_pop(L1, 1);
1004 }
1005#endif
1006 else if EQ("throw") {
1007#if defined(__cplusplus)
1008static struct X { int x; } x;
1009 throw x;
1010#else
1011 luaL_error(L1, "C++");
1012#endif
1013 break;
1014 }
1015 else luaL_error(L, "unknown instruction %s", buff);
1016 }
1017 return 0;
1018}
1019
1020/* }====================================================== */
1021
1022
1023/*
1024** {======================================================
1025** tests for yield inside hooks
1026** =======================================================
1027*/
1028
1029static void yieldf (lua_State *L, lua_Debug *ar) {
1030 lua_yield(L, 0);
1031}
1032
1033static int setyhook (lua_State *L) {
1034 if (lua_isnoneornil(L, 1))
1035 lua_sethook(L, NULL, 0, 0); /* turn off hooks */
1036 else {
1037 const char *smask = luaL_checkstring(L, 1);
1038 int count = luaL_optint(L, 2, 0);
1039 int mask = 0;
1040 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
1041 if (count > 0) mask |= LUA_MASKCOUNT;
1042 lua_sethook(L, yieldf, mask, count);
1043 }
1044 return 0;
1045}
1046
1047
1048static int coresume (lua_State *L) {
1049 int status;
1050 lua_State *co = lua_tothread(L, 1);
1051 luaL_argcheck(L, co, 1, "coroutine expected");
1052 status = lua_resume(co, 0);
1053 if (status != 0) {
1054 lua_pushboolean(L, 0);
1055 lua_insert(L, -2);
1056 return 2; /* return false + error message */
1057 }
1058 else {
1059 lua_pushboolean(L, 1);
1060 return 1;
1061 }
1062}
1063
1064/* }====================================================== */
1065
1066
1067
1068/*
1069** {======================================================
1070** tests auxlib functions
1071** =======================================================
1072*/
1073
1074static int auxgsub (lua_State *L) {
1075 const char *s1 = luaL_checkstring(L, 1);
1076 const char *s2 = luaL_checkstring(L, 2);
1077 const char *s3 = luaL_checkstring(L, 3);
1078 lua_settop(L, 3);
1079 luaL_gsub(L, s1, s2, s3);
1080 lua_assert(lua_gettop(L) == 4);
1081 return 1;
1082}
1083
1084
1085/* }====================================================== */
1086
1087
1088
1089static const struct luaL_Reg tests_funcs[] = {
1090 {"checkmemory", lua_checkmemory},
1091 {"closestate", closestate},
1092 {"d2s", d2s},
1093 {"doonnewstack", doonnewstack},
1094 {"doremote", doremote},
1095 {"gccolor", get_gccolor},
1096 {"gcstate", gcstate},
1097 {"getref", getref},
1098 {"gsub", auxgsub},
1099 {"hash", hash_query},
1100 {"int2fb", int2fb_aux},
1101 {"limits", get_limits},
1102 {"listcode", listcode},
1103 {"listk", listk},
1104 {"listlocals", listlocals},
1105 {"loadlib", loadlib},
1106 {"log2", log2_aux},
1107 {"newstate", newstate},
1108 {"newuserdata", newuserdata},
1109 {"num2int", num2int},
1110 {"pushuserdata", pushuserdata},
1111 {"querystr", string_query},
1112 {"querytab", table_query},
1113 {"ref", tref},
1114 {"resume", coresume},
1115 {"s2d", s2d},
1116 {"setyhook", setyhook},
1117 {"stacklevel", stacklevel},
1118 {"testC", testC},
1119 {"totalmem", mem_query},
1120 {"trick", settrick},
1121 {"udataval", udataval},
1122 {"unref", unref},
1123 {"upvalue", upvalue},
1124 {NULL, NULL}
1125};
1126
1127
1128static void checkfinalmem (void) {
1129 lua_assert(memcontrol.numblocks == 0);
1130 lua_assert(memcontrol.total == 0);
1131}
1132
1133
1134int luaB_opentests (lua_State *L) {
1135 void *ud;
1136 atexit(checkfinalmem);
1137 lua_assert(lua_getallocf(L, &ud) == debug_realloc);
1138 lua_assert(ud == cast(void *, &memcontrol));
1139 lua_setallocf(L, lua_getallocf(L, NULL), ud);
1140 lua_state = L; /* keep first state to be opened */
1141 luaL_register(L, "T", tests_funcs);
1142 return 0;
1143}
1144
1145#endif
diff --git a/ltests.h b/ltests.h
deleted file mode 100644
index 42a560c7..00000000
--- a/ltests.h
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp roberto $
3** Internal Header for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltests_h
8#define ltests_h
9
10
11#include <stdlib.h>
12
13
14#define LUA_DEBUG
15
16#undef NDEBUG
17#include <assert.h>
18#define lua_assert(c) assert(c)
19
20
21/* to avoid warnings, and to make sure value is really unused */
22#define UNUSED(x) (x=0, (void)(x))
23
24
25/* memory allocator control variables */
26typedef struct Memcontrol {
27 unsigned long numblocks;
28 unsigned long total;
29 unsigned long maxmem;
30 unsigned long memlimit;
31} Memcontrol;
32
33LUAI_DATA Memcontrol memcontrol;
34
35
36/*
37** generic variable for debug tricks
38*/
39LUAI_DATA int Trick;
40
41
42void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
43
44#ifdef lua_c
45#define luaL_newstate() lua_newstate(debug_realloc, &memcontrol)
46#endif
47
48
49typedef struct CallInfo *pCallInfo;
50
51int lua_checkmemory (lua_State *L);
52int lua_checkpc (lua_State *L, pCallInfo ci);
53
54
55/* test for lock/unlock */
56#undef luai_userstateopen
57#undef luai_userstatethread
58#undef lua_lock
59#undef lua_unlock
60#undef LUAI_EXTRASPACE
61
62struct L_EXTRA { int lock; int *plock; };
63#define LUAI_EXTRASPACE sizeof(struct L_EXTRA)
64#define getlock(l) (cast(struct L_EXTRA *, l) - 1)
65#define luai_userstateopen(l) \
66 (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
67#define luai_userstatethread(l,l1) (getlock(l1)->plock = getlock(l)->plock)
68#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
69#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
70
71
72int luaB_opentests (lua_State *L);
73
74#ifdef lua_c
75#define luaL_openlibs(L) { (luaL_openlibs)(L); luaB_opentests(L); }
76#endif
77
78
79
80/* change some sizes to give some bugs a chance */
81
82#undef LUAL_BUFFERSIZE
83#define LUAL_BUFFERSIZE 27
84#define MINSTRTABSIZE 2
85
86#endif
diff --git a/ltm.c b/ltm.c
deleted file mode 100644
index 3b4715dd..00000000
--- a/ltm.c
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2** $Id: ltm.c,v 2.7 2005/12/22 16:19:56 roberto Exp roberto $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define ltm_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "lobject.h"
16#include "lstate.h"
17#include "lstring.h"
18#include "ltable.h"
19#include "ltm.h"
20
21
22
23const char *const luaT_typenames[] = {
24 "nil", "boolean", "userdata", "number",
25 "string", "table", "function", "userdata", "thread",
26 "proto", "upval"
27};
28
29
30void luaT_init (lua_State *L) {
31 static const char *const luaT_eventname[] = { /* ORDER TM */
32 "__index", "__newindex",
33 "__gc", "__mode", "__eq",
34 "__add", "__sub", "__mul", "__div", "__mod",
35 "__pow", "__unm", "__len", "__lt", "__le",
36 "__concat", "__call"
37 };
38 int i;
39 for (i=0; i<TM_N; i++) {
40 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
41 luaS_fix(G(L)->tmname[i]); /* never collect these names */
42 }
43}
44
45
46/*
47** function to be used with macro "fasttm": optimized for absence of
48** tag methods
49*/
50const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
51 const TValue *tm = luaH_getstr(events, ename);
52 lua_assert(event <= TM_EQ);
53 if (ttisnil(tm)) { /* no tag method? */
54 events->flags |= cast_byte(1u<<event); /* cache this fact */
55 return NULL;
56 }
57 else return tm;
58}
59
60
61const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
62 Table *mt;
63 switch (ttype(o)) {
64 case LUA_TTABLE:
65 mt = hvalue(o)->metatable;
66 break;
67 case LUA_TUSERDATA:
68 mt = uvalue(o)->metatable;
69 break;
70 default:
71 mt = G(L)->mt[ttype(o)];
72 }
73 return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
74}
75
diff --git a/ltm.h b/ltm.h
deleted file mode 100644
index dcb14fc6..00000000
--- a/ltm.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2** $Id: ltm.h,v 2.5 2005/05/20 15:53:42 roberto Exp roberto $
3** Tag methods
4** See Copyright Notice in lua.h
5*/
6
7#ifndef ltm_h
8#define ltm_h
9
10
11#include "lobject.h"
12
13
14/*
15* WARNING: if you change the order of this enumeration,
16* grep "ORDER TM"
17*/
18typedef enum {
19 TM_INDEX,
20 TM_NEWINDEX,
21 TM_GC,
22 TM_MODE,
23 TM_EQ, /* last tag method with `fast' access */
24 TM_ADD,
25 TM_SUB,
26 TM_MUL,
27 TM_DIV,
28 TM_MOD,
29 TM_POW,
30 TM_UNM,
31 TM_LEN,
32 TM_LT,
33 TM_LE,
34 TM_CONCAT,
35 TM_CALL,
36 TM_N /* number of elements in the enum */
37} TMS;
38
39
40
41#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
42 ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
43
44#define fasttm(l,et,e) gfasttm(G(l), et, e)
45
46LUAI_DATA const char *const luaT_typenames[];
47
48
49LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
50LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
51 TMS event);
52LUAI_FUNC void luaT_init (lua_State *L);
53
54#endif
diff --git a/lua.c b/lua.c
deleted file mode 100644
index b8cf32ed..00000000
--- a/lua.c
+++ /dev/null
@@ -1,390 +0,0 @@
1/*
2** $Id: lua.c,v 1.159 2006/05/24 14:16:39 roberto Exp roberto $
3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h
5*/
6
7
8#include <signal.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define lua_c
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20
21
22static lua_State *globalL = NULL;
23
24static const char *progname = LUA_PROGNAME;
25
26
27
28static void lstop (lua_State *L, lua_Debug *ar) {
29 (void)ar; /* unused arg. */
30 lua_sethook(L, NULL, 0, 0);
31 luaL_error(L, "interrupted!");
32}
33
34
35static void laction (int i) {
36 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
37 terminate process (default action) */
38 lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
39}
40
41
42static void print_usage (void) {
43 fprintf(stderr,
44 "usage: %s [options] [script [args]].\n"
45 "Available options are:\n"
46 " -e stat execute string " LUA_QL("stat") "\n"
47 " -l name require library " LUA_QL("name") "\n"
48 " -i enter interactive mode after executing " LUA_QL("script") "\n"
49 " -v show version information\n"
50 " -- stop handling options\n"
51 " - execute stdin and stop handling options\n"
52 ,
53 progname);
54 fflush(stderr);
55}
56
57
58static void l_message (const char *pname, const char *msg) {
59 if (pname) fprintf(stderr, "%s: ", pname);
60 fprintf(stderr, "%s\n", msg);
61 fflush(stderr);
62}
63
64
65static int report (lua_State *L, int status) {
66 if (status && !lua_isnil(L, -1)) {
67 const char *msg = lua_tostring(L, -1);
68 if (msg == NULL) msg = "(error object is not a string)";
69 l_message(progname, msg);
70 lua_pop(L, 1);
71 }
72 return status;
73}
74
75
76static int traceback (lua_State *L) {
77 lua_getfield(L, LUA_GLOBALSINDEX, "debug");
78 if (!lua_istable(L, -1)) {
79 lua_pop(L, 1);
80 return 1;
81 }
82 lua_getfield(L, -1, "traceback");
83 if (!lua_isfunction(L, -1)) {
84 lua_pop(L, 2);
85 return 1;
86 }
87 lua_pushvalue(L, 1); /* pass error message */
88 lua_pushinteger(L, 2); /* skip this function and traceback */
89 lua_call(L, 2, 1); /* call debug.traceback */
90 return 1;
91}
92
93
94static int docall (lua_State *L, int narg, int clear) {
95 int status;
96 int base = lua_gettop(L) - narg; /* function index */
97 lua_pushcfunction(L, traceback); /* push traceback function */
98 lua_insert(L, base); /* put it under chunk and args */
99 signal(SIGINT, laction);
100 status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
101 signal(SIGINT, SIG_DFL);
102 lua_remove(L, base); /* remove traceback function */
103 /* force a complete garbage collection in case of errors */
104 if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
105 return status;
106}
107
108
109static void print_version (void) {
110 l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT);
111}
112
113
114static int getargs (lua_State *L, char **argv, int n) {
115 int narg;
116 int i;
117 int argc = 0;
118 while (argv[argc]) argc++; /* count total number of arguments */
119 narg = argc - (n + 1); /* number of arguments to the script */
120 luaL_checkstack(L, narg + 3, "too many arguments to script");
121 for (i=n+1; i < argc; i++)
122 lua_pushstring(L, argv[i]);
123 lua_createtable(L, narg, n + 1);
124 for (i=0; i < argc; i++) {
125 lua_pushstring(L, argv[i]);
126 lua_rawseti(L, -2, i - n);
127 }
128 return narg;
129}
130
131
132static int dofile (lua_State *L, const char *name) {
133 int status = luaL_loadfile(L, name) || docall(L, 0, 1);
134 return report(L, status);
135}
136
137
138static int dostring (lua_State *L, const char *s, const char *name) {
139 int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
140 return report(L, status);
141}
142
143
144static int dolibrary (lua_State *L, const char *name) {
145 lua_getglobal(L, "require");
146 lua_pushstring(L, name);
147 return report(L, lua_pcall(L, 1, 0, 0));
148}
149
150
151static const char *get_prompt (lua_State *L, int firstline) {
152 const char *p;
153 lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
154 p = lua_tostring(L, -1);
155 if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
156 lua_pop(L, 1); /* remove global */
157 return p;
158}
159
160
161static int incomplete (lua_State *L, int status) {
162 if (status == LUA_ERRSYNTAX) {
163 size_t lmsg;
164 const char *msg = lua_tolstring(L, -1, &lmsg);
165 const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
166 if (strstr(msg, LUA_QL("<eof>")) == tp) {
167 lua_pop(L, 1);
168 return 1;
169 }
170 }
171 return 0; /* else... */
172}
173
174
175static int pushline (lua_State *L, int firstline) {
176 char buffer[LUA_MAXINPUT];
177 char *b = buffer;
178 size_t l;
179 const char *prmt = get_prompt(L, firstline);
180 if (lua_readline(L, b, prmt) == 0)
181 return 0; /* no input */
182 l = strlen(b);
183 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
184 b[l-1] = '\0'; /* remove it */
185 if (firstline && b[0] == '=') /* first line starts with `=' ? */
186 lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
187 else
188 lua_pushstring(L, b);
189 lua_freeline(L, b);
190 return 1;
191}
192
193
194static int loadline (lua_State *L) {
195 int status;
196 lua_settop(L, 0);
197 if (!pushline(L, 1))
198 return -1; /* no input */
199 for (;;) { /* repeat until gets a complete line */
200 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
201 if (!incomplete(L, status)) break; /* cannot try to add lines? */
202 if (!pushline(L, 0)) /* no more input? */
203 return -1;
204 lua_pushliteral(L, "\n"); /* add a new line... */
205 lua_insert(L, -2); /* ...between the two lines */
206 lua_concat(L, 3); /* join them */
207 }
208 lua_saveline(L, 1);
209 lua_remove(L, 1); /* remove line */
210 return status;
211}
212
213
214static void dotty (lua_State *L) {
215 int status;
216 const char *oldprogname = progname;
217 progname = NULL;
218 while ((status = loadline(L)) != -1) {
219 if (status == 0) status = docall(L, 0, 0);
220 report(L, status);
221 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
222 lua_getglobal(L, "print");
223 lua_insert(L, 1);
224 if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
225 l_message(progname, lua_pushfstring(L,
226 "error calling " LUA_QL("print") " (%s)",
227 lua_tostring(L, -1)));
228 }
229 }
230 lua_settop(L, 0); /* clear stack */
231 fputs("\n", stdout);
232 fflush(stdout);
233 progname = oldprogname;
234}
235
236
237static int handle_script (lua_State *L, char **argv, int n) {
238 int status;
239 const char *fname;
240 int narg = getargs(L, argv, n); /* collect arguments */
241 lua_setglobal(L, "arg");
242 fname = argv[n];
243 if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
244 fname = NULL; /* stdin */
245 status = luaL_loadfile(L, fname);
246 lua_insert(L, -(narg+1));
247 if (status == 0)
248 status = docall(L, narg, 0);
249 else
250 lua_pop(L, narg);
251 return report(L, status);
252}
253
254
255/* check that argument has no extra characters at the end */
256#define notail(x) {if ((x)[2] != '\0') return -1;}
257
258
259static int collectargs (char **argv, int *pi, int *pv, int *pe) {
260 int i;
261 for (i = 1; argv[i] != NULL; i++) {
262 if (argv[i][0] != '-') /* not an option? */
263 return i;
264 switch (argv[i][1]) { /* option */
265 case '-':
266 notail(argv[i]);
267 return (argv[i+1] != NULL ? i+1 : 0);
268 case '\0':
269 return i;
270 case 'i':
271 notail(argv[i]);
272 *pi = 1; /* go through */
273 case 'v':
274 notail(argv[i]);
275 *pv = 1;
276 break;
277 case 'e':
278 *pe = 1; /* go through */
279 case 'l':
280 if (argv[i][2] == '\0') {
281 i++;
282 if (argv[i] == NULL) return -1;
283 }
284 break;
285 default: return -1; /* invalid option */
286 }
287 }
288 return 0;
289}
290
291
292static int runargs (lua_State *L, char **argv, int n) {
293 int i;
294 for (i = 1; i < n; i++) {
295 if (argv[i] == NULL) continue;
296 lua_assert(argv[i][0] == '-');
297 switch (argv[i][1]) { /* option */
298 case 'e': {
299 const char *chunk = argv[i] + 2;
300 if (*chunk == '\0') chunk = argv[++i];
301 lua_assert(chunk != NULL);
302 if (dostring(L, chunk, "=(command line)") != 0)
303 return 1;
304 break;
305 }
306 case 'l': {
307 const char *filename = argv[i] + 2;
308 if (*filename == '\0') filename = argv[++i];
309 lua_assert(filename != NULL);
310 if (dolibrary(L, filename))
311 return 1; /* stop if file fails */
312 break;
313 }
314 default: break;
315 }
316 }
317 return 0;
318}
319
320
321static int handle_luainit (lua_State *L) {
322 const char *init = getenv(LUA_INIT);
323 if (init == NULL) return 0; /* status OK */
324 else if (init[0] == '@')
325 return dofile(L, init+1);
326 else
327 return dostring(L, init, "=" LUA_INIT);
328}
329
330
331struct Smain {
332 int argc;
333 char **argv;
334 int status;
335};
336
337
338static int pmain (lua_State *L) {
339 struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
340 char **argv = s->argv;
341 int script;
342 int has_i = 0, has_v = 0, has_e = 0;
343 globalL = L;
344 if (argv[0] && argv[0][0]) progname = argv[0];
345 lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
346 luaL_openlibs(L); /* open libraries */
347 lua_gc(L, LUA_GCRESTART, 0);
348 s->status = handle_luainit(L);
349 if (s->status != 0) return 0;
350 script = collectargs(argv, &has_i, &has_v, &has_e);
351 if (script < 0) { /* invalid args? */
352 print_usage();
353 s->status = 1;
354 return 0;
355 }
356 if (has_v) print_version();
357 s->status = runargs(L, argv, (script > 0) ? script : s->argc);
358 if (s->status != 0) return 0;
359 if (script)
360 s->status = handle_script(L, argv, script);
361 if (s->status != 0) return 0;
362 if (has_i)
363 dotty(L);
364 else if (script == 0 && !has_e && !has_v) {
365 if (lua_stdin_is_tty()) {
366 print_version();
367 dotty(L);
368 }
369 else dofile(L, NULL); /* executes stdin as a file */
370 }
371 return 0;
372}
373
374
375int main (int argc, char **argv) {
376 int status;
377 struct Smain s;
378 lua_State *L = lua_open(); /* create state */
379 if (L == NULL) {
380 l_message(argv[0], "cannot create state: not enough memory");
381 return EXIT_FAILURE;
382 }
383 s.argc = argc;
384 s.argv = argv;
385 status = lua_cpcall(L, &pmain, &s);
386 report(L, status);
387 lua_close(L);
388 return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
389}
390
diff --git a/lua.h b/lua.h
deleted file mode 100644
index fd1e46e5..00000000
--- a/lua.h
+++ /dev/null
@@ -1,385 +0,0 @@
1/*
2** $Id: lua.h,v 1.217 2006/05/31 16:50:40 roberto Exp roberto $
3** Lua - An Extensible Extension Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file
6*/
7
8
9#ifndef lua_h
10#define lua_h
11
12#include <stdarg.h>
13#include <stddef.h>
14
15
16#include "luaconf.h"
17
18
19#define LUA_VERSION "Lua 5.1"
20#define LUA_RELEASE "Lua 5.1.1"
21#define LUA_VERSION_NUM 501
22#define LUA_COPYRIGHT "Copyright (C) 1994-2006 Lua.org, PUC-Rio"
23#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
24
25
26/* mark for precompiled code (`<esc>Lua') */
27#define LUA_SIGNATURE "\033Lua"
28
29/* option for multiple returns in `lua_pcall' and `lua_call' */
30#define LUA_MULTRET (-1)
31
32
33/*
34** pseudo-indices
35*/
36#define LUA_REGISTRYINDEX (-10000)
37#define LUA_ENVIRONINDEX (-10001)
38#define LUA_GLOBALSINDEX (-10002)
39#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
40
41
42/* thread status; 0 is OK */
43#define LUA_YIELD 1
44#define LUA_ERRRUN 2
45#define LUA_ERRSYNTAX 3
46#define LUA_ERRMEM 4
47#define LUA_ERRERR 5
48
49
50typedef struct lua_State lua_State;
51
52typedef int (*lua_CFunction) (lua_State *L);
53
54
55/*
56** functions that read/write blocks when loading/dumping Lua chunks
57*/
58typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
59
60typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
61
62
63/*
64** prototype for memory-allocation functions
65*/
66typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
67
68
69/*
70** basic types
71*/
72#define LUA_TNONE (-1)
73
74#define LUA_TNIL 0
75#define LUA_TBOOLEAN 1
76#define LUA_TLIGHTUSERDATA 2
77#define LUA_TNUMBER 3
78#define LUA_TSTRING 4
79#define LUA_TTABLE 5
80#define LUA_TFUNCTION 6
81#define LUA_TUSERDATA 7
82#define LUA_TTHREAD 8
83
84
85
86/* minimum Lua stack available to a C function */
87#define LUA_MINSTACK 20
88
89
90/*
91** generic extra include file
92*/
93#if defined(LUA_USER_H)
94#include LUA_USER_H
95#endif
96
97
98/* type of numbers in Lua */
99typedef LUA_NUMBER lua_Number;
100
101
102/* type for integer functions */
103typedef LUA_INTEGER lua_Integer;
104
105
106
107/*
108** state manipulation
109*/
110LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
111LUA_API void (lua_close) (lua_State *L);
112LUA_API lua_State *(lua_newthread) (lua_State *L);
113
114LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
115
116
117/*
118** basic stack manipulation
119*/
120LUA_API int (lua_gettop) (lua_State *L);
121LUA_API void (lua_settop) (lua_State *L, int idx);
122LUA_API void (lua_pushvalue) (lua_State *L, int idx);
123LUA_API void (lua_remove) (lua_State *L, int idx);
124LUA_API void (lua_insert) (lua_State *L, int idx);
125LUA_API void (lua_replace) (lua_State *L, int idx);
126LUA_API int (lua_checkstack) (lua_State *L, int sz);
127
128LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
129
130
131/*
132** access functions (stack -> C)
133*/
134
135LUA_API int (lua_isnumber) (lua_State *L, int idx);
136LUA_API int (lua_isstring) (lua_State *L, int idx);
137LUA_API int (lua_iscfunction) (lua_State *L, int idx);
138LUA_API int (lua_isuserdata) (lua_State *L, int idx);
139LUA_API int (lua_type) (lua_State *L, int idx);
140LUA_API const char *(lua_typename) (lua_State *L, int tp);
141
142LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
143LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
144LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
145
146LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
147LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
148LUA_API int (lua_toboolean) (lua_State *L, int idx);
149LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
150LUA_API size_t (lua_objlen) (lua_State *L, int idx);
151LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
152LUA_API void *(lua_touserdata) (lua_State *L, int idx);
153LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
154LUA_API const void *(lua_topointer) (lua_State *L, int idx);
155
156
157/*
158** push functions (C -> stack)
159*/
160LUA_API void (lua_pushnil) (lua_State *L);
161LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
162LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
163LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
164LUA_API void (lua_pushstring) (lua_State *L, const char *s);
165LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
166 va_list argp);
167LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
168LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
169LUA_API void (lua_pushboolean) (lua_State *L, int b);
170LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
171LUA_API int (lua_pushthread) (lua_State *L);
172
173
174/*
175** get functions (Lua -> stack)
176*/
177LUA_API void (lua_gettable) (lua_State *L, int idx);
178LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
179LUA_API void (lua_rawget) (lua_State *L, int idx);
180LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
181LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
182LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
183LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
184LUA_API void (lua_getfenv) (lua_State *L, int idx);
185
186
187/*
188** set functions (stack -> Lua)
189*/
190LUA_API void (lua_settable) (lua_State *L, int idx);
191LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
192LUA_API void (lua_rawset) (lua_State *L, int idx);
193LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
194LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
195LUA_API int (lua_setfenv) (lua_State *L, int idx);
196
197
198/*
199** `load' and `call' functions (load and run Lua code)
200*/
201LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
202LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
203LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
204LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
205 const char *chunkname);
206
207LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
208
209
210/*
211** coroutine functions
212*/
213LUA_API int (lua_yield) (lua_State *L, int nresults);
214LUA_API int (lua_resume) (lua_State *L, int narg);
215LUA_API int (lua_status) (lua_State *L);
216
217/*
218** garbage-collection function and options
219*/
220
221#define LUA_GCSTOP 0
222#define LUA_GCRESTART 1
223#define LUA_GCCOLLECT 2
224#define LUA_GCCOUNT 3
225#define LUA_GCCOUNTB 4
226#define LUA_GCSTEP 5
227#define LUA_GCSETPAUSE 6
228#define LUA_GCSETSTEPMUL 7
229
230LUA_API int (lua_gc) (lua_State *L, int what, int data);
231
232
233/*
234** miscellaneous functions
235*/
236
237LUA_API int (lua_error) (lua_State *L);
238
239LUA_API int (lua_next) (lua_State *L, int idx);
240
241LUA_API void (lua_concat) (lua_State *L, int n);
242
243LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
244LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
245
246
247
248/*
249** ===============================================================
250** some useful macros
251** ===============================================================
252*/
253
254#define lua_pop(L,n) lua_settop(L, -(n)-1)
255
256#define lua_newtable(L) lua_createtable(L, 0, 0)
257
258#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
259
260#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
261
262#define lua_strlen(L,i) lua_objlen(L, (i))
263
264#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
265#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
266#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
267#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
268#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
269#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
270#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
271#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
272
273#define lua_pushliteral(L, s) \
274 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
275
276#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
277#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
278
279#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
280
281
282
283/*
284** compatibility macros and functions
285*/
286
287#define lua_open() luaL_newstate()
288
289#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
290
291#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
292
293#define lua_Chunkreader lua_Reader
294#define lua_Chunkwriter lua_Writer
295
296
297
298/*
299** {======================================================================
300** Debug API
301** =======================================================================
302*/
303
304
305/*
306** Event codes
307*/
308#define LUA_HOOKCALL 0
309#define LUA_HOOKRET 1
310#define LUA_HOOKLINE 2
311#define LUA_HOOKCOUNT 3
312#define LUA_HOOKTAILRET 4
313
314
315/*
316** Event masks
317*/
318#define LUA_MASKCALL (1 << LUA_HOOKCALL)
319#define LUA_MASKRET (1 << LUA_HOOKRET)
320#define LUA_MASKLINE (1 << LUA_HOOKLINE)
321#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
322
323typedef struct lua_Debug lua_Debug; /* activation record */
324
325
326/* Functions to be called by the debuger in specific events */
327typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
328
329
330LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
331LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
332LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
333LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
334LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
335LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
336
337LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
338LUA_API lua_Hook lua_gethook (lua_State *L);
339LUA_API int lua_gethookmask (lua_State *L);
340LUA_API int lua_gethookcount (lua_State *L);
341
342
343struct lua_Debug {
344 int event;
345 const char *name; /* (n) */
346 const char *namewhat; /* (n) `global', `local', `field', `method' */
347 const char *what; /* (S) `Lua', `C', `main', `tail' */
348 const char *source; /* (S) */
349 int currentline; /* (l) */
350 int nups; /* (u) number of upvalues */
351 int linedefined; /* (S) */
352 int lastlinedefined; /* (S) */
353 char short_src[LUA_IDSIZE]; /* (S) */
354 /* private part */
355 int i_ci; /* active function */
356};
357
358/* }====================================================================== */
359
360
361/******************************************************************************
362* Copyright (C) 1994-2006 Lua.org, PUC-Rio. All rights reserved.
363*
364* Permission is hereby granted, free of charge, to any person obtaining
365* a copy of this software and associated documentation files (the
366* "Software"), to deal in the Software without restriction, including
367* without limitation the rights to use, copy, modify, merge, publish,
368* distribute, sublicense, and/or sell copies of the Software, and to
369* permit persons to whom the Software is furnished to do so, subject to
370* the following conditions:
371*
372* The above copyright notice and this permission notice shall be
373* included in all copies or substantial portions of the Software.
374*
375* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
376* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
377* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
378* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
379* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
380* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
381* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
382******************************************************************************/
383
384
385#endif
diff --git a/luaconf.h b/luaconf.h
deleted file mode 100644
index 0d42a985..00000000
--- a/luaconf.h
+++ /dev/null
@@ -1,762 +0,0 @@
1/*
2** $Id: luaconf.h,v 1.81 2006/02/10 17:44:06 roberto Exp roberto $
3** Configuration file for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lconfig_h
9#define lconfig_h
10
11#include <limits.h>
12#include <stddef.h>
13
14
15/*
16** ==================================================================
17** Search for "@@" to find all configurable definitions.
18** ===================================================================
19*/
20
21
22/*
23@@ LUA_ANSI controls the use of non-ansi features.
24** CHANGE it (define it) if you want Lua to avoid the use of any
25** non-ansi feature or library.
26*/
27#if defined(__STRICT_ANSI__)
28#define LUA_ANSI
29#endif
30
31
32#if !defined(LUA_ANSI) && defined(_WIN32)
33#define LUA_WIN
34#endif
35
36#if defined(LUA_USE_LINUX)
37#define LUA_USE_POSIX
38#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
39#define LUA_USE_READLINE /* needs some extra libraries */
40#endif
41
42#if defined(LUA_USE_MACOSX)
43#define LUA_USE_POSIX
44#define LUA_DL_DYLD /* does not need extra library */
45#endif
46
47
48
49/*
50@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
51@* Interfaces Extension (XSI).
52** CHANGE it (define it) if your system is XSI compatible.
53*/
54#if defined(LUA_USE_POSIX)
55#define LUA_USE_MKSTEMP
56#define LUA_USE_ISATTY
57#define LUA_USE_POPEN
58#define LUA_USE_ULONGJMP
59#endif
60
61
62/*
63@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
64@* Lua check to set its paths.
65@@ LUA_INIT is the name of the environment variable that Lua
66@* checks for initialization code.
67** CHANGE them if you want different names.
68*/
69#define LUA_PATH "LUA_PATH"
70#define LUA_CPATH "LUA_CPATH"
71#define LUA_INIT "LUA_INIT"
72
73
74/*
75@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
76@* Lua libraries.
77@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
78@* C libraries.
79** CHANGE them if your machine has a non-conventional directory
80** hierarchy or if you want to install your libraries in
81** non-conventional directories.
82*/
83#if defined(_WIN32)
84/*
85** In Windows, any exclamation mark ('!') in the path is replaced by the
86** path of the directory of the executable file of the current process.
87*/
88#define LUA_LDIR "!\\lua\\"
89#define LUA_CDIR "!\\"
90#define LUA_PATH_DEFAULT \
91 ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
92 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
93#define LUA_CPATH_DEFAULT \
94 ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
95
96#else
97#define LUA_ROOT "/usr/local/"
98#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
99#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
100#define LUA_PATH_DEFAULT \
101 "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
102 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
103#define LUA_CPATH_DEFAULT \
104 "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
105#endif
106
107
108/*
109@@ LUA_DIRSEP is the directory separator (for submodules).
110** CHANGE it if your machine does not use "/" as the directory separator
111** and is not Windows. (On Windows Lua automatically uses "\".)
112*/
113#if defined(_WIN32)
114#define LUA_DIRSEP "\\"
115#else
116#define LUA_DIRSEP "/"
117#endif
118
119
120/*
121@@ LUA_PATHSEP is the character that separates templates in a path.
122@@ LUA_PATH_MARK is the string that marks the substitution points in a
123@* template.
124@@ LUA_EXECDIR in a Windows path is replaced by the executable's
125@* directory.
126@@ LUA_IGMARK is a mark to ignore all before it when bulding the
127@* luaopen_ function name.
128** CHANGE them if for some reason your system cannot use those
129** characters. (E.g., if one of those characters is a common character
130** in file/directory names.) Probably you do not need to change them.
131*/
132#define LUA_PATHSEP ";"
133#define LUA_PATH_MARK "?"
134#define LUA_EXECDIR "!"
135#define LUA_IGMARK "-"
136
137
138/*
139@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
140** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
141** machines, ptrdiff_t gives a good choice between int or long.)
142*/
143#define LUA_INTEGER ptrdiff_t
144
145
146/*
147@@ LUA_API is a mark for all core API functions.
148@@ LUALIB_API is a mark for all standard library functions.
149** CHANGE them if you need to define those functions in some special way.
150** For instance, if you want to create one Windows DLL with the core and
151** the libraries, you may want to use the following definition (define
152** LUA_BUILD_AS_DLL to get it).
153*/
154#if defined(LUA_BUILD_AS_DLL)
155
156#if defined(LUA_CORE) || defined(LUA_LIB)
157#define LUA_API __declspec(dllexport)
158#else
159#define LUA_API __declspec(dllimport)
160#endif
161
162#else
163
164#define LUA_API extern
165
166#endif
167
168/* more often than not the libs go together with the core */
169#define LUALIB_API LUA_API
170
171
172/*
173@@ LUAI_FUNC is a mark for all extern functions that are not to be
174@* exported to outside modules.
175@@ LUAI_DATA is a mark for all extern (const) variables that are not to
176@* be exported to outside modules.
177** CHANGE them if you need to mark them in some special way. Elf/gcc
178** (versions 3.2 and later) mark them as "hidden" to optimize access
179** when Lua is compiled as a shared library.
180*/
181#if defined(luaall_c)
182#define LUAI_FUNC static
183#define LUAI_DATA /* empty */
184
185#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
186 defined(__ELF__)
187#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
188#define LUAI_DATA LUAI_FUNC
189
190#else
191#define LUAI_FUNC extern
192#define LUAI_DATA extern
193#endif
194
195
196
197/*
198@@ LUA_QL describes how error messages quote program elements.
199** CHANGE it if you want a different appearance.
200*/
201#define LUA_QL(x) "'" x "'"
202#define LUA_QS LUA_QL("%s")
203
204
205/*
206@@ LUA_IDSIZE gives the maximum size for the description of the source
207@* of a function in debug information.
208** CHANGE it if you want a different size.
209*/
210#define LUA_IDSIZE 60
211
212
213/*
214** {==================================================================
215** Stand-alone configuration
216** ===================================================================
217*/
218
219#if defined(lua_c) || defined(luaall_c)
220
221/*
222@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
223@* is, whether we're running lua interactively).
224** CHANGE it if you have a better definition for non-POSIX/non-Windows
225** systems.
226*/
227#if defined(LUA_USE_ISATTY)
228#include <unistd.h>
229#define lua_stdin_is_tty() isatty(0)
230#elif defined(LUA_WIN)
231#include <io.h>
232#include <stdio.h>
233#define lua_stdin_is_tty() _isatty(_fileno(stdin))
234#else
235#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
236#endif
237
238
239/*
240@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
241@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
242** CHANGE them if you want different prompts. (You can also change the
243** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
244*/
245#define LUA_PROMPT "> "
246#define LUA_PROMPT2 ">> "
247
248
249/*
250@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
251** CHANGE it if your stand-alone interpreter has a different name and
252** your system is not able to detect that name automatically.
253*/
254#define LUA_PROGNAME "lua"
255
256
257/*
258@@ LUA_MAXINPUT is the maximum length for an input line in the
259@* stand-alone interpreter.
260** CHANGE it if you need longer lines.
261*/
262#define LUA_MAXINPUT 512
263
264
265/*
266@@ lua_readline defines how to show a prompt and then read a line from
267@* the standard input.
268@@ lua_saveline defines how to "save" a read line in a "history".
269@@ lua_freeline defines how to free a line read by lua_readline.
270** CHANGE them if you want to improve this functionality (e.g., by using
271** GNU readline and history facilities).
272*/
273#if defined(LUA_USE_READLINE)
274#include <stdio.h>
275#include <readline/readline.h>
276#include <readline/history.h>
277#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
278#define lua_saveline(L,idx) \
279 if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
280 add_history(lua_tostring(L, idx)); /* add it to history */
281#define lua_freeline(L,b) ((void)L, free(b))
282#else
283#define lua_readline(L,b,p) \
284 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
285 fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
286#define lua_saveline(L,idx) { (void)L; (void)idx; }
287#define lua_freeline(L,b) { (void)L; (void)b; }
288#endif
289
290#endif
291
292/* }================================================================== */
293
294
295/*
296@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
297@* as a percentage.
298** CHANGE it if you want the GC to run faster or slower (higher values
299** mean larger pauses which mean slower collection.) You can also change
300** this value dynamically.
301*/
302#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
303
304
305/*
306@@ LUAI_GCMUL defines the default speed of garbage collection relative to
307@* memory allocation as a percentage.
308** CHANGE it if you want to change the granularity of the garbage
309** collection. (Higher values mean coarser collections. 0 represents
310** infinity, where each step performs a full collection.) You can also
311** change this value dynamically.
312*/
313#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
314
315
316
317/*
318@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
319** CHANGE it (define it) if you want exact compatibility with the
320** behavior of setn/getn in Lua 5.0.
321*/
322#undef LUA_COMPAT_GETN
323
324/*
325@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
326** CHANGE it to undefined as soon as you do not need a global 'loadlib'
327** function (the function is still available as 'package.loadlib').
328*/
329#undef LUA_COMPAT_LOADLIB
330
331/*
332@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
333** CHANGE it to undefined as soon as your programs use only '...' to
334** access vararg parameters (instead of the old 'arg' table).
335*/
336#define LUA_COMPAT_VARARG
337
338/*
339@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
340** CHANGE it to undefined as soon as your programs use 'math.fmod' or
341** the new '%' operator instead of 'math.mod'.
342*/
343#define LUA_COMPAT_MOD
344
345/*
346@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
347@* facility.
348** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
349** off the advisory error when nesting [[...]].
350*/
351#define LUA_COMPAT_LSTR 1
352
353/*
354@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
355** CHANGE it to undefined as soon as you rename 'string.gfind' to
356** 'string.gmatch'.
357*/
358#define LUA_COMPAT_GFIND
359
360/*
361@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
362@* behavior.
363** CHANGE it to undefined as soon as you replace to 'luaL_registry'
364** your uses of 'luaL_openlib'
365*/
366#define LUA_COMPAT_OPENLIB
367
368
369
370/*
371@@ luai_apicheck is the assert macro used by the Lua-C API.
372** CHANGE luai_apicheck if you want Lua to perform some checks in the
373** parameters it gets from API calls. This may slow down the interpreter
374** a bit, but may be quite useful when debugging C code that interfaces
375** with Lua. A useful redefinition is to use assert.h.
376*/
377#if defined(LUA_USE_APICHECK)
378#include <assert.h>
379#define luai_apicheck(L,o) { (void)L; assert(o); }
380#else
381#define luai_apicheck(L,o) { (void)L; }
382#endif
383
384
385/*
386@@ LUAI_BITSINT defines the number of bits in an int.
387** CHANGE here if Lua cannot automatically detect the number of bits of
388** your machine. Probably you do not need to change this.
389*/
390/* avoid overflows in comparison */
391#if INT_MAX-20 < 32760
392#define LUAI_BITSINT 16
393#elif INT_MAX > 2147483640L
394/* int has at least 32 bits */
395#define LUAI_BITSINT 32
396#else
397#error "you must define LUA_BITSINT with number of bits in an integer"
398#endif
399
400
401/*
402@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
403@@ LUAI_INT32 is an signed integer with at least 32 bits.
404@@ LUAI_UMEM is an unsigned integer big enough to count the total
405@* memory used by Lua.
406@@ LUAI_MEM is a signed integer big enough to count the total memory
407@* used by Lua.
408** CHANGE here if for some weird reason the default definitions are not
409** good enough for your machine. (The definitions in the 'else'
410** part always works, but may waste space on machines with 64-bit
411** longs.) Probably you do not need to change this.
412*/
413#if LUAI_BITSINT >= 32
414#define LUAI_UINT32 unsigned int
415#define LUAI_INT32 int
416#define LUAI_MAXINT32 INT_MAX
417#define LUAI_UMEM size_t
418#define LUAI_MEM ptrdiff_t
419#else
420/* 16-bit ints */
421#define LUAI_UINT32 unsigned long
422#define LUAI_INT32 long
423#define LUAI_MAXINT32 LONG_MAX
424#define LUAI_UMEM unsigned long
425#define LUAI_MEM long
426#endif
427
428
429/*
430@@ LUAI_MAXCALLS limits the number of nested calls.
431** CHANGE it if you need really deep recursive calls. This limit is
432** arbitrary; its only purpose is to stop infinite recursion before
433** exhausting memory.
434*/
435#define LUAI_MAXCALLS 20000
436
437
438/*
439@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
440@* can use.
441** CHANGE it if you need lots of (Lua) stack space for your C
442** functions. This limit is arbitrary; its only purpose is to stop C
443** functions to consume unlimited stack space.
444*/
445#define LUAI_MAXCSTACK 2048
446
447
448
449/*
450** {==================================================================
451** CHANGE (to smaller values) the following definitions if your system
452** has a small C stack. (Or you may want to change them to larger
453** values if your system has a large C stack and these limits are
454** too rigid for you.) Some of these constants control the size of
455** stack-allocated arrays used by the compiler or the interpreter, while
456** others limit the maximum number of recursive calls that the compiler
457** or the interpreter can perform. Values too large may cause a C stack
458** overflow for some forms of deep constructs.
459** ===================================================================
460*/
461
462
463/*
464@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
465@* syntactical nested non-terminals in a program.
466*/
467#define LUAI_MAXCCALLS 200
468
469
470/*
471@@ LUAI_MAXVARS is the maximum number of local variables per function
472@* (must be smaller than 250).
473*/
474#define LUAI_MAXVARS 200
475
476
477/*
478@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
479@* (must be smaller than 250).
480*/
481#define LUAI_MAXUPVALUES 60
482
483
484/*
485@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
486*/
487#define LUAL_BUFFERSIZE BUFSIZ
488
489/* }================================================================== */
490
491
492
493
494/*
495** {==================================================================
496@@ LUA_NUMBER is the type of numbers in Lua.
497** CHANGE the following definitions only if you want to build Lua
498** with a number type different from double. You may also need to
499** change lua_number2int & lua_number2integer.
500** ===================================================================
501*/
502
503#define LUA_NUMBER_DOUBLE
504#define LUA_NUMBER double
505
506/*
507@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
508@* over a number.
509*/
510#define LUAI_UACNUMBER double
511
512
513/*
514@@ LUA_NUMBER_SCAN is the format for reading numbers.
515@@ LUA_NUMBER_FMT is the format for writing numbers.
516@@ lua_number2str converts a number to a string.
517@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
518@@ lua_str2number converts a string to a number.
519*/
520#define LUA_NUMBER_SCAN "%lf"
521#define LUA_NUMBER_FMT "%.14g"
522#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
523#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
524#define lua_str2number(s,p) strtod((s), (p))
525
526
527/*
528@@ The luai_num* macros define the primitive operations over numbers.
529*/
530#if defined(LUA_CORE)
531#include <math.h>
532#define luai_numadd(a,b) ((a)+(b))
533#define luai_numsub(a,b) ((a)-(b))
534#define luai_nummul(a,b) ((a)*(b))
535#define luai_numdiv(a,b) ((a)/(b))
536#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
537#define luai_numpow(a,b) (pow(a,b))
538#define luai_numunm(a) (-(a))
539#define luai_numeq(a,b) ((a)==(b))
540#define luai_numlt(a,b) ((a)<(b))
541#define luai_numle(a,b) ((a)<=(b))
542#define luai_numisnan(a) (!luai_numeq((a), (a)))
543#endif
544
545
546/*
547@@ lua_number2int is a macro to convert lua_Number to int.
548@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
549** CHANGE them if you know a faster way to convert a lua_Number to
550** int (with any rounding method and without throwing errors) in your
551** system. In Pentium machines, a naive typecast from double to int
552** in C is extremely slow, so any alternative is worth trying.
553*/
554
555/* On a Pentium, resort to a trick */
556#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
557 (defined(__i386) || defined (_M_IX86) || defined(__i386__))
558
559/* On a Microsoft compiler, use assembler */
560#if defined(_MSC_VER)
561
562#define lua_number2int(i,d) __asm fld d __asm fistp i
563#define lua_number2integer(i,n) lua_number2int(i, n)
564
565/* the next trick should work on any Pentium, but sometimes clashes
566 with a DirectX idiosyncrasy */
567#else
568
569union luai_Cast { double l_d; long l_l; };
570#define lua_number2int(i,d) \
571 { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
572#define lua_number2integer(i,n) lua_number2int(i, n)
573
574#endif
575
576
577/* this option always works, but may be slow */
578#else
579#define lua_number2int(i,d) ((i)=(int)(d))
580#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
581
582#endif
583
584/* }================================================================== */
585
586
587/*
588@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
589** CHANGE it if your system requires alignments larger than double. (For
590** instance, if your system supports long doubles and they must be
591** aligned in 16-byte boundaries, then you should add long double in the
592** union.) Probably you do not need to change this.
593*/
594#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
595
596
597/*
598@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
599** CHANGE them if you prefer to use longjmp/setjmp even with C++
600** or if want/don't to use _longjmp/_setjmp instead of regular
601** longjmp/setjmp. By default, Lua handles errors with exceptions when
602** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
603** and with longjmp/setjmp otherwise.
604*/
605#if defined(__cplusplus)
606/* C++ exceptions */
607#define LUAI_THROW(L,c) throw(c)
608#define LUAI_TRY(L,c,a) try { a } catch(...) \
609 { if ((c)->status == 0) (c)->status = -1; }
610#define luai_jmpbuf int /* dummy variable */
611
612#elif defined(LUA_USE_ULONGJMP)
613/* in Unix, try _longjmp/_setjmp (more efficient) */
614#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
615#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
616#define luai_jmpbuf jmp_buf
617
618#else
619/* default handling with long jumps */
620#define LUAI_THROW(L,c) longjmp((c)->b, 1)
621#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
622#define luai_jmpbuf jmp_buf
623
624#endif
625
626
627/*
628@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
629@* can do during pattern-matching.
630** CHANGE it if you need more captures. This limit is arbitrary.
631*/
632#define LUA_MAXCAPTURES 32
633
634
635/*
636@@ lua_tmpnam is the function that the OS library uses to create a
637@* temporary name.
638@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
639** CHANGE them if you have an alternative to tmpnam (which is considered
640** insecure) or if you want the original tmpnam anyway. By default, Lua
641** uses tmpnam except when POSIX is available, where it uses mkstemp.
642*/
643#if defined(loslib_c) || defined(luaall_c)
644
645#if defined(LUA_USE_MKSTEMP)
646#include <unistd.h>
647#define LUA_TMPNAMBUFSIZE 32
648#define lua_tmpnam(b,e) { \
649 strcpy(b, "/tmp/lua_XXXXXX"); \
650 e = mkstemp(b); \
651 if (e != -1) close(e); \
652 e = (e == -1); }
653
654#else
655#define LUA_TMPNAMBUFSIZE L_tmpnam
656#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
657#endif
658
659#endif
660
661
662/*
663@@ lua_popen spawns a new process connected to the current one through
664@* the file streams.
665** CHANGE it if you have a way to implement it in your system.
666*/
667#if defined(LUA_USE_POPEN)
668
669#define lua_popen(L,c,m) ((void)L, popen(c,m))
670#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
671
672#elif defined(LUA_WIN)
673
674#define lua_popen(L,c,m) ((void)L, _popen(c,m))
675#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
676
677#else
678
679#define lua_popen(L,c,m) ((void)((void)c, m), \
680 luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
681#define lua_pclose(L,file) ((void)((void)L, file), 0)
682
683#endif
684
685/*
686@@ LUA_DL_* define which dynamic-library system Lua should use.
687** CHANGE here if Lua has problems choosing the appropriate
688** dynamic-library system for your platform (either Windows' DLL, Mac's
689** dyld, or Unix's dlopen). If your system is some kind of Unix, there
690** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
691** it. To use dlopen you also need to adapt the src/Makefile (probably
692** adding -ldl to the linker options), so Lua does not select it
693** automatically. (When you change the makefile to add -ldl, you must
694** also add -DLUA_USE_DLOPEN.)
695** If you do not want any kind of dynamic library, undefine all these
696** options.
697** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
698*/
699#if defined(LUA_USE_DLOPEN)
700#define LUA_DL_DLOPEN
701#endif
702
703#if defined(LUA_WIN)
704#define LUA_DL_DLL
705#endif
706
707
708/*
709@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
710@* (the data goes just *before* the lua_State pointer).
711** CHANGE (define) this if you really need that. This value must be
712** a multiple of the maximum alignment required for your machine.
713*/
714#define LUAI_EXTRASPACE 0
715
716
717/*
718@@ luai_userstate* allow user-specific actions on threads.
719** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
720** extra when a thread is created/deleted/resumed/yielded.
721*/
722#define luai_userstateopen(L) ((void)L)
723#define luai_userstateclose(L) ((void)L)
724#define luai_userstatethread(L,L1) ((void)L)
725#define luai_userstatefree(L) ((void)L)
726#define luai_userstateresume(L,n) ((void)L)
727#define luai_userstateyield(L,n) ((void)L)
728
729
730/*
731@@ LUA_INTFRMLEN is the length modifier for integer conversions
732@* in 'string.format'.
733@@ LUA_INTFRM_T is the integer type correspoding to the previous length
734@* modifier.
735** CHANGE them if your system supports long long or does not support long.
736*/
737
738#if defined(LUA_USELONGLONG)
739
740#define LUA_INTFRMLEN "ll"
741#define LUA_INTFRM_T long long
742
743#else
744
745#define LUA_INTFRMLEN "l"
746#define LUA_INTFRM_T long
747
748#endif
749
750
751
752/* =================================================================== */
753
754/*
755** Local configuration. You can use this space to add your redefinitions
756** without modifying the main part of the file.
757*/
758
759
760
761#endif
762
diff --git a/lualib.h b/lualib.h
deleted file mode 100644
index 3afa4591..00000000
--- a/lualib.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2** $Id: lualib.h,v 1.35 2005/08/10 18:06:58 roberto Exp roberto $
3** Lua standard libraries
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lualib_h
9#define lualib_h
10
11#include "lua.h"
12
13
14/* Key to file-handle type */
15#define LUA_FILEHANDLE "FILE*"
16
17
18#define LUA_COLIBNAME "coroutine"
19LUALIB_API int (luaopen_base) (lua_State *L);
20
21#define LUA_TABLIBNAME "table"
22LUALIB_API int (luaopen_table) (lua_State *L);
23
24#define LUA_IOLIBNAME "io"
25LUALIB_API int (luaopen_io) (lua_State *L);
26
27#define LUA_OSLIBNAME "os"
28LUALIB_API int (luaopen_os) (lua_State *L);
29
30#define LUA_STRLIBNAME "string"
31LUALIB_API int (luaopen_string) (lua_State *L);
32
33#define LUA_MATHLIBNAME "math"
34LUALIB_API int (luaopen_math) (lua_State *L);
35
36#define LUA_DBLIBNAME "debug"
37LUALIB_API int (luaopen_debug) (lua_State *L);
38
39#define LUA_LOADLIBNAME "package"
40LUALIB_API int (luaopen_package) (lua_State *L);
41
42
43/* open all previous libraries */
44LUALIB_API void (luaL_openlibs) (lua_State *L);
45
46
47
48#ifndef lua_assert
49#define lua_assert(x) ((void)0)
50#endif
51
52
53#endif
diff --git a/lundump.c b/lundump.c
deleted file mode 100644
index 7fc635ee..00000000
--- a/lundump.c
+++ /dev/null
@@ -1,223 +0,0 @@
1/*
2** $Id: lundump.c,v 1.60 2006/02/16 15:53:49 lhf Exp $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#include <string.h>
8
9#define lundump_c
10#define LUA_CORE
11
12#include "lua.h"
13
14#include "ldebug.h"
15#include "ldo.h"
16#include "lfunc.h"
17#include "lmem.h"
18#include "lobject.h"
19#include "lstring.h"
20#include "lundump.h"
21#include "lzio.h"
22
23typedef struct {
24 lua_State* L;
25 ZIO* Z;
26 Mbuffer* b;
27 const char* name;
28} LoadState;
29
30#ifdef LUAC_TRUST_BINARIES
31#define IF(c,s)
32#else
33#define IF(c,s) if (c) error(S,s)
34
35static void error(LoadState* S, const char* why)
36{
37 luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
38 luaD_throw(S->L,LUA_ERRSYNTAX);
39}
40#endif
41
42#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
43#define LoadByte(S) (lu_byte)LoadChar(S)
44#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
45#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
46
47static void LoadBlock(LoadState* S, void* b, size_t size)
48{
49 size_t r=luaZ_read(S->Z,b,size);
50 IF (r!=0, "unexpected end");
51}
52
53static int LoadChar(LoadState* S)
54{
55 char x;
56 LoadVar(S,x);
57 return x;
58}
59
60static int LoadInt(LoadState* S)
61{
62 int x;
63 LoadVar(S,x);
64 IF (x<0, "bad integer");
65 return x;
66}
67
68static lua_Number LoadNumber(LoadState* S)
69{
70 lua_Number x;
71 LoadVar(S,x);
72 return x;
73}
74
75static TString* LoadString(LoadState* S)
76{
77 size_t size;
78 LoadVar(S,size);
79 if (size==0)
80 return NULL;
81 else
82 {
83 char* s=luaZ_openspace(S->L,S->b,size);
84 LoadBlock(S,s,size);
85 return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
86 }
87}
88
89static void LoadCode(LoadState* S, Proto* f)
90{
91 int n=LoadInt(S);
92 f->code=luaM_newvector(S->L,n,Instruction);
93 f->sizecode=n;
94 LoadVector(S,f->code,n,sizeof(Instruction));
95}
96
97static Proto* LoadFunction(LoadState* S, TString* p);
98
99static void LoadConstants(LoadState* S, Proto* f)
100{
101 int i,n;
102 n=LoadInt(S);
103 f->k=luaM_newvector(S->L,n,TValue);
104 f->sizek=n;
105 for (i=0; i<n; i++) setnilvalue(&f->k[i]);
106 for (i=0; i<n; i++)
107 {
108 TValue* o=&f->k[i];
109 int t=LoadChar(S);
110 switch (t)
111 {
112 case LUA_TNIL:
113 setnilvalue(o);
114 break;
115 case LUA_TBOOLEAN:
116 setbvalue(o,LoadChar(S));
117 break;
118 case LUA_TNUMBER:
119 setnvalue(o,LoadNumber(S));
120 break;
121 case LUA_TSTRING:
122 setsvalue2n(S->L,o,LoadString(S));
123 break;
124 default:
125 IF (1, "bad constant");
126 break;
127 }
128 }
129 n=LoadInt(S);
130 f->p=luaM_newvector(S->L,n,Proto*);
131 f->sizep=n;
132 for (i=0; i<n; i++) f->p[i]=NULL;
133 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
134}
135
136static void LoadDebug(LoadState* S, Proto* f)
137{
138 int i,n;
139 n=LoadInt(S);
140 f->lineinfo=luaM_newvector(S->L,n,int);
141 f->sizelineinfo=n;
142 LoadVector(S,f->lineinfo,n,sizeof(int));
143 n=LoadInt(S);
144 f->locvars=luaM_newvector(S->L,n,LocVar);
145 f->sizelocvars=n;
146 for (i=0; i<n; i++) f->locvars[i].varname=NULL;
147 for (i=0; i<n; i++)
148 {
149 f->locvars[i].varname=LoadString(S);
150 f->locvars[i].startpc=LoadInt(S);
151 f->locvars[i].endpc=LoadInt(S);
152 }
153 n=LoadInt(S);
154 f->upvalues=luaM_newvector(S->L,n,TString*);
155 f->sizeupvalues=n;
156 for (i=0; i<n; i++) f->upvalues[i]=NULL;
157 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
158}
159
160static Proto* LoadFunction(LoadState* S, TString* p)
161{
162 Proto* f=luaF_newproto(S->L);
163 setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
164 f->source=LoadString(S); if (f->source==NULL) f->source=p;
165 f->linedefined=LoadInt(S);
166 f->lastlinedefined=LoadInt(S);
167 f->nups=LoadByte(S);
168 f->numparams=LoadByte(S);
169 f->is_vararg=LoadByte(S);
170 f->maxstacksize=LoadByte(S);
171 LoadCode(S,f);
172 LoadConstants(S,f);
173 LoadDebug(S,f);
174 IF (!luaG_checkcode(f), "bad code");
175 S->L->top--;
176 return f;
177}
178
179static void LoadHeader(LoadState* S)
180{
181 char h[LUAC_HEADERSIZE];
182 char s[LUAC_HEADERSIZE];
183 luaU_header(h);
184 LoadBlock(S,s,LUAC_HEADERSIZE);
185 IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
186}
187
188/*
189** load precompiled chunk
190*/
191Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
192{
193 LoadState S;
194 if (*name=='@' || *name=='=')
195 S.name=name+1;
196 else if (*name==LUA_SIGNATURE[0])
197 S.name="binary string";
198 else
199 S.name=name;
200 S.L=L;
201 S.Z=Z;
202 S.b=buff;
203 LoadHeader(&S);
204 return LoadFunction(&S,luaS_newliteral(L,"=?"));
205}
206
207/*
208* make header
209*/
210void luaU_header (char* h)
211{
212 int x=1;
213 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
214 h+=sizeof(LUA_SIGNATURE)-1;
215 *h++=(char)LUAC_VERSION;
216 *h++=(char)LUAC_FORMAT;
217 *h++=(char)*(char*)&x; /* endianness */
218 *h++=(char)sizeof(int);
219 *h++=(char)sizeof(size_t);
220 *h++=(char)sizeof(Instruction);
221 *h++=(char)sizeof(lua_Number);
222 *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
223}
diff --git a/lundump.h b/lundump.h
deleted file mode 100644
index 2f064694..00000000
--- a/lundump.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2** $Id: lundump.h,v 1.39 2005/11/01 17:04:55 lhf Exp lhf $
3** load precompiled Lua chunks
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lundump_h
8#define lundump_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13/* load one chunk; from lundump.c */
14LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
15
16/* make header; from lundump.c */
17LUAI_FUNC void luaU_header (char* h);
18
19/* dump one chunk; from ldump.c */
20LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
21
22#ifdef luac_c
23/* print one chunk; from print.c */
24LUAI_FUNC void luaU_print (const Proto* f, int full);
25#endif
26
27/* for header of binary files -- this is Lua 5.1 */
28#define LUAC_VERSION 0x51
29
30/* for header of binary files -- this is the official format */
31#define LUAC_FORMAT 0
32
33/* size of header of binary files */
34#define LUAC_HEADERSIZE 12
35
36#endif
diff --git a/lvm.c b/lvm.c
deleted file mode 100644
index 6c92567f..00000000
--- a/lvm.c
+++ /dev/null
@@ -1,763 +0,0 @@
1/*
2** $Id: lvm.c,v 2.62 2006/01/23 19:51:43 roberto Exp roberto $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define lvm_c
13#define LUA_CORE
14
15#include "lua.h"
16
17#include "ldebug.h"
18#include "ldo.h"
19#include "lfunc.h"
20#include "lgc.h"
21#include "lobject.h"
22#include "lopcodes.h"
23#include "lstate.h"
24#include "lstring.h"
25#include "ltable.h"
26#include "ltm.h"
27#include "lvm.h"
28
29
30
31/* limit for table tag-method chains (to avoid loops) */
32#define MAXTAGLOOP 100
33
34
35const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
36 lua_Number num;
37 if (ttisnumber(obj)) return obj;
38 if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
39 setnvalue(n, num);
40 return n;
41 }
42 else
43 return NULL;
44}
45
46
47int luaV_tostring (lua_State *L, StkId obj) {
48 if (!ttisnumber(obj))
49 return 0;
50 else {
51 char s[LUAI_MAXNUMBER2STR];
52 lua_Number n = nvalue(obj);
53 lua_number2str(s, n);
54 setsvalue2s(L, obj, luaS_new(L, s));
55 return 1;
56 }
57}
58
59
60static void traceexec (lua_State *L, const Instruction *pc) {
61 lu_byte mask = L->hookmask;
62 const Instruction *oldpc = L->savedpc;
63 L->savedpc = pc;
64 if (mask > LUA_MASKLINE) { /* instruction-hook set? */
65 if (L->hookcount == 0) {
66 resethookcount(L);
67 luaD_callhook(L, LUA_HOOKCOUNT, -1);
68 }
69 }
70 if (mask & LUA_MASKLINE) {
71 Proto *p = ci_func(L->ci)->l.p;
72 int npc = pcRel(pc, p);
73 int newline = getline(p, npc);
74 /* call linehook when enter a new function, when jump back (loop),
75 or when enter a new line */
76 if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
77 luaD_callhook(L, LUA_HOOKLINE, newline);
78 }
79}
80
81
82static void callTMres (lua_State *L, StkId res, const TValue *f,
83 const TValue *p1, const TValue *p2) {
84 ptrdiff_t result = savestack(L, res);
85 setobj2s(L, L->top, f); /* push function */
86 setobj2s(L, L->top+1, p1); /* 1st argument */
87 setobj2s(L, L->top+2, p2); /* 2nd argument */
88 luaD_checkstack(L, 3);
89 L->top += 3;
90 luaD_call(L, L->top - 3, 1);
91 res = restorestack(L, result);
92 L->top--;
93 setobjs2s(L, res, L->top);
94}
95
96
97
98static void callTM (lua_State *L, const TValue *f, const TValue *p1,
99 const TValue *p2, const TValue *p3) {
100 setobj2s(L, L->top, f); /* push function */
101 setobj2s(L, L->top+1, p1); /* 1st argument */
102 setobj2s(L, L->top+2, p2); /* 2nd argument */
103 setobj2s(L, L->top+3, p3); /* 3th argument */
104 luaD_checkstack(L, 4);
105 L->top += 4;
106 luaD_call(L, L->top - 4, 0);
107}
108
109
110void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
111 int loop;
112 for (loop = 0; loop < MAXTAGLOOP; loop++) {
113 const TValue *tm;
114 if (ttistable(t)) { /* `t' is a table? */
115 Table *h = hvalue(t);
116 const TValue *res = luaH_get(h, key); /* do a primitive get */
117 if (!ttisnil(res) || /* result is no nil? */
118 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
119 setobj2s(L, val, res);
120 return;
121 }
122 /* else will try the tag method */
123 }
124 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
125 luaG_typeerror(L, t, "index");
126 if (ttisfunction(tm)) {
127 callTMres(L, val, tm, t, key);
128 return;
129 }
130 t = tm; /* else repeat with `tm' */
131 }
132 luaG_runerror(L, "loop in gettable");
133}
134
135
136void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
137 int loop;
138 for (loop = 0; loop < MAXTAGLOOP; loop++) {
139 const TValue *tm;
140 if (ttistable(t)) { /* `t' is a table? */
141 Table *h = hvalue(t);
142 TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
143 if (!ttisnil(oldval) || /* result is no nil? */
144 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
145 setobj2t(L, oldval, val);
146 luaC_barriert(L, h, val);
147 return;
148 }
149 /* else will try the tag method */
150 }
151 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
152 luaG_typeerror(L, t, "index");
153 if (ttisfunction(tm)) {
154 callTM(L, tm, t, key, val);
155 return;
156 }
157 t = tm; /* else repeat with `tm' */
158 }
159 luaG_runerror(L, "loop in settable");
160}
161
162
163static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
164 StkId res, TMS event) {
165 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
166 if (ttisnil(tm))
167 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
168 if (!ttisfunction(tm)) return 0;
169 callTMres(L, res, tm, p1, p2);
170 return 1;
171}
172
173
174static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
175 TMS event) {
176 const TValue *tm1 = fasttm(L, mt1, event);
177 const TValue *tm2;
178 if (tm1 == NULL) return NULL; /* no metamethod */
179 if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
180 tm2 = fasttm(L, mt2, event);
181 if (tm2 == NULL) return NULL; /* no metamethod */
182 if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
183 return tm1;
184 return NULL;
185}
186
187
188static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
189 TMS event) {
190 const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
191 const TValue *tm2;
192 if (ttisnil(tm1)) return -1; /* no metamethod? */
193 tm2 = luaT_gettmbyobj(L, p2, event);
194 if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
195 return -1;
196 callTMres(L, L->top, tm1, p1, p2);
197 return !l_isfalse(L->top);
198}
199
200
201static int l_strcmp (const TString *ls, const TString *rs) {
202 const char *l = getstr(ls);
203 size_t ll = ls->tsv.len;
204 const char *r = getstr(rs);
205 size_t lr = rs->tsv.len;
206 for (;;) {
207 int temp = strcoll(l, r);
208 if (temp != 0) return temp;
209 else { /* strings are equal up to a `\0' */
210 size_t len = strlen(l); /* index of first `\0' in both strings */
211 if (len == lr) /* r is finished? */
212 return (len == ll) ? 0 : 1;
213 else if (len == ll) /* l is finished? */
214 return -1; /* l is smaller than r (because r is not finished) */
215 /* both strings longer than `len'; go on comparing (after the `\0') */
216 len++;
217 l += len; ll -= len; r += len; lr -= len;
218 }
219 }
220}
221
222
223int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
224 int res;
225 if (ttype(l) != ttype(r))
226 return luaG_ordererror(L, l, r);
227 else if (ttisnumber(l))
228 return luai_numlt(nvalue(l), nvalue(r));
229 else if (ttisstring(l))
230 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
231 else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
232 return res;
233 return luaG_ordererror(L, l, r);
234}
235
236
237static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
238 int res;
239 if (ttype(l) != ttype(r))
240 return luaG_ordererror(L, l, r);
241 else if (ttisnumber(l))
242 return luai_numle(nvalue(l), nvalue(r));
243 else if (ttisstring(l))
244 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
245 else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
246 return res;
247 else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
248 return !res;
249 return luaG_ordererror(L, l, r);
250}
251
252
253int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
254 const TValue *tm;
255 lua_assert(ttype(t1) == ttype(t2));
256 switch (ttype(t1)) {
257 case LUA_TNIL: return 1;
258 case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
259 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
260 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
261 case LUA_TUSERDATA: {
262 if (uvalue(t1) == uvalue(t2)) return 1;
263 tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
264 TM_EQ);
265 break; /* will try TM */
266 }
267 case LUA_TTABLE: {
268 if (hvalue(t1) == hvalue(t2)) return 1;
269 tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
270 break; /* will try TM */
271 }
272 default: return gcvalue(t1) == gcvalue(t2);
273 }
274 if (tm == NULL) return 0; /* no TM? */
275 callTMres(L, L->top, tm, t1, t2); /* call TM */
276 return !l_isfalse(L->top);
277}
278
279
280void luaV_concat (lua_State *L, int total, int last) {
281 do {
282 StkId top = L->base + last + 1;
283 int n = 2; /* number of elements handled in this pass (at least 2) */
284 if (!tostring(L, top-2) || !tostring(L, top-1)) {
285 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
286 luaG_concaterror(L, top-2, top-1);
287 } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */
288 /* at least two string values; get as many as possible */
289 size_t tl = tsvalue(top-1)->len;
290 char *buffer;
291 int i;
292 /* collect total length */
293 for (n = 1; n < total && tostring(L, top-n-1); n++) {
294 size_t l = tsvalue(top-n-1)->len;
295 if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
296 tl += l;
297 }
298 buffer = luaZ_openspace(L, &G(L)->buff, tl);
299 tl = 0;
300 for (i=n; i>0; i--) { /* concat all strings */
301 size_t l = tsvalue(top-i)->len;
302 memcpy(buffer+tl, svalue(top-i), l);
303 tl += l;
304 }
305 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
306 }
307 total -= n-1; /* got `n' strings to create 1 new */
308 last -= n-1;
309 } while (total > 1); /* repeat until only 1 result left */
310}
311
312
313static void Arith (lua_State *L, StkId ra, const TValue *rb,
314 const TValue *rc, TMS op) {
315 TValue tempb, tempc;
316 const TValue *b, *c;
317 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
318 (c = luaV_tonumber(rc, &tempc)) != NULL) {
319 lua_Number nb = nvalue(b), nc = nvalue(c);
320 switch (op) {
321 case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
322 case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
323 case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
324 case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
325 case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
326 case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
327 case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
328 default: lua_assert(0); break;
329 }
330 }
331 else if (!call_binTM(L, rb, rc, ra, op))
332 luaG_aritherror(L, rb, rc);
333}
334
335
336
337/*
338** some macros for common tasks in `luaV_execute'
339*/
340
341#define runtime_check(L, c) { if (!(c)) break; }
342
343#define RA(i) (base+GETARG_A(i))
344/* to be used after possible stack reallocation */
345#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
346#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
347#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
348 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
349#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
350 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
351#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
352
353
354#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
355
356
357#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
358
359
360#define arith_op(op,tm) { \
361 TValue *rb = RKB(i); \
362 TValue *rc = RKC(i); \
363 if (ttisnumber(rb) && ttisnumber(rc)) { \
364 lua_Number nb = nvalue(rb), nc = nvalue(rc); \
365 setnvalue(ra, op(nb, nc)); \
366 } \
367 else \
368 Protect(Arith(L, ra, rb, rc, tm)); \
369 }
370
371
372
373void luaV_execute (lua_State *L, int nexeccalls) {
374 LClosure *cl;
375 StkId base;
376 TValue *k;
377 const Instruction *pc;
378 reentry: /* entry point */
379 lua_assert(isLua(L->ci));
380 pc = L->savedpc;
381 cl = &clvalue(L->ci->func)->l;
382 base = L->base;
383 k = cl->p->k;
384 /* main loop of interpreter */
385 for (;;) {
386 const Instruction i = *pc++;
387 StkId ra;
388 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
389 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
390 traceexec(L, pc);
391 if (L->status == LUA_YIELD) { /* did hook yield? */
392 L->savedpc = pc - 1;
393 return;
394 }
395 base = L->base;
396 }
397 /* warning!! several calls may realloc the stack and invalidate `ra' */
398 ra = RA(i);
399 lua_assert(base == L->base && L->base == L->ci->base);
400 lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
401 lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
402 switch (GET_OPCODE(i)) {
403 case OP_MOVE: {
404 setobjs2s(L, ra, RB(i));
405 continue;
406 }
407 case OP_LOADK: {
408 setobj2s(L, ra, KBx(i));
409 continue;
410 }
411 case OP_LOADBOOL: {
412 setbvalue(ra, GETARG_B(i));
413 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
414 continue;
415 }
416 case OP_LOADNIL: {
417 TValue *rb = RB(i);
418 do {
419 setnilvalue(rb--);
420 } while (rb >= ra);
421 continue;
422 }
423 case OP_GETUPVAL: {
424 int b = GETARG_B(i);
425 setobj2s(L, ra, cl->upvals[b]->v);
426 continue;
427 }
428 case OP_GETGLOBAL: {
429 TValue g;
430 TValue *rb = KBx(i);
431 sethvalue(L, &g, cl->env);
432 lua_assert(ttisstring(rb));
433 Protect(luaV_gettable(L, &g, rb, ra));
434 continue;
435 }
436 case OP_GETTABLE: {
437 Protect(luaV_gettable(L, RB(i), RKC(i), ra));
438 continue;
439 }
440 case OP_SETGLOBAL: {
441 TValue g;
442 sethvalue(L, &g, cl->env);
443 lua_assert(ttisstring(KBx(i)));
444 Protect(luaV_settable(L, &g, KBx(i), ra));
445 continue;
446 }
447 case OP_SETUPVAL: {
448 UpVal *uv = cl->upvals[GETARG_B(i)];
449 setobj(L, uv->v, ra);
450 luaC_barrier(L, uv, ra);
451 continue;
452 }
453 case OP_SETTABLE: {
454 Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
455 continue;
456 }
457 case OP_NEWTABLE: {
458 int b = GETARG_B(i);
459 int c = GETARG_C(i);
460 sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
461 Protect(luaC_checkGC(L));
462 continue;
463 }
464 case OP_SELF: {
465 StkId rb = RB(i);
466 setobjs2s(L, ra+1, rb);
467 Protect(luaV_gettable(L, rb, RKC(i), ra));
468 continue;
469 }
470 case OP_ADD: {
471 arith_op(luai_numadd, TM_ADD);
472 continue;
473 }
474 case OP_SUB: {
475 arith_op(luai_numsub, TM_SUB);
476 continue;
477 }
478 case OP_MUL: {
479 arith_op(luai_nummul, TM_MUL);
480 continue;
481 }
482 case OP_DIV: {
483 arith_op(luai_numdiv, TM_DIV);
484 continue;
485 }
486 case OP_MOD: {
487 arith_op(luai_nummod, TM_MOD);
488 continue;
489 }
490 case OP_POW: {
491 arith_op(luai_numpow, TM_POW);
492 continue;
493 }
494 case OP_UNM: {
495 TValue *rb = RB(i);
496 if (ttisnumber(rb)) {
497 lua_Number nb = nvalue(rb);
498 setnvalue(ra, luai_numunm(nb));
499 }
500 else {
501 Protect(Arith(L, ra, rb, rb, TM_UNM));
502 }
503 continue;
504 }
505 case OP_NOT: {
506 int res = l_isfalse(RB(i)); /* next assignment may change this value */
507 setbvalue(ra, res);
508 continue;
509 }
510 case OP_LEN: {
511 const TValue *rb = RB(i);
512 switch (ttype(rb)) {
513 case LUA_TTABLE: {
514 setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
515 break;
516 }
517 case LUA_TSTRING: {
518 setnvalue(ra, cast_num(tsvalue(rb)->len));
519 break;
520 }
521 default: { /* try metamethod */
522 Protect(
523 if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
524 luaG_typeerror(L, rb, "get length of");
525 )
526 }
527 }
528 continue;
529 }
530 case OP_CONCAT: {
531 int b = GETARG_B(i);
532 int c = GETARG_C(i);
533 Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
534 setobjs2s(L, RA(i), base+b);
535 continue;
536 }
537 case OP_JMP: {
538 dojump(L, pc, GETARG_sBx(i));
539 continue;
540 }
541 case OP_EQ: {
542 TValue *rb = RKB(i);
543 TValue *rc = RKC(i);
544 Protect(
545 if (equalobj(L, rb, rc) == GETARG_A(i))
546 dojump(L, pc, GETARG_sBx(*pc));
547 )
548 pc++;
549 continue;
550 }
551 case OP_LT: {
552 Protect(
553 if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
554 dojump(L, pc, GETARG_sBx(*pc));
555 )
556 pc++;
557 continue;
558 }
559 case OP_LE: {
560 Protect(
561 if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
562 dojump(L, pc, GETARG_sBx(*pc));
563 )
564 pc++;
565 continue;
566 }
567 case OP_TEST: {
568 if (l_isfalse(ra) != GETARG_C(i))
569 dojump(L, pc, GETARG_sBx(*pc));
570 pc++;
571 continue;
572 }
573 case OP_TESTSET: {
574 TValue *rb = RB(i);
575 if (l_isfalse(rb) != GETARG_C(i)) {
576 setobjs2s(L, ra, rb);
577 dojump(L, pc, GETARG_sBx(*pc));
578 }
579 pc++;
580 continue;
581 }
582 case OP_CALL: {
583 int b = GETARG_B(i);
584 int nresults = GETARG_C(i) - 1;
585 if (b != 0) L->top = ra+b; /* else previous instruction set top */
586 L->savedpc = pc;
587 switch (luaD_precall(L, ra, nresults)) {
588 case PCRLUA: {
589 nexeccalls++;
590 goto reentry; /* restart luaV_execute over new Lua function */
591 }
592 case PCRC: {
593 /* it was a C function (`precall' called it); adjust results */
594 if (nresults >= 0) L->top = L->ci->top;
595 base = L->base;
596 continue;
597 }
598 default: {
599 return; /* yield */
600 }
601 }
602 }
603 case OP_TAILCALL: {
604 int b = GETARG_B(i);
605 if (b != 0) L->top = ra+b; /* else previous instruction set top */
606 L->savedpc = pc;
607 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
608 switch (luaD_precall(L, ra, LUA_MULTRET)) {
609 case PCRLUA: {
610 /* tail call: put new frame in place of previous one */
611 CallInfo *ci = L->ci - 1; /* previous frame */
612 int aux;
613 StkId func = ci->func;
614 StkId pfunc = (ci+1)->func; /* previous function index */
615 if (L->openupval) luaF_close(L, ci->base);
616 L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
617 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
618 setobjs2s(L, func+aux, pfunc+aux);
619 ci->top = L->top = func+aux; /* correct top */
620 lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
621 ci->savedpc = L->savedpc;
622 ci->tailcalls++; /* one more call lost */
623 L->ci--; /* remove new frame */
624 goto reentry;
625 }
626 case PCRC: { /* it was a C function (`precall' called it) */
627 base = L->base;
628 continue;
629 }
630 default: {
631 return; /* yield */
632 }
633 }
634 }
635 case OP_RETURN: {
636 int b = GETARG_B(i);
637 if (b != 0) L->top = ra+b-1;
638 if (L->openupval) luaF_close(L, base);
639 L->savedpc = pc;
640 b = luaD_poscall(L, ra);
641 if (--nexeccalls == 0) /* was previous function running `here'? */
642 return; /* no: return */
643 else { /* yes: continue its execution */
644 if (b) L->top = L->ci->top;
645 lua_assert(isLua(L->ci));
646 lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
647 goto reentry;
648 }
649 }
650 case OP_FORLOOP: {
651 lua_Number step = nvalue(ra+2);
652 lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
653 lua_Number limit = nvalue(ra+1);
654 if (luai_numlt(0, step) ? luai_numle(idx, limit)
655 : luai_numle(limit, idx)) {
656 dojump(L, pc, GETARG_sBx(i)); /* jump back */
657 setnvalue(ra, idx); /* update internal index... */
658 setnvalue(ra+3, idx); /* ...and external index */
659 }
660 continue;
661 }
662 case OP_FORPREP: {
663 const TValue *init = ra;
664 const TValue *plimit = ra+1;
665 const TValue *pstep = ra+2;
666 L->savedpc = pc; /* next steps may throw errors */
667 if (!tonumber(init, ra))
668 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
669 else if (!tonumber(plimit, ra+1))
670 luaG_runerror(L, LUA_QL("for") " limit must be a number");
671 else if (!tonumber(pstep, ra+2))
672 luaG_runerror(L, LUA_QL("for") " step must be a number");
673 setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
674 dojump(L, pc, GETARG_sBx(i));
675 continue;
676 }
677 case OP_TFORLOOP: {
678 StkId cb = ra + 3; /* call base */
679 setobjs2s(L, cb+2, ra+2);
680 setobjs2s(L, cb+1, ra+1);
681 setobjs2s(L, cb, ra);
682 L->top = cb+3; /* func. + 2 args (state and index) */
683 Protect(luaD_call(L, cb, GETARG_C(i)));
684 L->top = L->ci->top;
685 cb = RA(i) + 3; /* previous call may change the stack */
686 if (!ttisnil(cb)) { /* continue loop? */
687 setobjs2s(L, cb-1, cb); /* save control variable */
688 dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
689 }
690 pc++;
691 continue;
692 }
693 case OP_SETLIST: {
694 int n = GETARG_B(i);
695 int c = GETARG_C(i);
696 int last;
697 Table *h;
698 if (n == 0) {
699 n = cast_int(L->top - ra) - 1;
700 L->top = L->ci->top;
701 }
702 if (c == 0) c = cast_int(*pc++);
703 runtime_check(L, ttistable(ra));
704 h = hvalue(ra);
705 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
706 if (last > h->sizearray) /* needs more space? */
707 luaH_resizearray(L, h, last); /* pre-alloc it at once */
708 for (; n > 0; n--) {
709 TValue *val = ra+n;
710 setobj2t(L, luaH_setnum(L, h, last--), val);
711 luaC_barriert(L, h, val);
712 }
713 continue;
714 }
715 case OP_CLOSE: {
716 luaF_close(L, ra);
717 continue;
718 }
719 case OP_CLOSURE: {
720 Proto *p;
721 Closure *ncl;
722 int nup, j;
723 p = cl->p->p[GETARG_Bx(i)];
724 nup = p->nups;
725 ncl = luaF_newLclosure(L, nup, cl->env);
726 ncl->l.p = p;
727 for (j=0; j<nup; j++, pc++) {
728 if (GET_OPCODE(*pc) == OP_GETUPVAL)
729 ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
730 else {
731 lua_assert(GET_OPCODE(*pc) == OP_MOVE);
732 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
733 }
734 }
735 setclvalue(L, ra, ncl);
736 Protect(luaC_checkGC(L));
737 continue;
738 }
739 case OP_VARARG: {
740 int b = GETARG_B(i) - 1;
741 int j;
742 CallInfo *ci = L->ci;
743 int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
744 if (b == LUA_MULTRET) {
745 Protect(luaD_checkstack(L, n));
746 ra = RA(i); /* previous call may change the stack */
747 b = n;
748 L->top = ra + n;
749 }
750 for (j = 0; j < b; j++) {
751 if (j < n) {
752 setobjs2s(L, ra + j, ci->base - n + j);
753 }
754 else {
755 setnilvalue(ra + j);
756 }
757 }
758 continue;
759 }
760 }
761 }
762}
763
diff --git a/lvm.h b/lvm.h
deleted file mode 100644
index adca8cdd..00000000
--- a/lvm.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2** $Id: lvm.h,v 2.4 2005/04/25 19:24:10 roberto Exp roberto $
3** Lua virtual machine
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lvm_h
8#define lvm_h
9
10
11#include "ldo.h"
12#include "lobject.h"
13#include "ltm.h"
14
15
16#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
17
18#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
19 (((o) = luaV_tonumber(o,n)) != NULL))
20
21#define equalobj(L,o1,o2) \
22 (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
23
24
25LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
26LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
27LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
28LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
29LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
30 StkId val);
31LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
32 StkId val);
33LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
34LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
35
36#endif
diff --git a/lzio.c b/lzio.c
deleted file mode 100644
index a09dbdad..00000000
--- a/lzio.c
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2** $Id: lzio.c,v 1.30 2005/05/17 19:49:15 roberto Exp roberto $
3** a generic input stream interface
4** See Copyright Notice in lua.h
5*/
6
7
8#include <string.h>
9
10#define lzio_c
11#define LUA_CORE
12
13#include "lua.h"
14
15#include "llimits.h"
16#include "lmem.h"
17#include "lstate.h"
18#include "lzio.h"
19
20
21int luaZ_fill (ZIO *z) {
22 size_t size;
23 lua_State *L = z->L;
24 const char *buff;
25 lua_unlock(L);
26 buff = z->reader(L, z->data, &size);
27 lua_lock(L);
28 if (buff == NULL || size == 0) return EOZ;
29 z->n = size - 1;
30 z->p = buff;
31 return char2int(*(z->p++));
32}
33
34
35int luaZ_lookahead (ZIO *z) {
36 if (z->n == 0) {
37 if (luaZ_fill(z) == EOZ)
38 return EOZ;
39 else {
40 z->n++; /* luaZ_fill removed first byte; put back it */
41 z->p--;
42 }
43 }
44 return char2int(*z->p);
45}
46
47
48void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
49 z->L = L;
50 z->reader = reader;
51 z->data = data;
52 z->n = 0;
53 z->p = NULL;
54}
55
56
57/* --------------------------------------------------------------- read --- */
58size_t luaZ_read (ZIO *z, void *b, size_t n) {
59 while (n) {
60 size_t m;
61 if (luaZ_lookahead(z) == EOZ)
62 return n; /* return number of missing bytes */
63 m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
64 memcpy(b, z->p, m);
65 z->n -= m;
66 z->p += m;
67 b = (char *)b + m;
68 n -= m;
69 }
70 return 0;
71}
72
73/* ------------------------------------------------------------------------ */
74char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
75 if (n > buff->buffsize) {
76 if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
77 luaZ_resizebuffer(L, buff, n);
78 }
79 return buff->buffer;
80}
81
82
diff --git a/lzio.h b/lzio.h
deleted file mode 100644
index 85843679..00000000
--- a/lzio.h
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2** $Id: lzio.h,v 1.20 2005/04/25 19:24:10 roberto Exp roberto $
3** Buffered streams
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lzio_h
9#define lzio_h
10
11#include "lua.h"
12
13#include "lmem.h"
14
15
16#define EOZ (-1) /* end of stream */
17
18typedef struct Zio ZIO;
19
20#define char2int(c) cast(int, cast(unsigned char, (c)))
21
22#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
23
24typedef struct Mbuffer {
25 char *buffer;
26 size_t n;
27 size_t buffsize;
28} Mbuffer;
29
30#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
31
32#define luaZ_buffer(buff) ((buff)->buffer)
33#define luaZ_sizebuffer(buff) ((buff)->buffsize)
34#define luaZ_bufflen(buff) ((buff)->n)
35
36#define luaZ_resetbuffer(buff) ((buff)->n = 0)
37
38
39#define luaZ_resizebuffer(L, buff, size) \
40 (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
41 (buff)->buffsize = size)
42
43#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
44
45
46LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
47LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
48 void *data);
49LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
50LUAI_FUNC int luaZ_lookahead (ZIO *z);
51
52
53
54/* --------- Private Part ------------------ */
55
56struct Zio {
57 size_t n; /* bytes still unread */
58 const char *p; /* current position in buffer */
59 lua_Reader reader;
60 void* data; /* additional data */
61 lua_State *L; /* Lua state (for reader) */
62};
63
64
65LUAI_FUNC int luaZ_fill (ZIO *z);
66
67#endif