History

Lua 5.1-work1

Lua Team committed 22 years ago

Commit 4014ed71 parent ad2eda775 files · +2140 −2612Browse files

Unified · Split

75 files
  1. HISTORY +1 −1
  2. INSTALL +11 −11
  3. MANIFEST +114 −0
  4. RCS +0 −1
  5. README +1 −1
  6. build +6 −3
  7. config +5 −48
  8. configure +0 −9
  9. etc/Makefile +8 −11
  10. etc/RCS +0 −1
  11. etc/README +4 −0
  12. etc/all.c +41 −0
  13. etc/min.c +28 −18
  14. etc/noparser.c +3 −0
  15. include/Makefile +1 −1
  16. include/RCS +0 −1
  17. include/lauxlib.h +17 −16
  18. include/lua.h +13 −56
  19. include/luaconf.h +312 −0
  20. include/lualib.h +8 −17
  21. src/RCS +0 −1
  22. src/README +2 −2
  23. src/lapi.c +55 −33
  24. src/lcode.c +28 −13
  25. src/lcode.h +5 −2
  26. src/ldebug.c +24 −15
  27. src/ldebug.h +2 −2
  28. src/ldo.c +68 −56
  29. src/ldo.h +8 −2
  30. src/ldump.c +18 −12
  31. src/lfunc.c +2 −1
  32. src/lgc.c +173 −137
  33. src/lgc.h +19 −13
  34. src/lib/Makefile +2 −2
  35. src/lib/RCS +0 −1
  36. src/lib/lauxlib.c +96 −63
  37. src/lib/lbaselib.c +120 −176
  38. src/lib/ldblib.c +16 −17
  39. src/lib/linit.c +38 −0
  40. src/lib/liolib.c +69 −309
  41. src/lib/lmathlib.c +9 −21
  42. src/lib/loadlib.c +4 −1
  43. src/lib/loslib.c +241 −0
  44. src/lib/lstrlib.c +16 −14
  45. src/lib/ltablib.c +25 −22
  46. src/llex.c +2 −1
  47. src/llimits.h +2 −95
  48. src/lmem.c +3 −3
  49. src/lobject.c +18 −12
  50. src/lobject.h +5 −1
  51. src/lopcodes.c +5 −5
  52. src/lopcodes.h +41 −17
  53. src/lparser.c +33 −35
  54. src/lparser.h +3 −2
  55. src/lstate.c +22 −10
  56. src/lstate.h +15 −41
  57. src/lstring.c +4 −8
  58. src/lstring.h +1 −2
  59. src/ltable.c +16 −47
  60. src/ltable.h +2 −1
  61. src/ltests.c +0 −852
  62. src/ltm.c +2 −1
  63. src/lua/RCS +0 −1
  64. src/lua/README +2 −2
  65. src/lua/lua.c +101 −146
  66. src/luac/Makefile +1 −5
  67. src/luac/RCS +0 −1
  68. src/luac/README +1 −1
  69. src/luac/luac.c +44 −31
  70. src/luac/print.c +21 −31
  71. src/lundump.c +7 −6
  72. src/lundump.h +3 −3
  73. src/lvm.c +166 −138
  74. src/lvm.h +5 −3
  75. src/lzio.c +2 −1
HISTORY+1−1
@@ -1,4 +1,4 @@
1This is Lua 5.0.1This is Lua 5.1 (work).
2 2
3* Changes from version 4.0 to 5.03* Changes from version 4.0 to 5.0
4 -------------------------------4 -------------------------------
INSTALL+11−11
@@ -1,4 +1,4 @@
1This is Lua 5.0.1This is Lua 5.1 (work).
2 2
3* Installation3* Installation
4 ------------4 ------------
@@ -7,8 +7,9 @@ This is Lua 5.0. · 2 unmodified lines
7 1. Read "config" and edit it to suit your platform and needs.7 1. Read "config" and edit it to suit your platform and needs.
8 We strongly recommend that you enable support for dynamic loading,8 We strongly recommend that you enable support for dynamic loading,
9 if your platform allows it.9 if your platform allows it.
10 2. Do "make".10 2. Do the same for include/luaconf.h.
11 3. If you want to install Lua in an "official" place in your system,11 3. Do "make".
12 4. If you want to install Lua in an "official" place in your system,
12 then do "make install". The official place and the way to install13 then do "make install". The official place and the way to install
13 files are defined in "config". You may have to be root to do this.14 files are defined in "config". You may have to be root to do this.
14 15
@@ -53,27 +54,26 @@ This is Lua 5.0. · 38 unmodified lines
53 /usr/local/lib may not be a place that is checked for shared libraries.54 /usr/local/lib may not be a place that is checked for shared libraries.
54 In Linux, the places checked are in /etc/ld.so.conf. Try also "man ld.so".55 In Linux, the places checked are in /etc/ld.so.conf. Try also "man ld.so".
55 56
56 Building shared libraries in other systems is similar but details differ;57 Building shared libraries on other systems is similar but details differ;
57 you may need to fix a few details in the top-level Makefile.58 you may need to fix a few details in the top-level Makefile.
58 59
59* Installation on Windows and other systems60* Installation on Windows and other systems
60 -----------------------------------------61 -----------------------------------------
61 The instructions for building Lua on other systems machine depend on the62 The instructions for building Lua on other systems depend on the particular
62 particular compiler you are using. The simplest way is to create a folder63 compiler you are using. The simplest way is to create a folder with all .c
63 with all .c and .h files, and then create projects for the core library,64 and .h files, and then create projects for the core library, the standard
64 the standard library, the interpreter, and the compiler, as follows:65 library, the interpreter, and the compiler, as follows:
65 66
66 core lib: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c67 core lib: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c
67 lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c68 lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c
68 ltable.c ltm.c lundump.c lvm.c lzio.c69 ltable.c ltm.c lundump.c lvm.c lzio.c
69 70
70 standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c ltablib.c71 standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c
71 lstrlib.c loadlib.c72 ltablib.c lstrlib.c loadlib.c
72 73
73 interpreter: core lib, standard lib, lua.c74 interpreter: core lib, standard lib, lua.c
74 75
75 compiler: core lib, lauxlib.c luac.c print.c76 compiler: core lib, lauxlib.c luac.c print.c
76 and also lopcodes.c (with LUA_OPNAMES defined) from core.
77 77
78 Of course, to use Lua as a library, you'll have to know how to create78 Of course, to use Lua as a library, you'll have to know how to create
79 and use libraries with your compiler.79 and use libraries with your compiler.
MANIFEST+114−0
@@ -0,0 +1,114 @@
1MANIFEST contents of Lua 5.1 (work1) distribution on Wed Sep 1 22:19:31 BRT 2004
2lua-5.1-work1
3lua-5.1-work1/COPYRIGHT
4lua-5.1-work1/HISTORY
5lua-5.1-work1/INSTALL
6lua-5.1-work1/MANIFEST
7lua-5.1-work1/Makefile
8lua-5.1-work1/README
9lua-5.1-work1/bin
10lua-5.1-work1/build
11lua-5.1-work1/config
12lua-5.1-work1/etc
13lua-5.1-work1/etc/Makefile
14lua-5.1-work1/etc/README
15lua-5.1-work1/etc/all.c
16lua-5.1-work1/etc/lua.ico
17lua-5.1-work1/etc/min.c
18lua-5.1-work1/etc/noparser.c
19lua-5.1-work1/etc/saconfig.c
20lua-5.1-work1/include
21lua-5.1-work1/include/Makefile
22lua-5.1-work1/include/lauxlib.h
23lua-5.1-work1/include/lua.h
24lua-5.1-work1/include/luaconf.h
25lua-5.1-work1/include/lualib.h
26lua-5.1-work1/lib
27lua-5.1-work1/src
28lua-5.1-work1/src/Makefile
29lua-5.1-work1/src/README
30lua-5.1-work1/src/lapi.c
31lua-5.1-work1/src/lapi.h
32lua-5.1-work1/src/lcode.c
33lua-5.1-work1/src/lcode.h
34lua-5.1-work1/src/ldebug.c
35lua-5.1-work1/src/ldebug.h
36lua-5.1-work1/src/ldo.c
37lua-5.1-work1/src/ldo.h
38lua-5.1-work1/src/ldump.c
39lua-5.1-work1/src/lfunc.c
40lua-5.1-work1/src/lfunc.h
41lua-5.1-work1/src/lgc.c
42lua-5.1-work1/src/lgc.h
43lua-5.1-work1/src/lib
44lua-5.1-work1/src/lib/Makefile
45lua-5.1-work1/src/lib/README
46lua-5.1-work1/src/lib/lauxlib.c
47lua-5.1-work1/src/lib/lbaselib.c
48lua-5.1-work1/src/lib/ldblib.c
49lua-5.1-work1/src/lib/linit.c
50lua-5.1-work1/src/lib/liolib.c
51lua-5.1-work1/src/lib/lmathlib.c
52lua-5.1-work1/src/lib/loadlib.c
53lua-5.1-work1/src/lib/loslib.c
54lua-5.1-work1/src/lib/lstrlib.c
55lua-5.1-work1/src/lib/ltablib.c
56lua-5.1-work1/src/llex.c
57lua-5.1-work1/src/llex.h
58lua-5.1-work1/src/llimits.h
59lua-5.1-work1/src/lmem.c
60lua-5.1-work1/src/lmem.h
61lua-5.1-work1/src/lobject.c
62lua-5.1-work1/src/lobject.h
63lua-5.1-work1/src/lopcodes.c
64lua-5.1-work1/src/lopcodes.h
65lua-5.1-work1/src/lparser.c
66lua-5.1-work1/src/lparser.h
67lua-5.1-work1/src/lstate.c
68lua-5.1-work1/src/lstate.h
69lua-5.1-work1/src/lstring.c
70lua-5.1-work1/src/lstring.h
71lua-5.1-work1/src/ltable.c
72lua-5.1-work1/src/ltable.h
73lua-5.1-work1/src/ltm.c
74lua-5.1-work1/src/ltm.h
75lua-5.1-work1/src/lua
76lua-5.1-work1/src/lua/Makefile
77lua-5.1-work1/src/lua/README
78lua-5.1-work1/src/lua/lua.c
79lua-5.1-work1/src/luac
80lua-5.1-work1/src/luac/Makefile
81lua-5.1-work1/src/luac/README
82lua-5.1-work1/src/luac/luac.c
83lua-5.1-work1/src/luac/print.c
84lua-5.1-work1/src/lundump.c
85lua-5.1-work1/src/lundump.h
86lua-5.1-work1/src/lvm.c
87lua-5.1-work1/src/lvm.h
88lua-5.1-work1/src/lzio.c
89lua-5.1-work1/src/lzio.h
90lua-5.1-work1/test
91lua-5.1-work1/test/README
92lua-5.1-work1/test/bisect.lua
93lua-5.1-work1/test/cf.lua
94lua-5.1-work1/test/echo.lua
95lua-5.1-work1/test/env.lua
96lua-5.1-work1/test/factorial.lua
97lua-5.1-work1/test/fib.lua
98lua-5.1-work1/test/fibfor.lua
99lua-5.1-work1/test/globals.lua
100lua-5.1-work1/test/hello.lua
101lua-5.1-work1/test/life.lua
102lua-5.1-work1/test/lua
103lua-5.1-work1/test/luac
104lua-5.1-work1/test/luac.lua
105lua-5.1-work1/test/printf.lua
106lua-5.1-work1/test/readonly.lua
107lua-5.1-work1/test/sieve.lua
108lua-5.1-work1/test/sort.lua
109lua-5.1-work1/test/table.lua
110lua-5.1-work1/test/trace-calls.lua
111lua-5.1-work1/test/trace-globals.lua
112lua-5.1-work1/test/undefined.lua
113lua-5.1-work1/test/xd.lua
114END OF MANIFEST
RCS+0−1
@@ -1 +0,0 @@
1../RCS
README+1−1
@@ -1,4 +1,4 @@
1This is Lua 5.0.1This is Lua 5.1 (work).
2See HISTORY for a summary of changes since the last released version.2See HISTORY for a summary of changes since the last released version.
3 3
4* What is Lua?4* What is Lua?
build+6−3
@@ -1,9 +1,12 @@
1# If you don't want to use make, run this script.1#!/bin/sh
2# But make sure you read config to see what can be customized.2#
3# If you don't want to use make, run this script to build Lua.
4# Read config and include/luaconf.h to see what can be customized.
3 5
4 6
5# Easiest way to build bin/lua:7# Easiest way to build bin/lua:
6# cc -O2 -o bin/lua -Iinclude -Isrc src/*.c src/lib/*.c src/lua/*.c -lm -ldl8# cc -O2 -o bin/lua -Iinclude -Isrc src/*.c src/lib/*.c src/lua/*.c -lm -ldl
9# bin/lua test/hello.lua
7 10
8 11
9# Easiest way to build Lua libraries and executables:12# Easiest way to build Lua libraries and executables:
@@ -25,7 +28,7 @@ cc -O2 -o ../../bin/lua -I../../include *.c ../../lib/*.a -lm -ldl · 15 unmodified lines
25 28
26echo -n 'luac... '29echo -n 'luac... '
27cd ../luac30cd ../luac
28cc -O2 -o ../../bin/luac -I../../include -I.. *.c -DLUA_OPNAMES ../lopcodes.c ../../lib/*.a31cc -O2 -o ../../bin/luac -I../../include -I.. *.c ../../lib/*.a
29 32
30echo 'done'33echo 'done'
31 34
config+5−48
@@ -1,14 +1,10 @@
1# configuration file for making Lua 5.01# configuration file for making Lua 5.1 (work)
2# see INSTALL for installation instructions2# see INSTALL for installation instructions
3 3
4# These are default values. Skip this section and see the explanations below.4# These are default values. Skip this section and see the explanations below.
5 5
6LOADLIB=6LOADLIB=
7DLLIB=7DLLIB=
8NUMBER=
9POPEN=
10TMPNAM=
11DEGREES=
12USERCONF=8USERCONF=
13 9
14# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================10# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
@@ -42,50 +38,11 @@ USERCONF= · 27 unmodified lines
42 38
43# --------------------------------------------------------------- Lua libraries39# --------------------------------------------------------------- Lua libraries
44 40
45# The Lua IO library (src/lib/liolib.c) has support for pipes using popen and41# See include/luaconf.h.
46# pclose. This support is enabled by default on POSIX systems.
47# If your system is not POSIX but has popen and pclose, define USE_POPEN=1.
48# If you don't want to support pipes, define USE_POPEN=0.
49#
50#POPEN= -DUSE_POPEN=1
51#POPEN= -DUSE_POPEN=0
52#
53# The form below will probably work on (some) Windows systems.
54#
55#POPEN= -DUSE_POPEN=1 -Dpopen=_popen -Dpclose=_pclose
56
57# The Lua OS library (src/lib/liolib.c) exports an interface to the C function
58# tmpnam, which gcc now thinks is `dangerous'. So, support for tmpnam is
59# disabled by default when compiling with gcc.
60# If you still want to use tmpnam, define USE_TMPNAME=1. If you don't want to
61# use tmpnam even if you're not compiling with gcc, define USE_TMPNAME=0.
62#
63#TMPNAM= -DUSE_TMPNAME=1
64#TMPNAM= -DUSE_TMPNAME=0
65
66# The Lua math library (src/lib/lmathlib.c) now operates in radians, unlike
67# previous versions of Lua, which used degrees. To use degrees instead of
68# radians, define USE_DEGREES.
69#
70#DEGREES= -DUSE_DEGREES
71 42
72# ------------------------------------------------------------------ Lua core43# ------------------------------------------------------------------ Lua core
73 44
74# Lua uses double for numbers. To change this, uncomment and edit the following45# See include/luaconf.h.
75# line, changing USE_XXX to one of USE_DOUBLE, USE_FLOAT, USE_LONG, USE_INT.
76#
77#NUMBER= -DLUA_USER_H='"../etc/luser_number.h"' -DUSE_XXX
78
79# When compiling Lua with gcc on a Pentium machine, using a fast rounding
80# method for the conversion of doubles to ints can give around 20% speed
81# improvement. To use this rounding method, uncomment the following line.
82#NUMBER= -DLUA_USER_H='"../etc/luser_number.h"' -DUSE_FASTROUND
83
84# For partial compatibility with old upvalue syntax, define LUA_COMPATUPSYNTAX.
85# For partial compatibility with old upvalue behavior in C functions, define
86# LUA_COMPATUPVALUES. Add these definitions to MYCFLAGS.
87#
88# -DLUA_COMPATUPSYNTAX -DLUA_COMPATUPVALUES
89 46
90# ------------------------------------------------------------- Lua interpreter47# ------------------------------------------------------------- Lua interpreter
91 48
@@ -165,14 +122,14 @@ INSTALL_DATA= cp · 73 unmodified lines
165 122
166# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========123# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
167 124
168V= 5.0125V= 5.1
169 126
170BIN= $(LUA)/bin127BIN= $(LUA)/bin
171INC= $(LUA)/include128INC= $(LUA)/include
172LIB= $(LUA)/lib129LIB= $(LUA)/lib
173 130
174INCS= -I$(INC) $(EXTRA_INCS)131INCS= -I$(INC) $(EXTRA_INCS)
175DEFS= $(NUMBER) $(EXTRA_DEFS)132DEFS= $(EXTRA_DEFS)
176 133
177CFLAGS= $(MYCFLAGS) $(WARN) $(INCS) $(DEFS)134CFLAGS= $(MYCFLAGS) $(WARN) $(INCS) $(DEFS)
178 135
configure+0−9
@@ -1,9 +0,0 @@
1#!/bin/sh
2
3# Lua does not use GNU autoconf; just edit ./config if needed to suit your
4# platform and then run make.
5
6# This shows the parameters currently set in ./config:
7make echo
8
9# If you want config as a Lua program, run "make lecho".
etc/Makefile+8−11
@@ -4,32 +4,29 @@ LUA= .. · 3 unmodified lines
4 4
5include $(LUA)/config5include $(LUA)/config
6 6
7LIBLUA=$(LIB)/liblua.a7ALL= min noparser luab 1
8ALL= bin2c min noparser luab
9 8
10all:9all:
11 @echo 'choose a target:' $(ALL)10 @echo 'choose a target:' $(ALL)
12 11
13bin2c: bin2c.c
14 $(CC) $(CFLAGS) -o $@ $@.c
15
16min: min.c $(LIBLUA)12min: min.c $(LIBLUA)
17 $(CC) $(CFLAGS) -o $@ $@.c -L$(LIB) -llua13 $(CC) $(CFLAGS) -o $@ $@.c -L$(LIB) -llua -llualib
18 14
19noparser: noparser.c15noparser: noparser.c
20 $(CC) $(CFLAGS) -I$(LUA)/src -o $@.o -c $@.c16 $(CC) $(CFLAGS) -I$(LUA)/src -o $@.o -c $@.c
21 17
22luab: noparser $(LIBLUA)18luab: noparser
23 $(CC) -o $@ noparser.o $(LUA)/src/lua/lua.o -L$(LIB) -llua -llualib $(EXTRA_LIBS)19 $(CC) -o $@ noparser.o $(LUA)/src/lua/lua.o -L$(LIB) -llua -llualib $(EXTRA_LIBS) $(DLLIB)
24 $(BIN)/luac $(LUA)/test/hello.lua20 $(BIN)/luac $(LUA)/test/hello.lua
25 $@ luac.out21 $@ luac.out
26 -$@ -e'a=1'22 -$@ -e'a=1'
27 23
241:
25 $(CC) $(CFLAGS) -I../src -I../src/lib -I../src/lua all.c $(EXTRA_LIBS) $(DLLIB)
26 ./a.out $(LUA)/test/hello.lua
27
28flat:28flat:
29 cd ..; mkdir flat; mv include/*.h src/*.[ch] src/*/*.[ch] flat29 cd ..; mkdir flat; mv include/*.h src/*.[ch] src/*/*.[ch] flat
30 30
31$(LIBLUA):
32 cd ../src; $(MAKE)
33
34clean:31clean:
35 rm -f $(ALL) a.out core *.o luac.out32 rm -f $(ALL) a.out core *.o luac.out
etc/RCS+0−1
@@ -1 +0,0 @@
1../RCS
etc/README+4−0
@@ -1,6 +1,10 @@
1This directory contains some useful files and code.1This directory contains some useful files and code.
2Unlike the code in ../src, everything here is in the public domain.2Unlike the code in ../src, everything here is in the public domain.
3 3
4all.c
5 Full Lua interpreter in a single file.
6 Do "make 1".
7
4lua.ico8lua.ico
5 A Lua icon for Windows (and web sites, as favicon.ico).9 A Lua icon for Windows (and web sites, as favicon.ico).
6 Drawn by hand by Markus Gritsch <gritsch@iue.tuwien.ac.at>.10 Drawn by hand by Markus Gritsch <gritsch@iue.tuwien.ac.at>.
etc/all.c+41−0
@@ -0,0 +1,41 @@
1/*
2* all.c -- Lua core, libraries and interpreter in a single file
3*/
4
5#define LUA_CORE
6#define LUA_LIB
7#define lua_c
8
9#include "lapi.c"
10#include "lcode.c"
11#include "ldebug.c"
12#include "ldo.c"
13#include "ldump.c"
14#include "lfunc.c"
15#include "lgc.c"
16#include "llex.c"
17#include "lmem.c"
18#include "lobject.c"
19#include "lopcodes.c"
20#include "lparser.c"
21#include "lstate.c"
22#include "lstring.c"
23#include "ltable.c"
24#include "ltm.c"
25#include "lundump.c"
26#include "lvm.c"
27#include "lzio.c"
28
29#include "lauxlib.c"
30#include "lbaselib.c"
31#include "ldblib.c"
32#include "liolib.c"
33#include "linit.c"
34#include "lmathlib.c"
35#include "loadlib.c"
36#define pushresult pushresult2
37#include "loslib.c"
38#include "lstrlib.c"
39#include "ltablib.c"
40
41#include "lua.c"
etc/min.c+28−18
@@ -1,37 +1,47 @@
1/*1/*
2* min.c -- a minimal Lua interpreter2* min.c -- a minimal Lua interpreter
3* only dynamic loading is enabled -- all libraries must be dynamically loaded3* loads stdin only with minimal error handling.
4* no interaction, only batch execution4* no interaction, and no standard library, only a "print" function.
5*/5*/
6 6
7#include <stdio.h>7#include <stdio.h>
8#include "lua.h"8#include "lua.h"
9#include "lualib.h"
10#include "lauxlib.h"9#include "lauxlib.h"
11 10
12static int run(lua_State *L)11static int print(lua_State *L)
13{12{
14 char **argv=lua_touserdata(L,1);13 int n=lua_gettop(L);
15 lua_register(L,"error",lua_error);14 int i;
16 luaopen_loadlib(L);15 for (i=1; i<=n; i++)
17 while (*++argv)
18 {16 {
19 if (luaL_loadfile(L,*argv)) lua_error(L); else lua_call(L,0,0);17 if (i>1) printf("\t");
18 if (lua_isstring(L,i))
19 printf("%s",lua_tostring(L,i));
20 else if (lua_isnil(L,i))
21 printf("%s","nil");
22 else if (lua_isboolean(L,i))
23 printf("%s",lua_toboolean(L,i) ? "true" : "false");
24 else
25 printf("%s:%p",lua_typename(L,lua_type(L,i)),lua_topointer(L,i));
20 }26 }
27 printf("\n");
21 return 0;28 return 0;
22}29}
23 30
24#define report(s) fprintf(stderr,"%s\n",s)31static const char *getF(lua_State *L, void *ud, size_t *size)
32{
33 FILE *f=(FILE *)ud;
34 static char buff[512];
35 if (feof(f)) return NULL;
36 *size=fread(buff,1,sizeof(buff),f);
37 return (*size>0) ? buff : NULL;
38}
25 39
26int main(int argc, char *argv[])40int main(void)
27{41{
28 lua_State *L=lua_open();42 lua_State *L=lua_open();
29 if (L==NULL)43 lua_register(L,"print",print);
30 {44 if (lua_load(L,getF,stdin,"=stdin") || lua_pcall(L,0,0,0))
31 report("not enough memory for state");45 fprintf(stderr,"%s\n",lua_tostring(L,-1));
32 return 1;
33 }
34 if (lua_cpcall(L,run,argv)) report(lua_tostring(L,-1));
35 lua_close(L);
36 return 0;46 return 0;
37}47}
etc/noparser.c+3−0
@@ -9,6 +9,8 @@ · 8 unmodified lines
9* load the parsing modules. To try it, do "make luab".9* load the parsing modules. To try it, do "make luab".
10*/10*/
11 11
12#define LUA_CORE
13
12#include "llex.h"14#include "llex.h"
13#include "lparser.h"15#include "lparser.h"
14#include "lzio.h"16#include "lzio.h"
@@ -28,6 +30,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { · 13 unmodified lines
28/*30/*
29* If you also want to avoid the dump module, ldump.o, enable the code below.31* If you also want to avoid the dump module, ldump.o, enable the code below.
30*/32*/
33#define NODUMP
31#ifdef NODUMP34#ifdef NODUMP
32#include "lundump.h"35#include "lundump.h"
33 36
include/Makefile+1−1
@@ -4,7 +4,7 @@ LUA= .. · 3 unmodified lines
4 4
5include $(LUA)/config5include $(LUA)/config
6 6
7SRCS= lua.h lualib.h lauxlib.h7SRCS= lua.h lualib.h lauxlib.h luaconf.h
8 8
9all:9all:
10 10
include/RCS+0−1
@@ -1 +0,0 @@
1../RCS
include/lauxlib.h+17−16
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lauxlib.h,v 1.63 2004/03/13 13:32:09 roberto Exp $2** $Id: lauxlib.h,v 1.70 2004/07/09 18:23:17 roberto Exp $
3** Auxiliary functions for building Lua libraries3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -15,10 +15,8 @@ · 9 unmodified lines
15#include "lua.h"15#include "lua.h"
16 16
17 17
18#ifndef LUALIB_API18/* extra error code for `luaL_load' */
19#define LUALIB_API LUA_API19#define LUA_ERRFILE (LUA_ERRERR+1)
20#endif
21
22 20
23 21
24typedef struct luaL_reg {22typedef struct luaL_reg {
@@ -56,6 +54,9 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...); · 31 unmodified lines
56 54
57LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);55LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
58 56
57LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name,
58 const char *path);
59
59LUALIB_API int luaL_ref (lua_State *L, int t);60LUALIB_API int luaL_ref (lua_State *L, int t);
60LUALIB_API void luaL_unref (lua_State *L, int t, int ref);61LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
61 62
@@ -85,6 +86,7 @@ LUALIB_API lua_State *(luaL_newstate) (void); · 23 unmodified lines
85#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, n))86#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, n))
86#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, n,d))87#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, n,d))
87 88
89#define luaL_typename(L,i) lua_typename(L,lua_type(L,(i)))
88 90
89/*91/*
90** {======================================================92** {======================================================
@@ -93,10 +95,6 @@ LUALIB_API lua_State *(luaL_newstate) (void); · 2 unmodified lines
93*/95*/
94 96
95 97
96#ifndef LUAL_BUFFERSIZE
97#define LUAL_BUFFERSIZE BUFSIZ
98#endif
99
100 98
101typedef struct luaL_Buffer {99typedef struct luaL_Buffer {
102 char *p; /* current position in buffer */100 char *p; /* current position in buffer */
@@ -122,15 +120,18 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B); · 19 unmodified lines
122/* }====================================================== */120/* }====================================================== */
123 121
124 122
123/* compatibility with ref system */
125 124
126/*125/* pre-defined references */
127** Compatibility macros and functions126#define LUA_NOREF (-2)
128*/127#define LUA_REFNIL (-1)
128
129#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
130 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
131
132#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
129 133
130LUALIB_API int lua_dofile (lua_State *L, const char *filename);134#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref)
131LUALIB_API int lua_dostring (lua_State *L, const char *str);
132LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
133 const char *n);
134 135
135 136
136#endif137#endif
include/lua.h+13−56
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lua.h,v 1.187 2004/03/09 17:34:35 roberto Exp $2** $Id: lua.h,v 1.192 2004/06/04 15:30:53 roberto Exp $
3** Lua - An Extensible Extension Language3** Lua - An Extensible Extension Language
4** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil4** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
5** http://www.lua.org mailto:info@lua.org5** http://www.lua.org mailto:info@lua.org
@@ -14,7 +14,10 @@ · 8 unmodified lines
14#include <stddef.h>14#include <stddef.h>
15 15
16 16
17#define LUA_VERSION "Lua 5.1 (work)"17#include "luaconf.h"
18
19
20#define LUA_VERSION "Lua 5.1 (work1)"
18#define LUA_COPYRIGHT "Copyright (C) 1994-2004 Tecgraf, PUC-Rio"21#define LUA_COPYRIGHT "Copyright (C) 1994-2004 Tecgraf, PUC-Rio"
19#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"22#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
20 23
@@ -34,12 +37,11 @@ · 13 unmodified lines
34#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))37#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
35 38
36 39
37/* error codes for `lua_load' and `lua_pcall' */40/* error codes for `lua_pcall' */
38#define LUA_ERRRUN 141#define LUA_ERRRUN 1
39#define LUA_ERRFILE 242#define LUA_ERRSYNTAX 2
40#define LUA_ERRSYNTAX 343#define LUA_ERRMEM 3
41#define LUA_ERRMEM 444#define LUA_ERRERR 4
42#define LUA_ERRERR 5
43 45
44 46
45typedef struct lua_State lua_State;47typedef struct lua_State lua_State;
@@ -91,26 +93,13 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); · 45 unmodified lines
91 93
92 94
93/* type of numbers in Lua */95/* type of numbers in Lua */
94#ifndef LUA_NUMBER
95typedef double lua_Number;
96#else
97typedef LUA_NUMBER lua_Number;96typedef LUA_NUMBER lua_Number;
98#endif
99 97
100 98
101/* type for integer functions */99/* type for integer functions */
102#ifndef LUA_INTEGER
103typedef long lua_Integer;
104#else
105typedef LUA_INTEGER lua_Integer;100typedef LUA_INTEGER lua_Integer;
106#endif
107 101
108 102
109/* mark for all API functions */
110#ifndef LUA_API
111#define LUA_API extern
112#endif
113
114 103
115/*104/*
116** state manipulation105** state manipulation
@@ -155,7 +144,7 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int idx); · 38 unmodified lines
155LUA_API lua_Integer lua_tointeger (lua_State *L, int idx);144LUA_API lua_Integer lua_tointeger (lua_State *L, int idx);
156LUA_API int lua_toboolean (lua_State *L, int idx);145LUA_API int lua_toboolean (lua_State *L, int idx);
157LUA_API const char *lua_tostring (lua_State *L, int idx);146LUA_API const char *lua_tostring (lua_State *L, int idx);
158LUA_API size_t lua_strlen (lua_State *L, int idx);147LUA_API size_t lua_objsize (lua_State *L, int idx);
159LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx);148LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx);
160LUA_API void *lua_touserdata (lua_State *L, int idx);149LUA_API void *lua_touserdata (lua_State *L, int idx);
161LUA_API lua_State *lua_tothread (lua_State *L, int idx);150LUA_API lua_State *lua_tothread (lua_State *L, int idx);
@@ -228,6 +217,7 @@ LUA_API int lua_resume (lua_State *L, int narg); · 66 unmodified lines
228#define LUA_GCRESTART 1217#define LUA_GCRESTART 1
229#define LUA_GCCOLLECT 2218#define LUA_GCCOLLECT 2
230#define LUA_GCCOUNT 3219#define LUA_GCCOUNT 3
220#define LUA_GCSTEP 4
231 221
232LUA_API int lua_gc (lua_State *L, int what, int data);222LUA_API int lua_gc (lua_State *L, int what, int data);
233 223
@@ -254,11 +244,6 @@ LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud); · 20 unmodified lines
254** ===============================================================244** ===============================================================
255*/245*/
256 246
257#define lua_boxpointer(L,u) \
258 (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
259
260#define lua_unboxpointer(L,i) (*(void **)(lua_touserdata(L, i)))
261
262#define lua_pop(L,n) lua_settop(L, -(n)-1)247#define lua_pop(L,n) lua_settop(L, -(n)-1)
263 248
264#define lua_newtable(L) lua_createtable(L, 0, 0)249#define lua_newtable(L) lua_createtable(L, 0, 0)
@@ -267,6 +252,8 @@ LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud); · 2 unmodified lines
267 252
268#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)253#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
269 254
255#define lua_strlen(L,i) lua_objsize(L,i)
256
270#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)257#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
271#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)258#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
272#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA)259#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA)
@@ -295,39 +282,9 @@ LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud); · 22 unmodified lines
295#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)282#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
296 283
297 284
298/* compatibility with ref system */
299
300/* pre-defined references */
301#define LUA_NOREF (-2)
302#define LUA_REFNIL (-1)
303
304#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
305 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
306
307#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
308
309#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref)
310 285
311 286
312 287
313/*
314** {======================================================================
315** useful definitions for Lua kernel and libraries
316** =======================================================================
317*/
318
319/* formats for Lua numbers */
320#ifndef LUA_NUMBER_SCAN
321#define LUA_NUMBER_SCAN "%lf"
322#endif
323
324#ifndef LUA_NUMBER_FMT
325#define LUA_NUMBER_FMT "%.14g"
326#endif
327
328/* }====================================================================== */
329
330
331/*288/*
332** {======================================================================289** {======================================================================
333** Debug API290** Debug API
include/luaconf.h+312−0
@@ -0,0 +1,312 @@
1/*
2** $Id: luaconf.h,v 1.11 2004/08/30 18:35:14 roberto Exp $
3** Configuration file for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#ifndef lconfig_h
9#define lconfig_h
10
11#include <limits.h>
12#include <stddef.h>
13
14
15/*
16** {======================================================
17** Index (search for keyword to find corresponding entry)
18** =======================================================
19*/
20
21
22/* }====================================================== */
23
24
25
26
27/*
28** {======================================================
29** Generic configuration
30** =======================================================
31*/
32
33/* default path */
34#define LUA_PATH_DEFAULT "?;?.lua"
35
36
37/* type of numbers in Lua */
38#define LUA_NUMBER double
39
40/* formats for Lua numbers */
41#define LUA_NUMBER_SCAN "%lf"
42#define LUA_NUMBER_FMT "%.14g"
43
44
45/* type for integer functions */
46#define LUA_INTEGER long
47
48
49/* mark for all API functions */
50#define LUA_API extern
51
52/* mark for auxlib functions */
53#define LUALIB_API extern
54
55/* buffer size used by lauxlib buffer system */
56#define LUAL_BUFFERSIZE BUFSIZ
57
58
59/* first index for arrays */
60#define LUA_FIRSTINDEX 1
61
62/* assertions in Lua (mainly for internal debugging) */
63#define lua_assert(c) /* empty */
64
65/* }====================================================== */
66
67
68
69/*
70** {======================================================
71** Stand-alone configuration
72** =======================================================
73*/
74
75#ifdef lua_c
76
77/* definition of `isatty' */
78#ifdef _POSIX_C_SOURCE
79#include <unistd.h>
80#define stdin_is_tty() isatty(0)
81#else
82#define stdin_is_tty() 1 /* assume stdin is a tty */
83#endif
84
85
86#define PROMPT "> "
87#define PROMPT2 ">> "
88#define PROGNAME "lua"
89
90
91/*
92** this macro allows you to open other libraries when starting the
93** stand-alone interpreter
94*/
95#define lua_userinit(L) luaopen_stdlibs(L)
96/*
97** #define lua_userinit(L) { int luaopen_mylibs(lua_State *L); \
98** luaopen_stdlibs(L); luaopen_mylibs(L); }
99*/
100
101
102
103/*
104** this macro can be used by some `history' system to save lines
105** read in manual input
106*/
107#define lua_saveline(L,line) /* empty */
108
109
110
111#endif
112
113/* }====================================================== */
114
115
116
117/*
118** {======================================================
119** Core configuration
120** =======================================================
121*/
122
123#ifdef LUA_CORE
124
125/* LUA-C API assertions */
126#define api_check(L, o) /* empty */
127
128
129/* an unsigned integer with at least 32 bits */
130#define LUA_UINT32 unsigned long
131
132/* a signed integer with at least 32 bits */
133#define LUA_INT32 long
134#define LUA_MAXINT32 LONG_MAX
135
136
137/* maximum depth for calls (unsigned short) */
138#define LUA_MAXCALLS 4096
139
140/*
141** maximum depth for C calls (unsigned short): Not too big, or may
142** overflow the C stack...
143*/
144#define LUA_MAXCCALLS 200
145
146
147/* maximum size for the virtual stack of a C function */
148#define MAXCSTACK 2048
149
150
151/*
152** maximum number of syntactical nested non-terminals: Not too big,
153** or may overflow the C stack...
154*/
155#define LUA_MAXPARSERLEVEL 200
156
157
158/* maximum number of variables declared in a function */
159#define MAXVARS 200 /* <MAXSTACK */
160
161
162/* maximum number of upvalues per function */
163#define MAXUPVALUES 32 /* <MAXSTACK */
164
165
166/* maximum size of expressions for optimizing `while' code */
167#define MAXEXPWHILE 100
168
169
170/* function to convert a lua_Number to int (with any rounding method) */
171#if defined(__GNUC__) && defined(__i386)
172#define lua_number2int(i,d) __asm__ ("fistpl %0":"=m"(i):"t"(d):"st")
173#elif 0
174/* on machines compliant with C99, you can try `lrint' */
175#include <math.h>
176#define lua_number2int(i,d) ((i)=lrint(d))
177#else
178#define lua_number2int(i,d) ((i)=(int)(d))
179#endif
180
181/* function to convert a lua_Number to lua_Integer (with any rounding method) */
182#define lua_number2integer(i,n) lua_number2int(i,n)
183
184
185/* function to convert a lua_Number to a string */
186#include <stdio.h>
187#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
188
189/* function to convert a string to a lua_Number */
190#define lua_str2number(s,p) strtod((s), (p))
191
192
193
194/* result of a `usual argument conversion' over lua_Number */
195#define LUA_UACNUMBER double
196
197
198/* number of bits in an `int' */
199/* avoid overflows in comparison */
200#if INT_MAX-20 < 32760
201#define LUA_BITSINT 16
202#elif INT_MAX > 2147483640L
203/* machine has at least 32 bits */
204#define LUA_BITSINT 32
205#else
206#error "you must define LUA_BITSINT with number of bits in an integer"
207#endif
208
209
210/* type to ensure maximum alignment */
211#define LUSER_ALIGNMENT_T union { double u; void *s; long l; }
212
213
214/* exception handling */
215#ifndef __cplusplus
216/* default handling with long jumps */
217#include <setjmp.h>
218#define L_THROW(c) longjmp((c)->b, 1)
219#define L_TRY(c,a) if (setjmp((c)->b) == 0) { a }
220#define l_jmpbuf jmp_buf
221
222#else
223/* C++ exceptions */
224#define L_THROW(c) throw(c)
225#define L_TRY(c,a) try { a } catch(...) \
226 { if ((c)->status == 0) (c)->status = -1; }
227#define l_jmpbuf int /* dummy variable */
228#endif
229
230
231
232/*
233** macros for thread synchronization inside Lua core machine:
234** all accesses to the global state and to global objects are synchronized.
235** Because threads can read the stack of other threads
236** (when running garbage collection),
237** a thread must also synchronize any write-access to its own stack.
238** Unsynchronized accesses are allowed only when reading its own stack,
239** or when reading immutable fields from global objects
240** (such as string values and udata values).
241*/
242#define lua_lock(L) ((void) 0)
243#define lua_unlock(L) ((void) 0)
244
245/*
246** this macro allows a thread switch in appropriate places in the Lua
247** core
248*/
249#define lua_threadyield(L) {lua_unlock(L); lua_lock(L);}
250
251
252
253/* allows user-specific initialization on new threads */
254#define lua_userstateopen(l) /* empty */
255
256
257#endif
258
259/* }====================================================== */
260
261
262
263/*
264** {======================================================
265** Library configuration
266** =======================================================
267*/
268
269#ifdef LUA_LIB
270
271
272
273/* `assert' options */
274
275/* environment variable that holds the search path for packages */
276#define LUA_PATH "LUA_PATH"
277
278/* separator of templates in a path */
279#define LUA_PATH_SEP ';'
280
281/* wild char in each template */
282#define LUA_PATH_MARK "?"
283
284
285/* maximum number of captures in pattern-matching */
286#define MAX_CAPTURES 32 /* arbitrary limit */
287
288
289/*
290** by default, gcc does not get `tmpname'
291*/
292#ifdef __GNUC__
293#define USE_TMPNAME 0
294#else
295#define USE_TMPNAME 1
296#endif
297
298
299
300#endif
301
302/* }====================================================== */
303
304
305
306
307/* Local configuration */
308
309#undef USE_TMPNAME
310#define USE_TMPNAME 1
311
312#endif
include/lualib.h+8−17
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lualib.h,v 1.28 2003/03/18 12:24:26 roberto Exp $2** $Id: lualib.h,v 1.32 2004/07/09 15:47:48 roberto Exp $
3** Lua standard libraries3** Lua standard libraries
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -11,9 +11,8 @@ · 5 unmodified lines
11#include "lua.h"11#include "lua.h"
12 12
13 13
14#ifndef LUALIB_API14/* Key to file-handle type */
15#define LUALIB_API LUA_API15#define LUA_FILEHANDLE "FILE*"
16#endif
17 16
18 17
19#define LUA_COLIBNAME "coroutine"18#define LUA_COLIBNAME "coroutine"
@@ -23,9 +22,11 @@ LUALIB_API int luaopen_base (lua_State *L); · 3 unmodified lines
23LUALIB_API int luaopen_table (lua_State *L);22LUALIB_API int luaopen_table (lua_State *L);
24 23
25#define LUA_IOLIBNAME "io"24#define LUA_IOLIBNAME "io"
26#define LUA_OSLIBNAME "os"
27LUALIB_API int luaopen_io (lua_State *L);25LUALIB_API int luaopen_io (lua_State *L);
28 26
27#define LUA_OSLIBNAME "os"
28LUALIB_API int luaopen_os (lua_State *L);
29
29#define LUA_STRLIBNAME "string"30#define LUA_STRLIBNAME "string"
30LUALIB_API int luaopen_string (lua_State *L);31LUALIB_API int luaopen_string (lua_State *L);
31 32
@@ -39,18 +40,8 @@ LUALIB_API int luaopen_debug (lua_State *L); · 7 unmodified lines
39LUALIB_API int luaopen_loadlib (lua_State *L);40LUALIB_API int luaopen_loadlib (lua_State *L);
40 41
41 42
42/* to help testing the libraries */43/* open all previous libraries */
43#ifndef lua_assert44LUALIB_API int luaopen_stdlibs (lua_State *L);
44#define lua_assert(c) /* empty */
45#endif
46
47 45
48/* compatibility code */
49#define lua_baselibopen luaopen_base
50#define lua_tablibopen luaopen_table
51#define lua_iolibopen luaopen_io
52#define lua_strlibopen luaopen_string
53#define lua_mathlibopen luaopen_math
54#define lua_dblibopen luaopen_debug
55 46
56#endif47#endif
src/RCS+0−1
@@ -1 +0,0 @@
1../RCS
src/README+2−2
@@ -1,5 +1,5 @@
1This is the Lua core.1This is the Lua core.
2 2
3The standard Lua library are in lib/.3The standard Lua library are in lib/.
4A sample interpreter is in lua/.4The standalone interpreter is in lua/.
5A standalone compiler is in luac/.5The standalone compiler is in luac/.
src/lapi.c+55−33
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lapi.c,v 2.5 2004/03/23 17:07:34 roberto Exp $2** $Id: lapi.c,v 2.18 2004/08/30 13:44:44 roberto Exp $
3** Lua API3** Lua API
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -10,6 +10,7 @@ · 4 unmodified lines
10#include <string.h>10#include <string.h>
11 11
12#define lapi_c12#define lapi_c
13#define LUA_CORE
13 14
14#include "lua.h"15#include "lua.h"
15 16
@@ -28,11 +29,6 @@ · 12 unmodified lines
28#include "lvm.h"29#include "lvm.h"
29 30
30 31
31/* function to convert a lua_Number to lua_Integer (with any rounding method) */
32#ifndef lua_number2integer
33#define lua_number2integer(i,n) ((i)=(lua_Integer)(n))
34#endif
35
36 32
37const char lua_ident[] =33const char lua_ident[] =
38 "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"34 "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
@@ -41,10 +37,6 @@ const char lua_ident[] = · 2 unmodified lines
41 37
42 38
43 39
44#ifndef api_check
45#define api_check(L, o) lua_assert(o)
46#endif
47
48#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))40#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
49 41
50#define api_checkvalidindex(L, i) api_check(L, (i) != &luaO_nilobject)42#define api_checkvalidindex(L, i) api_check(L, (i) != &luaO_nilobject)
@@ -56,7 +48,7 @@ const char lua_ident[] = · 5 unmodified lines
56static TValue *luaA_index (lua_State *L, int idx) {48static TValue *luaA_index (lua_State *L, int idx) {
57 if (idx > 0) {49 if (idx > 0) {
58 TValue *o = L->base + (idx - 1);50 TValue *o = L->base + (idx - 1);
59 api_check(L, idx <= L->stack_last - L->base);51 api_check(L, idx <= L->ci->top - L->base);
60 if (o >= L->top) return cast(TValue *, &luaO_nilobject);52 if (o >= L->top) return cast(TValue *, &luaO_nilobject);
61 else return o;53 else return o;
62 }54 }
@@ -87,7 +79,7 @@ void luaA_pushobject (lua_State *L, const TValue *o) { · 24 unmodified lines
87LUA_API int lua_checkstack (lua_State *L, int size) {79LUA_API int lua_checkstack (lua_State *L, int size) {
88 int res;80 int res;
89 lua_lock(L);81 lua_lock(L);
90 if ((L->top - L->base + size) > LUA_MAXCSTACK)82 if ((L->top - L->base + size) > MAXCSTACK)
91 res = 0; /* stack overflow */83 res = 0; /* stack overflow */
92 else {84 else {
93 luaD_checkstack(L, size);85 luaD_checkstack(L, size);
@@ -331,10 +323,12 @@ LUA_API const char *lua_tostring (lua_State *L, int idx) { · 237 unmodified lines
331}323}
332 324
333 325
334LUA_API size_t lua_strlen (lua_State *L, int idx) {326LUA_API size_t lua_objsize (lua_State *L, int idx) {
335 StkId o = luaA_index(L, idx);327 StkId o = luaA_index(L, idx);
336 if (ttisstring(o))328 if (ttisstring(o))
337 return tsvalue(o)->len;329 return tsvalue(o)->len;
330 else if (ttisuserdata(o))
331 return uvalue(o)->len;
338 else {332 else {
339 size_t l;333 size_t l;
340 lua_lock(L); /* `luaV_tostring' may create a new string */334 lua_lock(L); /* `luaV_tostring' may create a new string */
@@ -496,7 +490,7 @@ LUA_API void lua_gettable (lua_State *L, int idx) { · 155 unmodified lines
496 lua_lock(L);490 lua_lock(L);
497 t = luaA_index(L, idx);491 t = luaA_index(L, idx);
498 api_checkvalidindex(L, t);492 api_checkvalidindex(L, t);
499 luaV_gettable(L, t, L->top - 1, L->top - 1);493 luaV_gettable(L, t, L->top - 1, L->top - 1, NULL);
500 lua_unlock(L);494 lua_unlock(L);
501}495}
502 496
@@ -508,7 +502,7 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { · 5 unmodified lines
508 t = luaA_index(L, idx);502 t = luaA_index(L, idx);
509 api_checkvalidindex(L, t);503 api_checkvalidindex(L, t);
510 setsvalue(L, &key, luaS_new(L, k));504 setsvalue(L, &key, luaS_new(L, k));
511 luaV_gettable(L, t, &key, L->top);505 luaV_gettable(L, t, &key, L->top, NULL);
512 api_incr_top(L);506 api_incr_top(L);
513 lua_unlock(L);507 lua_unlock(L);
514}508}
@@ -592,7 +586,7 @@ LUA_API void lua_settable (lua_State *L, int idx) { · 77 unmodified lines
592 api_checknelems(L, 2);586 api_checknelems(L, 2);
593 t = luaA_index(L, idx);587 t = luaA_index(L, idx);
594 api_checkvalidindex(L, t);588 api_checkvalidindex(L, t);
595 luaV_settable(L, t, L->top - 2, L->top - 1);589 luaV_settable(L, t, L->top - 2, L->top - 1, NULL);
596 L->top -= 2; /* pop index and value */590 L->top -= 2; /* pop index and value */
597 lua_unlock(L);591 lua_unlock(L);
598}592}
@@ -606,7 +600,7 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { · 7 unmodified lines
606 t = luaA_index(L, idx);600 t = luaA_index(L, idx);
607 api_checkvalidindex(L, t);601 api_checkvalidindex(L, t);
608 setsvalue(L, &key, luaS_new(L, k));602 setsvalue(L, &key, luaS_new(L, k));
609 luaV_settable(L, t, &key, L->top - 1);603 luaV_settable(L, t, &key, L->top - 1, NULL);
610 L->top--; /* pop value */604 L->top--; /* pop value */
611 lua_unlock(L);605 lua_unlock(L);
612}606}
@@ -619,7 +613,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) { · 6 unmodified lines
619 t = luaA_index(L, idx);613 t = luaA_index(L, idx);
620 api_check(L, ttistable(t));614 api_check(L, ttistable(t));
621 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);615 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
622 luaC_barrier(L, hvalue(t), L->top-1);616 luaC_barriert(L, hvalue(t), L->top-1);
623 L->top -= 2;617 L->top -= 2;
624 lua_unlock(L);618 lua_unlock(L);
625}619}
@@ -632,7 +626,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { · 6 unmodified lines
632 o = luaA_index(L, idx);626 o = luaA_index(L, idx);
633 api_check(L, ttistable(o));627 api_check(L, ttistable(o));
634 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);628 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
635 luaC_barrier(L, hvalue(o), L->top-1);629 luaC_barriert(L, hvalue(o), L->top-1);
636 L->top--;630 L->top--;
637 lua_unlock(L);631 lua_unlock(L);
638}632}
@@ -683,12 +677,13 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { · 44 unmodified lines
683 api_checknelems(L, 1);677 api_checknelems(L, 1);
684 o = luaA_index(L, idx);678 o = luaA_index(L, idx);
685 api_checkvalidindex(L, o);679 api_checkvalidindex(L, o);
686 L->top--;680 api_check(L, ttistable(L->top - 1));
687 api_check(L, ttistable(L->top));
688 if (isLfunction(o)) {681 if (isLfunction(o)) {
689 res = 1;682 res = 1;
690 clvalue(o)->l.g = *(L->top);683 clvalue(o)->l.g = *(L->top - 1);
684 luaC_objbarrier(L, clvalue(o), hvalue(L->top - 1));
691 }685 }
686 L->top--;
692 lua_unlock(L);687 lua_unlock(L);
693 return res;688 return res;
694}689}
@@ -698,12 +693,23 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { · 3 unmodified lines
698** `load' and `call' functions (run Lua code)693** `load' and `call' functions (run Lua code)
699*/694*/
700 695
696
697#define adjustresults(L,nres) \
698 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
699
700
701#define checkresults(L,na,nr) \
702 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
703
704
701LUA_API void lua_call (lua_State *L, int nargs, int nresults) {705LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
702 StkId func;706 StkId func;
703 lua_lock(L);707 lua_lock(L);
704 api_checknelems(L, nargs+1);708 api_checknelems(L, nargs+1);
709 checkresults(L, nargs, nresults);
705 func = L->top - (nargs+1);710 func = L->top - (nargs+1);
706 luaD_call(L, func, nresults);711 luaD_call(L, func, nresults);
712 adjustresults(L, nresults);
707 lua_unlock(L);713 lua_unlock(L);
708}714}
709 715
@@ -730,6 +736,8 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { · 20 unmodified lines
730 int status;736 int status;
731 ptrdiff_t func;737 ptrdiff_t func;
732 lua_lock(L);738 lua_lock(L);
739 api_checknelems(L, nargs+1);
740 checkresults(L, nargs, nresults);
733 if (errfunc == 0)741 if (errfunc == 0)
734 func = 0;742 func = 0;
735 else {743 else {
@@ -740,6 +748,7 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { · 4 unmodified lines
740 c.func = L->top - (nargs+1); /* function to be called */748 c.func = L->top - (nargs+1); /* function to be called */
741 c.nresults = nresults;749 c.nresults = nresults;
742 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);750 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
751 adjustresults(L, nresults);
743 lua_unlock(L);752 lua_unlock(L);
744 return status;753 return status;
745}754}
@@ -812,28 +821,41 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) { · 66 unmodified lines
812*/821*/
813 822
814LUA_API int lua_gc (lua_State *L, int what, int data) {823LUA_API int lua_gc (lua_State *L, int what, int data) {
815 global_State *g = G(L);824 int res = 0;
825 global_State *g;
826 lua_lock(L);
827 g = G(L);
816 switch (what) {828 switch (what) {
817 case LUA_GCSTOP: {829 case LUA_GCSTOP: {
818 g->GCthreshold = MAXLMEM;830 g->GCthreshold = MAXLMEM;
819 return 0;831 break;
820 }832 }
821 case LUA_GCRESTART: {833 case LUA_GCRESTART: {
822 g->GCthreshold = g->nblocks;834 g->GCthreshold = g->totalbytes;
823 return 0;835 break;
824 }836 }
825 case LUA_GCCOLLECT: {837 case LUA_GCCOLLECT: {
826 lua_lock(L);
827 luaC_fullgc(L);838 luaC_fullgc(L);
828 lua_unlock(L);839 break;
829 return 0;
830 }840 }
831 case LUA_GCCOUNT: {841 case LUA_GCCOUNT: {
832 /* GC values are expressed in Kbytes: #bytes/2^10 */842 /* GC values are expressed in Kbytes: #bytes/2^10 */
833 return cast(int, g->nblocks >> 10);843 res = cast(int, g->totalbytes >> 10);
844 break;
845 }
846 case LUA_GCSTEP: {
847 lu_mem a = (cast(lu_mem, data) << 10);
848 if (a <= g->totalbytes)
849 g->GCthreshold = g->totalbytes - a;
850 else
851 g->GCthreshold = 0;
852 luaC_step(L);
853 break;
834 }854 }
835 default: return -1; /* invalid option */855 default: res = -1; /* invalid option */
836 }856 }
857 lua_unlock(L);
858 return res;
837}859}
838 860
839 861
@@ -916,13 +938,13 @@ static const char *aux_upvalue (lua_State *L, StkId fi, int n, TValue **val) { · 76 unmodified lines
916 if (!ttisfunction(fi)) return NULL;938 if (!ttisfunction(fi)) return NULL;
917 f = clvalue(fi);939 f = clvalue(fi);
918 if (f->c.isC) {940 if (f->c.isC) {
919 if (n > f->c.nupvalues) return NULL;941 if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
920 *val = &f->c.upvalue[n-1];942 *val = &f->c.upvalue[n-1];
921 return "";943 return "";
922 }944 }
923 else {945 else {
924 Proto *p = f->l.p;946 Proto *p = f->l.p;
925 if (n > p->sizeupvalues) return NULL;947 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
926 *val = f->l.upvals[n-1]->v;948 *val = f->l.upvals[n-1]->v;
927 return getstr(p->upvalues[n-1]);949 return getstr(p->upvalues[n-1]);
928 }950 }
src/lcode.c+28−13
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: lcode.c,v 2.6 2004/08/24 20:09:11 roberto Exp $
3** Code generator for Lua3** Code generator for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <stdlib.h>8#include <stdlib.h>
9 9
10#define lcode_c10#define lcode_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -194,7 +195,7 @@ void luaK_reserveregs (FuncState *fs, int n) { · 180 unmodified lines
194 195
195 196
196static void freereg (FuncState *fs, int reg) {197static void freereg (FuncState *fs, int reg) {
197 if (reg >= fs->nactvar && reg < MAXSTACK) {198 if (!ISK(reg) && reg >= fs->nactvar) {
198 fs->freereg--;199 fs->freereg--;
199 lua_assert(reg == fs->freereg);200 lua_assert(reg == fs->freereg);
200 }201 }
@@ -222,7 +223,7 @@ static int addk (FuncState *fs, TValue *k, TValue *v) { · 21 unmodified lines
222 MAXARG_Bx, "constant table overflow");223 MAXARG_Bx, "constant table overflow");
223 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);224 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
224 setobj(L, &f->k[fs->nk], v);225 setobj(L, &f->k[fs->nk], v);
225 luaC_barrier(L, f, v);226 luaC_barriert(L, f, v);
226 return fs->nk++;227 return fs->nk++;
227 }228 }
228}229}
@@ -251,13 +252,26 @@ static int nil_constant (FuncState *fs) { · 22 unmodified lines
251}252}
252 253
253 254
254void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {255void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
255 if (e->k == VCALL) { /* expression is an open function call? */256 if (e->k == VCALL) { /* expression is an open function call? */
256 SETARG_C(getcode(fs, e), nresults+1);257 SETARG_C(getcode(fs, e), nresults+1);
257 if (nresults == 1) { /* `regular' expression? */258 }
258 e->k = VNONRELOC;259 else if (e->k == VVARARG) {
259 e->info = GETARG_A(getcode(fs, e));260 SETARG_B(getcode(fs, e), nresults+1);
260 }261 SETARG_A(getcode(fs, e), fs->freereg);
262 luaK_reserveregs(fs, 1);
263 }
264}
265
266
267void luaK_setoneret (FuncState *fs, expdesc *e) {
268 if (e->k == VCALL) { /* expression is an open function call? */
269 e->k = VNONRELOC;
270 e->info = GETARG_A(getcode(fs, e));
271 }
272 else if (e->k == VVARARG) {
273 SETARG_B(getcode(fs, e), 2);
274 e->k = VRELOCABLE; /* can relocate its simple result */
261 }275 }
262}276}
263 277
@@ -285,8 +299,9 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 21 unmodified lines
285 e->k = VRELOCABLE;299 e->k = VRELOCABLE;
286 break;300 break;
287 }301 }
302 case VVARARG:
288 case VCALL: {303 case VCALL: {
289 luaK_setcallreturns(fs, e, 1);304 luaK_setoneret(fs, e);
290 break;305 break;
291 }306 }
292 default: break; /* there is one value available (somewhere) */307 default: break; /* there is one value available (somewhere) */
@@ -403,16 +418,16 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { · 110 unmodified lines
403 luaK_exp2val(fs, e);418 luaK_exp2val(fs, e);
404 switch (e->k) {419 switch (e->k) {
405 case VNIL: {420 case VNIL: {
406 if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */421 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
407 e->info = nil_constant(fs);422 e->info = nil_constant(fs);
408 e->k = VK;423 e->k = VK;
409 return e->info + MAXSTACK;424 return RKASK(e->info);
410 }425 }
411 else break;426 else break;
412 }427 }
413 case VK: {428 case VK: {
414 if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */429 if (e->info <= MAXINDEXRK) /* constant fit in argC? */
415 return e->info + MAXSTACK;430 return RKASK(e->info);
416 else break;431 else break;
417 }432 }
418 default: break;433 default: break;
src/lcode.h+5−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp $2** $Id: lcode.h,v 1.39 2004/05/31 18:51:50 roberto Exp $
3** Code generator for Lua3** Code generator for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -41,6 +41,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; · 35 unmodified lines
41 41
42#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)42#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
43 43
44#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
45
44int luaK_code (FuncState *fs, Instruction i, int line);46int luaK_code (FuncState *fs, Instruction i, int line);
45int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);47int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);48int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
@@ -60,7 +62,8 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); · 13 unmodified lines
60void luaK_goiftrue (FuncState *fs, expdesc *e);62void luaK_goiftrue (FuncState *fs, expdesc *e);
61void luaK_goiffalse (FuncState *fs, expdesc *e);63void luaK_goiffalse (FuncState *fs, expdesc *e);
62void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);64void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
63void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);65void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
66void luaK_setoneret (FuncState *fs, expdesc *e);
64int luaK_jump (FuncState *fs);67int luaK_jump (FuncState *fs);
65void luaK_patchlist (FuncState *fs, int list, int target);68void luaK_patchlist (FuncState *fs, int list, int target);
66void luaK_patchtohere (FuncState *fs, int list);69void luaK_patchtohere (FuncState *fs, int list);
src/ldebug.c+24−15
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldebug.c,v 2.3 2004/03/23 13:10:16 roberto Exp $2** $Id: ldebug.c,v 2.8 2004/09/01 13:47:31 roberto Exp $
3** Debug Interface3** Debug Interface
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -11,6 +11,7 @@ · 5 unmodified lines
11 11
12 12
13#define ldebug_c13#define ldebug_c
14#define LUA_CORE
14 15
15#include "lua.h"16#include "lua.h"
16 17
@@ -34,7 +35,7 @@ static const char *getfuncname (CallInfo *ci, const char **name); · 17 unmodified lines
34 35
35static int currentpc (CallInfo *ci) {36static int currentpc (CallInfo *ci) {
36 if (!isLua(ci)) return -1; /* function is not a Lua function? */37 if (!isLua(ci)) return -1; /* function is not a Lua function? */
37 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);38 return pcRel(ci->savedpc, ci_func(ci)->l.p);
38}39}
39 40
40 41
@@ -85,7 +86,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { · 44 unmodified lines
85 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {86 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
86 level--;87 level--;
87 if (f_isLua(ci)) /* Lua function? */88 if (f_isLua(ci)) /* Lua function? */
88 level -= ci->u.l.tailcalls; /* skip lost tail calls */89 level -= ci->tailcalls; /* skip lost tail calls */
89 }90 }
90 if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */91 if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */
91 else if (level < 0) { /* level is of a lost tail call */92 else if (level < 0) { /* level is of a lost tail call */
@@ -220,8 +221,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { · 128 unmodified lines
220 }221 }
221 else if (ar->i_ci != 0) { /* no tail call? */222 else if (ar->i_ci != 0) { /* no tail call? */
222 CallInfo *ci = L->base_ci + ar->i_ci;223 CallInfo *ci = L->base_ci + ar->i_ci;
223 lua_assert(ttisfunction(ci->base - 1));224 lua_assert(ttisfunction(ci->func));
224 status = auxgetinfo(L, what, ar, ci->base - 1, ci);225 status = auxgetinfo(L, what, ar, ci->func, ci);
225 }226 }
226 else227 else
227 info_tailcall(L, ar);228 info_tailcall(L, ar);
@@ -254,8 +255,9 @@ static int precheck (const Proto *pt) { · 26 unmodified lines
254}255}
255 256
256 257
257static int checkopenop (const Proto *pt, int pc) {258#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
258 Instruction i = pt->code[pc+1];259
260int luaG_checkopenop (Instruction i) {
259 switch (GET_OPCODE(i)) {261 switch (GET_OPCODE(i)) {
260 case OP_CALL:262 case OP_CALL:
261 case OP_TAILCALL:263 case OP_TAILCALL:
@@ -274,8 +276,8 @@ static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { · 12 unmodified lines
274 case OpArgN: check(r == 0); break;276 case OpArgN: check(r == 0); break;
275 case OpArgU: break;277 case OpArgU: break;
276 case OpArgR: checkreg(pt, r); break;278 case OpArgR: checkreg(pt, r); break;
277 case OpArgK: 279 case OpArgK:
278 check(r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));280 check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
279 break;281 break;
280 }282 }
281 return 1;283 return 1;
@@ -355,7 +357,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { · 73 unmodified lines
355 }357 }
356 case OP_TFORLOOP: {358 case OP_TFORLOOP: {
357 checkreg(pt, a+5); /* space for control variables */359 checkreg(pt, a+5); /* space for control variables */
358 if (reg >= a) last = pc; /* affect all registers above base */360 if (reg >= a+3) last = pc; /* affect all regs above its call base */
359 break;361 break;
360 }362 }
361 case OP_TFORPREP:363 case OP_TFORPREP:
@@ -404,6 +406,13 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { · 42 unmodified lines
404 }406 }
405 break;407 break;
406 }408 }
409 case OP_VARARG: {
410 check(pt->is_vararg & NEWSTYLEVARARG);
411 b--;
412 if (b == LUA_MULTRET) check(checkopenop(pt, pc));
413 checkreg(pt, a+b-1);
414 break;
415 }
407 default: break;416 default: break;
408 }417 }
409 }418 }
@@ -423,9 +432,8 @@ int luaG_checkcode (const Proto *pt) { · 13 unmodified lines
423 432
424 433
425static const char *kname (Proto *p, int c) {434static const char *kname (Proto *p, int c) {
426 c = c - MAXSTACK;435 if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
427 if (c >= 0 && ttisstring(&p->k[c]))436 return svalue(&p->k[INDEXK(c)]);
428 return svalue(&p->k[c]);
429 else437 else
430 return "?";438 return "?";
431}439}
@@ -479,11 +487,12 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { · 47 unmodified lines
479 487
480static const char *getfuncname (CallInfo *ci, const char **name) {488static const char *getfuncname (CallInfo *ci, const char **name) {
481 Instruction i;489 Instruction i;
482 if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))490 if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
483 return NULL; /* calling function is not Lua (or is unknown) */491 return NULL; /* calling function is not Lua (or is unknown) */
484 ci--; /* calling function */492 ci--; /* calling function */
485 i = ci_func(ci)->l.p->code[currentpc(ci)];493 i = ci_func(ci)->l.p->code[currentpc(ci)];
486 if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)494 if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
495 GET_OPCODE(i) == OP_TFORLOOP)
487 return getobjname(ci, GETARG_A(i), name);496 return getobjname(ci, GETARG_A(i), name);
488 else497 else
489 return NULL; /* no useful name can be found */498 return NULL; /* no useful name can be found */
src/ldebug.h+2−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldebug.h,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: ldebug.h,v 2.2 2004/06/02 19:07:55 roberto Exp $
3** Auxiliary functions from Debug Interface module3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -25,6 +25,6 @@ int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2); · 19 unmodified lines
25void luaG_runerror (lua_State *L, const char *fmt, ...);25void luaG_runerror (lua_State *L, const char *fmt, ...);
26void luaG_errormsg (lua_State *L);26void luaG_errormsg (lua_State *L);
27int luaG_checkcode (const Proto *pt);27int luaG_checkcode (const Proto *pt);
28 28int luaG_checkopenop (Instruction i);
29 29
30#endif30#endif
src/ldo.c+68−56
@@ -1,15 +1,15 @@
1/*1/*
2** $Id: ldo.c,v 2.2 2004/03/23 17:02:58 roberto Exp $2** $Id: ldo.c,v 2.7 2004/06/02 19:07:55 roberto Exp $
3** Stack and Call structure of Lua3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
6 6
7 7
8#include <setjmp.h>
9#include <stdlib.h>8#include <stdlib.h>
10#include <string.h>9#include <string.h>
11 10
12#define ldo_c11#define ldo_c
12#define LUA_CORE
13 13
14#include "lua.h"14#include "lua.h"
15 15
@@ -34,29 +34,15 @@ · 18 unmodified lines
34 34
35/*35/*
36** {======================================================36** {======================================================
37** Error-recovery functions (based on long jumps)37** Error-recovery functions
38** =======================================================38** =======================================================
39*/39*/
40 40
41 41
42#ifndef LUA_USEEXCEPTIONS
43
44#define L_THROW(c) longjmp((c)->b, 1)
45#define L_TRY(c,a) if (setjmp((c)->b) == 0) { a }
46
47#else
48
49#define L_THROW(c) throw(c)
50#define L_TRY(c,a) try { a } catch(...) \
51 { if ((c)->status == 0) (c)->status = -1; }
52
53#endif
54
55
56/* chain list of long jump buffers */42/* chain list of long jump buffers */
57struct lua_longjmp {43struct lua_longjmp {
58 struct lua_longjmp *previous;44 struct lua_longjmp *previous;
59 jmp_buf b;45 l_jmpbuf b;
60 volatile int status; /* error code */46 volatile int status; /* error code */
61};47};
62 48
@@ -127,6 +113,7 @@ static void correctstack (lua_State *L, TValue *oldstack) { · 64 unmodified lines
127 for (ci = L->base_ci; ci <= L->ci; ci++) {113 for (ci = L->base_ci; ci <= L->ci; ci++) {
128 ci->top = (ci->top - oldstack) + L->stack;114 ci->top = (ci->top - oldstack) + L->stack;
129 ci->base = (ci->base - oldstack) + L->stack;115 ci->base = (ci->base - oldstack) + L->stack;
116 ci->func = (ci->func - oldstack) + L->stack;
130 }117 }
131 L->base = L->ci->base;118 L->base = L->ci->base;
132}119}
@@ -195,26 +182,37 @@ void luaD_callhook (lua_State *L, int event, int line) { · 62 unmodified lines
195}182}
196 183
197 184
198static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {185static StkId adjust_varargs (lua_State *L, int nfixargs, int actual,
186 int style) {
199 int i;187 int i;
200 Table *htab;188 Table *htab = NULL;
201 int actual = L->top - base; /* actual number of arguments */189 StkId base, fixed;
202 if (actual < nfixargs) {190 if (actual < nfixargs) {
203 luaD_checkstack(L, nfixargs - actual);
204 for (; actual < nfixargs; ++actual)191 for (; actual < nfixargs; ++actual)
205 setnilvalue(L->top++);192 setnilvalue(L->top++);
206 }193 }
207 actual -= nfixargs; /* number of extra arguments */194 if (style != NEWSTYLEVARARG) { /* compatibility with old-style vararg */
208 htab = luaH_new(L, actual, 1); /* create `arg' table */195 int nvar = actual - nfixargs; /* number of extra arguments */
209 for (i=0; i<actual; i++) /* put extra arguments into `arg' table */196 htab = luaH_new(L, nvar, 1); /* create `arg' table */
210 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - actual + i);197 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
211 /* store counter in field `n' */198 setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - nvar + i);
212 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")),199 /* store counter in field `n' */
213 cast(lua_Number, actual));200 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")),
214 L->top -= actual; /* remove extra elements from the stack */201 cast(lua_Number, nvar));
215 sethvalue(L, L->top, htab);202 }
216 lua_assert(iswhite(obj2gco(htab)));203 /* move fixed parameters to final position */
217 incr_top(L);204 fixed = L->top - actual; /* first fixed argument */
205 base = L->top; /* final position of first argument */
206 for (i=0; i<nfixargs; i++) {
207 setobjs2s(L, L->top++, fixed+i);
208 setnilvalue(fixed+i);
209 }
210 /* add `arg' parameter */
211 if (htab) {
212 sethvalue(L, L->top++, htab);
213 lua_assert(iswhite(obj2gco(htab)));
214 }
215 return base;
218}216}
219 217
220 218
@@ -233,44 +231,60 @@ static StkId tryfuncTM (lua_State *L, StkId func) { · 12 unmodified lines
233}231}
234 232
235 233
236StkId luaD_precall (lua_State *L, StkId func) {234int luaD_precall (lua_State *L, StkId func, int nresults) {
237 LClosure *cl;235 LClosure *cl;
238 ptrdiff_t funcr = savestack(L, func);236 ptrdiff_t funcr;
239 if (!ttisfunction(func)) /* `func' is not a function? */237 if (!ttisfunction(func)) /* `func' is not a function? */
240 func = tryfuncTM(L, func); /* check the `function' tag method */238 func = tryfuncTM(L, func); /* check the `function' tag method */
239 funcr = savestack(L, func);
241 if (L->ci + 1 == L->end_ci) luaD_growCI(L);240 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
242 else condhardstacktests(luaD_reallocCI(L, L->size_ci));241 else condhardstacktests(luaD_reallocCI(L, L->size_ci));
243 cl = &clvalue(func)->l;242 cl = &clvalue(func)->l;
244 if (!cl->isC) { /* Lua function? prepare its call */243 if (!cl->isC) { /* Lua function? prepare its call */
245 CallInfo *ci;244 CallInfo *ci;
246 StkId st;245 StkId st, base;
247 Proto *p = cl->p;246 Proto *p = cl->p;
248 if (p->is_vararg) /* varargs? */
249 adjust_varargs(L, p->numparams, func+1);
250 luaD_checkstack(L, p->maxstacksize);247 luaD_checkstack(L, p->maxstacksize);
248 func = restorestack(L, funcr);
249 if (p->is_vararg) { /* varargs? */
250 int nargs = L->top - func - 1;
251 base = adjust_varargs(L, p->numparams, nargs, p->is_vararg);
252 }
253 else
254 base = func + 1;
251 ci = ++L->ci; /* now `enter' new function */255 ci = ++L->ci; /* now `enter' new function */
252 L->base = L->ci->base = restorestack(L, funcr) + 1;256 ci->func = func;
257 L->base = ci->base = base;
253 ci->top = L->base + p->maxstacksize;258 ci->top = L->base + p->maxstacksize;
254 ci->u.l.savedpc = p->code; /* starting point */259 ci->savedpc = p->code; /* starting point */
255 ci->u.l.tailcalls = 0;260 ci->tailcalls = 0;
261 ci->nresults = nresults;
256 for (st = L->top; st < ci->top; st++)262 for (st = L->top; st < ci->top; st++)
257 setnilvalue(st);263 setnilvalue(st);
258 L->top = ci->top;264 L->top = ci->top;
259 return NULL;265 return PCRLUA;
260 }266 }
261 else { /* if is a C function, call it */267 else { /* if is a C function, call it */
262 CallInfo *ci;268 CallInfo *ci;
263 int n;269 int n;
264 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */270 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
265 ci = ++L->ci; /* now `enter' new function */271 ci = ++L->ci; /* now `enter' new function */
266 L->base = L->ci->base = restorestack(L, funcr) + 1;272 ci->func = restorestack(L, funcr);
273 L->base = ci->base = ci->func + 1;
267 ci->top = L->top + LUA_MINSTACK;274 ci->top = L->top + LUA_MINSTACK;
268 if (L->hookmask & LUA_MASKCALL)275 if (L->hookmask & LUA_MASKCALL)
269 luaD_callhook(L, LUA_HOOKCALL, -1);276 luaD_callhook(L, LUA_HOOKCALL, -1);
270 lua_unlock(L);277 lua_unlock(L);
271 n = (*curr_func(L)->c.f)(L); /* do the actual call */278 n = (*curr_func(L)->c.f)(L); /* do the actual call */
272 lua_lock(L);279 lua_lock(L);
273 return L->top - n;280 if (n >= 0) { /* no yielding? */
281 luaD_poscall(L, nresults, L->top - n);
282 return PCRC;
283 }
284 else {
285 ci->nresults = nresults;
286 return PCRYIELD;
287 }
274 }288 }
275}289}
276 290
@@ -279,7 +293,7 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { · 2 unmodified lines
279 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */293 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
280 luaD_callhook(L, LUA_HOOKRET, -1);294 luaD_callhook(L, LUA_HOOKRET, -1);
281 if (f_isLua(L->ci)) { /* Lua function? */295 if (f_isLua(L->ci)) { /* Lua function? */
282 while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */296 while (L->ci->tailcalls--) /* call hook for eventual tail calls */
283 luaD_callhook(L, LUA_HOOKTAILRET, -1);297 luaD_callhook(L, LUA_HOOKTAILRET, -1);
284 }298 }
285 return restorestack(L, fr);299 return restorestack(L, fr);
@@ -290,7 +304,7 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { · 4 unmodified lines
290 StkId res;304 StkId res;
291 if (L->hookmask & LUA_MASKRET)305 if (L->hookmask & LUA_MASKRET)
292 firstResult = callrethooks(L, firstResult);306 firstResult = callrethooks(L, firstResult);
293 res = L->base - 1; /* res == final position of 1st result */307 res = L->ci->func; /* res == final position of 1st result */
294 L->ci--;308 L->ci--;
295 L->base = L->ci->base; /* restore base */309 L->base = L->ci->base; /* restore base */
296 /* move results to correct place */310 /* move results to correct place */
@@ -311,17 +325,16 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { · 14 unmodified lines
311** function position.325** function position.
312*/ 326*/
313void luaD_call (lua_State *L, StkId func, int nResults) {327void luaD_call (lua_State *L, StkId func, int nResults) {
314 StkId firstResult;
315 if (++L->nCcalls >= LUA_MAXCCALLS) {328 if (++L->nCcalls >= LUA_MAXCCALLS) {
316 if (L->nCcalls == LUA_MAXCCALLS)329 if (L->nCcalls == LUA_MAXCCALLS)
317 luaG_runerror(L, "C stack overflow");330 luaG_runerror(L, "C stack overflow");
318 else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))331 else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
319 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */332 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
320 }333 }
321 firstResult = luaD_precall(L, func);334 if (luaD_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */
322 if (firstResult == NULL) /* is a Lua function? */335 StkId firstResult = luaV_execute(L, 1); /* call it */
323 firstResult = luaV_execute(L, 1); /* call it */336 luaD_poscall(L, nResults, firstResult);
324 luaD_poscall(L, nResults, firstResult);337 }
325 L->nCcalls--;338 L->nCcalls--;
326 luaC_checkGC(L);339 luaC_checkGC(L);
327}340}
@@ -333,15 +346,14 @@ static void resume (lua_State *L, void *ud) { · 5 unmodified lines
333 CallInfo *ci = L->ci;346 CallInfo *ci = L->ci;
334 if (!L->isSuspended) {347 if (!L->isSuspended) {
335 lua_assert(ci == L->base_ci && nargs < L->top - L->base);348 lua_assert(ci == L->base_ci && nargs < L->top - L->base);
336 luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */349 luaD_precall(L, L->top - (nargs + 1), LUA_MULTRET); /* start coroutine */
337 }350 }
338 else { /* resuming from previous yield */351 else { /* resuming from previous yield */
339 if (!f_isLua(ci)) { /* `common' yield? */352 if (!f_isLua(ci)) { /* `common' yield? */
340 /* finish interrupted execution of `OP_CALL' */353 /* finish interrupted execution of `OP_CALL' */
341 int nresults;354 int nresults = ci->nresults;
342 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||355 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
343 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);356 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
344 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
345 luaD_poscall(L, nresults, L->top - nargs); /* complete it */357 luaD_poscall(L, nresults, L->top - nargs); /* complete it */
346 if (nresults >= 0) L->top = L->ci->top;358 if (nresults >= 0) L->top = L->ci->top;
347 } /* else yielded inside a hook: just continue its execution */359 } /* else yielded inside a hook: just continue its execution */
src/ldo.h+8−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldo.h,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: ldo.h,v 2.2 2004/05/14 19:25:09 roberto Exp $
3** Stack and Call structure of Lua3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -38,13 +38,19 @@ · 32 unmodified lines
38#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))38#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
39 39
40 40
41/* results from luaD_precall */
42#define PCRLUA 0 /* initiated a call to a Lua function */
43#define PCRC 1 /* did a call to a C function */
44#define PCRYIELD 2 /* C funtion yielded */
45
46
41/* type of protected functions, to be ran by `runprotected' */47/* type of protected functions, to be ran by `runprotected' */
42typedef void (*Pfunc) (lua_State *L, void *ud);48typedef void (*Pfunc) (lua_State *L, void *ud);
43 49
44void luaD_resetprotection (lua_State *L);50void luaD_resetprotection (lua_State *L);
45int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);51int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
46void luaD_callhook (lua_State *L, int event, int line);52void luaD_callhook (lua_State *L, int event, int line);
47StkId luaD_precall (lua_State *L, StkId func);53int luaD_precall (lua_State *L, StkId func, int nresults);
48void luaD_call (lua_State *L, StkId func, int nResults);54void luaD_call (lua_State *L, StkId func, int nResults);
49int luaD_pcall (lua_State *L, Pfunc func, void *u,55int luaD_pcall (lua_State *L, Pfunc func, void *u,
50 ptrdiff_t oldtop, ptrdiff_t ef);56 ptrdiff_t oldtop, ptrdiff_t ef);
src/ldump.c+18−12
@@ -1,12 +1,13 @@
1/*1/*
2** $Id: ldump.c,v 1.6 2004/03/24 00:25:08 lhf Exp $2** $Id: ldump.c,v 1.8 2004/09/01 21:22:34 lhf Exp $
3** save bytecodes3** save pre-compiled Lua chunks
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
6 6
7#include <stddef.h>7#include <stddef.h>
8 8
9#define ldump_c9#define ldump_c
10#define LUA_CORE
10 11
11#include "lua.h"12#include "lua.h"
12 13
@@ -20,16 +21,20 @@ · 7 unmodified lines
20 21
21typedef struct {22typedef struct {
22 lua_State* L;23 lua_State* L;
23 lua_Chunkwriter write;24 lua_Chunkwriter writer;
24 void* data;25 void* data;
25 int strip;26 int strip;
27 int status;
26} DumpState;28} DumpState;
27 29
28static void DumpBlock(const void* b, size_t size, DumpState* D)30static void DumpBlock(const void* b, size_t size, DumpState* D)
29{31{
30 lua_unlock(D->L);32 if (D->status==0)
31 (*D->write)(D->L,b,size,D->data);33 {
32 lua_lock(D->L);34 lua_unlock(D->L);
35 D->status=(*D->writer)(D->L,b,size,D->data);
36 lua_lock(D->L);
37 }
33}38}
34 39
35static void DumpByte(int y, DumpState* D)40static void DumpByte(int y, DumpState* D)
@@ -53,7 +58,7 @@ static void DumpNumber(lua_Number x, DumpState* D) · 17 unmodified lines
53 DumpBlock(&x,sizeof(x),D);58 DumpBlock(&x,sizeof(x),D);
54}59}
55 60
56static void DumpString(TString* s, DumpState* D)61static void DumpString(const TString* s, DumpState* D)
57{62{
58 if (s==NULL || getstr(s)==NULL)63 if (s==NULL || getstr(s)==NULL)
59 DumpSize(0,D);64 DumpSize(0,D);
@@ -153,16 +158,17 @@ static void DumpHeader(DumpState* D) · 93 unmodified lines
153}158}
154 159
155/*160/*
156** dump function as precompiled chunk161** dump Lua function as precompiled chunk
157*/162*/
158int luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data, int strip)163int luaU_dump (lua_State* L, const Proto* f, lua_Chunkwriter w, void* data, int strip)
159{164{
160 DumpState D;165 DumpState D;
161 D.L=L;166 D.L=L;
162 D.write=w;167 D.writer=w;
163 D.data=data;168 D.data=data;
164 D.strip=strip;169 D.strip=strip;
170 D.status=0;
165 DumpHeader(&D);171 DumpHeader(&D);
166 DumpFunction(Main,NULL,&D);172 DumpFunction(f,NULL,&D);
167 return 1;173 return D.status;
168}174}
src/lfunc.c+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lfunc.c,v 2.3 2004/03/15 21:04:33 roberto Exp $2** $Id: lfunc.c,v 2.4 2004/04/30 20:13:38 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <stddef.h>8#include <stddef.h>
9 9
10#define lfunc_c10#define lfunc_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
src/lgc.c+173−137
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lgc.c,v 2.6 2004/03/23 12:57:12 roberto Exp $2** $Id: lgc.c,v 2.10 2004/08/30 13:44:44 roberto Exp $
3** Garbage Collector3** Garbage Collector
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -7,6 +7,7 @@ · 1 unmodified line
7#include <string.h>7#include <string.h>
8 8
9#define lgc_c9#define lgc_c
10#define LUA_CORE
10 11
11#include "lua.h"12#include "lua.h"
12 13
@@ -22,10 +23,11 @@ · 9 unmodified lines
22#include "ltm.h"23#include "ltm.h"
23 24
24 25
25#define GCSTEPSIZE (40*sizeof(TValue))26#define GCSTEPSIZE 1000
26#define GCFREECOST (sizeof(TValue)/2)27#define STEPMUL 2
27#define GCSWEEPCOST sizeof(TValue)28#define GCSWEEPMAX 10
28#define GCFINALIZECOST (10*sizeof(TValue))29#define GCSWEEPCOST 30
30#define GCFINALIZECOST 100
29 31
30 32
31#define FIXEDMASK bitmask(FIXEDBIT)33#define FIXEDMASK bitmask(FIXEDBIT)
@@ -266,60 +268,61 @@ static void traversestack (global_State *g, lua_State *l) { · 234 unmodified lines
266 268
267 269
268/*270/*
269** traverse a given `quantity' of gray objects,271** traverse one gray object, turning it to black.
270** turning them to black. Returns extra `quantity' traversed.272** Returns `quantity' traversed.
271*/273*/
272static l_mem propagatemarks (global_State *g, l_mem lim) {274static l_mem propagatemark (global_State *g) {
273 GCObject *o;275 GCObject *o = g->gray;
274 while ((o = g->gray) != NULL) {276 lua_assert(isgray(o));
275 lua_assert(isgray(o));277 gray2black(o);
276 gray2black(o);278 switch (o->gch.tt) {
277 switch (o->gch.tt) {279 case LUA_TTABLE: {
278 case LUA_TTABLE: {280 Table *h = gco2h(o);
279 Table *h = gco2h(o);281 g->gray = h->gclist;
280 g->gray = h->gclist;282 if (traversetable(g, h)) /* table is weak? */
281 if (traversetable(g, h)) /* table is weak? */283 black2gray(o); /* keep it gray */
282 black2gray(o); /* keep it gray */284 return sizeof(Table) + sizeof(TValue) * h->sizearray +
283 lim -= sizeof(Table) + sizeof(TValue) * h->sizearray +285 sizeof(Node) * sizenode(h);
284 sizeof(Node) * sizenode(h);286 break;
285 break;287 }
286 }288 case LUA_TFUNCTION: {
287 case LUA_TFUNCTION: {289 Closure *cl = gco2cl(o);
288 Closure *cl = gco2cl(o);290 g->gray = cl->c.gclist;
289 g->gray = cl->c.gclist;291 traverseclosure(g, cl);
290 traverseclosure(g, cl);292 return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
291 lim -= (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :293 sizeLclosure(cl->l.nupvalues);
292 sizeLclosure(cl->l.nupvalues);294 break;
293 break;295 }
294 }296 case LUA_TTHREAD: {
295 case LUA_TTHREAD: {297 lua_State *th = gco2th(o);
296 lua_State *th = gco2th(o);298 g->gray = th->gclist;
297 g->gray = th->gclist;299 th->gclist = g->grayagain;
298 th->gclist = g->grayagain;300 g->grayagain = o;
299 g->grayagain = o;301 black2gray(o);
300 black2gray(o);302 traversestack(g, th);
301 traversestack(g, th);303 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
302 lim -= sizeof(lua_State) + sizeof(TValue) * th->stacksize +304 sizeof(CallInfo) * th->size_ci;
303 sizeof(CallInfo) * th->size_ci;305 break;
304 break;306 }
305 }307 case LUA_TPROTO: {
306 case LUA_TPROTO: {308 Proto *p = gco2p(o);
307 Proto *p = gco2p(o);309 g->gray = p->gclist;
308 g->gray = p->gclist;310 traverseproto(g, p);
309 traverseproto(g, p);311 return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
310 lim -= sizeof(Proto) + sizeof(Instruction) * p->sizecode +312 sizeof(Proto *) * p->sizep +
311 sizeof(Proto *) * p->sizep +313 sizeof(TValue) * p->sizek +
312 sizeof(TValue) * p->sizek + 314 sizeof(int) * p->sizelineinfo +
313 sizeof(int) * p->sizelineinfo +315 sizeof(LocVar) * p->sizelocvars +
314 sizeof(LocVar) * p->sizelocvars +316 sizeof(TString *) * p->sizeupvalues;
315 sizeof(TString *) * p->sizeupvalues;317 break;
316 break;
317 }
318 default: lua_assert(0);
319 }318 }
320 if (lim <= 0) return lim;319 default: lua_assert(0); return 0;
321 }320 }
322 return lim;321}
322
323
324static void propagateall (global_State *g) {
325 while (g->gray) propagatemark(g);
323}326}
324 327
325 328
@@ -381,6 +384,7 @@ static void freeobj (lua_State *L, GCObject *o) { · 55 unmodified lines
381 break;384 break;
382 }385 }
383 case LUA_TSTRING: {386 case LUA_TSTRING: {
387 G(L)->strt.nuse--;
384 luaM_free(L, o, sizestring(gco2ts(o)->len));388 luaM_free(L, o, sizestring(gco2ts(o)->len));
385 break;389 break;
386 }390 }
@@ -393,59 +397,45 @@ static void freeobj (lua_State *L, GCObject *o) { · 6 unmodified lines
393}397}
394 398
395 399
396static l_mem sweepwholelist (lua_State *L, GCObject **p, int keepfixed,400
397 lu_int32 *count);401#define sweepwholelist(L,p) sweeplist(L,p,LUA_MAXINT32)
398 402
399 403
400static GCObject **sweeplist (lua_State *L, GCObject **p, int keepfixed,404static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
401 l_mem *plim, lu_int32 *count) {
402 GCObject *curr;405 GCObject *curr;
403 global_State *g = G(L);406 global_State *g = G(L);
404 l_mem lim = *plim;407 int whitebit = otherwhite(g);
405 int deadmask = otherwhite(g);408 int deadmask = whitebit | FIXEDMASK;
406 if (keepfixed) deadmask |= FIXEDMASK;409 int generational = g->gcgenerational;
407 while ((curr = *p) != NULL) {410 while ((curr = *p) != NULL && count-- > 0) {
408 if (((curr->gch.marked ^ FIXEDMASK) & deadmask) != deadmask) {411 if ((curr->gch.marked ^ whitebit) & deadmask) {
409 makewhite(g, curr);412 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
413 if (!generational || isdead(g, curr))
414 makewhite(g, curr);
410 if (curr->gch.tt == LUA_TTHREAD)415 if (curr->gch.tt == LUA_TTHREAD)
411 lim -= sweepwholelist(L, &gco2th(curr)->openupval, keepfixed, count);416 sweepwholelist(L, &gco2th(curr)->openupval);
412 p = &curr->gch.next;417 p = &curr->gch.next;
413 lim -= GCSWEEPCOST;
414 }418 }
415 else {419 else {
416 lua_assert(iswhite(curr));420 lua_assert(isdead(g, curr));
417 *p = curr->gch.next;421 *p = curr->gch.next;
418 if (curr == g->rootgc) /* is the first element of the list? */422 if (curr == g->rootgc) /* is the first element of the list? */
419 g->rootgc = curr->gch.next; /* adjust first */423 g->rootgc = curr->gch.next; /* adjust first */
420 freeobj(L, curr);424 freeobj(L, curr);
421 lim -= GCFREECOST;
422 if (count) (*count)--;
423 }425 }
424 if (lim <= 0) break;
425 }426 }
426 *plim = lim;
427 return p;427 return p;
428}428}
429 429
430 430
431static l_mem sweepwholelist (lua_State *L, GCObject **p, int keepfixed,
432 lu_int32 *count) {
433 l_mem lim = MAXLMEM;
434 /* empty lists are quite common here, so avoid useless calls */
435 if (*p) sweeplist(L, p, keepfixed, &lim, count);
436 return MAXLMEM - lim;
437}
438
439 431
440static l_mem sweepstrings (lua_State *L, int keepfixed, l_mem lim) {432static void freelist (lua_State *L, GCObject **p) {
441 int i;433 while (*p) {
442 global_State *g = G(L);434 GCObject *curr = *p;
443 for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */435 *p = (*p)->gch.next;
444 lim -= sweepwholelist(L, &G(L)->strt.hash[i], keepfixed, &g->strt.nuse);436 if (curr != obj2gco(L))
445 if (lim <= 0) break;437 freeobj(L, curr);
446 }438 }
447 g->sweepstrgc = i+1;
448 return lim;
449}439}
450 440
451 441
@@ -494,19 +484,12 @@ void luaC_callGCTM (lua_State *L) { · 42 unmodified lines
494}484}
495 485
496 486
497void luaC_sweepall (lua_State *L) {487void luaC_freeall (lua_State *L) {
498 global_State *g = G(L);488 global_State *g = G(L);
499 l_mem dummy = MAXLMEM;489 int i;
500 /* finish (occasional) current sweep */490 freelist(L, &g->rootgc);
501 sweepstrings(L, 0, MAXLMEM);491 for (i = 0; i < g->strt.size; i++) /* free all string lists */
502 sweeplist(L, &g->rootgc, 0, &dummy, NULL);492 freelist(L, &G(L)->strt.hash[i]);
503 /* do a whole new sweep */
504 markobject(g, g->mainthread); /* cannot collect main thread */
505 g->currentwhite = otherwhite(g);
506 g->sweepgc = &g->rootgc;
507 g->sweepstrgc = 0;
508 sweepstrings(L, 0, MAXLMEM);
509 sweeplist(L, &g->rootgc, 0, &dummy, NULL);
510}493}
511 494
512 495
@@ -530,8 +513,10 @@ static void remarkupvals (global_State *g) { · 17 unmodified lines
530 if (iswhite(o)) {513 if (iswhite(o)) {
531 GCObject *curr;514 GCObject *curr;
532 for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) {515 for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) {
533 if (isgray(curr))516 if (isgray(curr)) {
534 markvalue(g, gco2uv(curr)->v);517 UpVal *uv = gco2uv(curr);
518 markvalue(g, uv->v);
519 }
535 }520 }
536 }521 }
537 }522 }
@@ -540,6 +525,7 @@ static void remarkupvals (global_State *g) { · 2 unmodified lines
540 525
541static void atomic (lua_State *L) {526static void atomic (lua_State *L) {
542 global_State *g = G(L);527 global_State *g = G(L);
528 int aux;
543 lua_assert(g->gray == NULL);529 lua_assert(g->gray == NULL);
544 /* remark occasional upvalues of (maybe) dead threads */530 /* remark occasional upvalues of (maybe) dead threads */
545 remarkupvals(g);531 remarkupvals(g);
@@ -548,90 +534,130 @@ static void atomic (lua_State *L) { · 2 unmodified lines
548 g->weak = NULL;534 g->weak = NULL;
549 lua_assert(!iswhite(obj2gco(g->mainthread)));535 lua_assert(!iswhite(obj2gco(g->mainthread)));
550 markobject(g, L); /* mark running thread */536 markobject(g, L); /* mark running thread */
551 propagatemarks(g, MAXLMEM);537 propagateall(g);
552 /* remark gray again */538 /* remark gray again */
553 g->gray = g->grayagain;539 g->gray = g->grayagain;
554 g->grayagain = NULL;540 g->grayagain = NULL;
555 propagatemarks(g, MAXLMEM);541 propagateall(g);
556 luaC_separateudata(L, 0); /* separate userdata to be preserved */542 luaC_separateudata(L, 0); /* separate userdata to be preserved */
557 marktmu(g); /* mark `preserved' userdata */543 marktmu(g); /* mark `preserved' userdata */
558 propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */544 propagateall(g); /* remark, to propagate `preserveness' */
559 cleartable(g->weak); /* remove collected objects from weak tables */545 cleartable(g->weak); /* remove collected objects from weak tables */
560 /* flip current white */546 /* flip current white */
561 g->currentwhite = otherwhite(g);547 g->currentwhite = otherwhite(g);
548 g->sweepstrgc = 0;
549 g->sweepgc = &g->rootgc;
562 g->gcstate = GCSsweepstring;550 g->gcstate = GCSsweepstring;
551 aux = g->gcgenerational;
552 g->gcgenerational = (g->estimate <= 4*g->prevestimate/2);
553 if (!aux) /* last collection was full? */
554 g->prevestimate = g->estimate; /* keep estimate of last full collection */
555 g->estimate = g->totalbytes; /* first estimate */
563}556}
564 557
565 558
566static l_mem singlestep (lua_State *L, l_mem lim) {559static l_mem singlestep (lua_State *L) {
567 global_State *g = G(L);560 global_State *g = G(L);
561 /*lua_checkmemory(L);*/
568 switch (g->gcstate) {562 switch (g->gcstate) {
563 case GCSpause: {
564 /* start a new collection */
565 if (g->gcgenerational)
566 atomic(L);
567 else
568 markroot(L);
569 return 0;
570 }
569 case GCSpropagate: {571 case GCSpropagate: {
570 if (g->gray)572 if (g->gray)
571 lim = propagatemarks(g, lim);573 return propagatemark(g);
572 else { /* no more `gray' objects */574 else { /* no more `gray' objects */
573 atomic(L); /* finish mark phase */575 atomic(L); /* finish mark phase */
574 lim = 0;576 return 0;
575 }577 }
576 break;
577 }578 }
578 case GCSsweepstring: {579 case GCSsweepstring: {
579 lim = sweepstrings(L, 1, lim);580 lu_mem old = g->totalbytes;
580 if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */581 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
581 g->sweepstrgc = 0;582 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
582 g->gcstate = GCSsweep; /* end sweep-string phase */583 g->gcstate = GCSsweep; /* end sweep-string phase */
583 }584 g->estimate -= old - g->totalbytes;
584 break;585 return GCSWEEPCOST;
585 }586 }
586 case GCSsweep: {587 case GCSsweep: {
587 g->sweepgc = sweeplist(L, g->sweepgc, 1, &lim, NULL);588 lu_mem old = g->totalbytes;
589 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
588 if (*g->sweepgc == NULL) { /* nothing more to sweep? */590 if (*g->sweepgc == NULL) { /* nothing more to sweep? */
589 checkSizes(L);591 checkSizes(L);
590 g->sweepgc = &g->rootgc;
591 g->gcstate = GCSfinalize; /* end sweep phase */592 g->gcstate = GCSfinalize; /* end sweep phase */
592 }593 }
593 break;594 g->estimate -= old - g->totalbytes;
595 return GCSWEEPMAX*GCSWEEPCOST;
594 }596 }
595 case GCSfinalize: {597 case GCSfinalize: {
596 if (g->tmudata) {598 if (g->tmudata) {
597 GCTM(L);599 GCTM(L);
598 lim -= GCFINALIZECOST;600 return GCFINALIZECOST;
599 }601 }
600 else { /* no more `udata' to finalize */602 else {
601 markroot(L); /* may restart collection */603 g->gcstate = GCSpause; /* end collection */
602 lim = 0;604 return 0;
603 }605 }
604 break;
605 }606 }
606 default: lua_assert(0);607 default: lua_assert(0); return 0;
607 }608 }
608 return lim;
609}609}
610 610
611 611
612void luaC_step (lua_State *L) {612void luaC_step (lua_State *L) {
613 global_State *g = G(L);613 global_State *g = G(L);
614 l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2;614 l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * STEPMUL;
615/*printf("step(%c): ", g->gcgenerational?'g':' ');*/
615 do {616 do {
616 lim = singlestep(L, lim);617 /*printf("%c", "_pswf"[g->gcstate]);*/
617 if (g->gcstate == GCSfinalize && g->tmudata == NULL)618 lim -= singlestep(L);
618 break; /* do not start new collection */619 if (g->gcstate == GCSpause)
620 break;
619 } while (lim > 0);621 } while (lim > 0);
620 g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2;622/*printf("\n");*/
621 lua_assert((long)g->nblocks + (long)GCSTEPSIZE >= lim/2);623 if (g->gcstate != GCSpause)
624 g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */
625 else {
626/*printf("---\n");*/
627 lua_assert(g->totalbytes >= g->estimate);
628 g->GCthreshold = 2*g->estimate;
629 if (g->GCthreshold < g->totalbytes + GCSTEPSIZE)
630 g->GCthreshold = g->totalbytes + GCSTEPSIZE;
631 }
622}632}
623 633
624 634
625void luaC_fullgc (lua_State *L) {635void luaC_fullgc (lua_State *L) {
626 global_State *g = G(L);636 global_State *g = G(L);
637 if (g->gcstate <= GCSpropagate || g->gcgenerational) {
638 g->gcgenerational = 0;
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 /* finish any pending sweep phase */
627 while (g->gcstate != GCSfinalize) {649 while (g->gcstate != GCSfinalize) {
628 singlestep(L, MAXLMEM);650 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
651 singlestep(L);
629 }652 }
630 markroot(L);653 markroot(L);
654 lua_assert(!g->gcgenerational);
631 while (g->gcstate != GCSfinalize) {655 while (g->gcstate != GCSfinalize) {
632 singlestep(L, MAXLMEM);656 singlestep(L);
657 g->gcgenerational = 0; /* keep it in this mode */
633 }658 }
634 g->GCthreshold = g->nblocks + GCSTEPSIZE;659 lua_assert(g->estimate == g->totalbytes);
660 g->GCthreshold = 2*g->estimate;
635 luaC_callGCTM(L); /* call finalizers */661 luaC_callGCTM(L); /* call finalizers */
636}662}
637 663
@@ -639,7 +665,7 @@ void luaC_fullgc (lua_State *L) { · 1 unmodified line
639void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {665void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
640 global_State *g = G(L);666 global_State *g = G(L);
641 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));667 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
642 lua_assert(g->gcstate != GCSfinalize);668 lua_assert(g->gcgenerational || g->gcstate != GCSfinalize);
643 if (g->gcstate != GCSpropagate) /* sweeping phases? */669 if (g->gcstate != GCSpropagate) /* sweeping phases? */
644 black2gray(o); /* just mark as gray to avoid other barriers */670 black2gray(o); /* just mark as gray to avoid other barriers */
645 else /* breaking invariant! */671 else /* breaking invariant! */
@@ -647,6 +673,16 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { · 1 unmodified line
647}673}
648 674
649 675
676void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) {
677 global_State *g = G(L);
678 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
679 lua_assert(g->gcgenerational || g->gcstate != GCSfinalize);
680 black2gray(o); /* make table gray (again) */
681 gco2h(o)->gclist = g->grayagain;
682 g->grayagain = o;
683}
684
685
650void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {686void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
651 global_State *g = G(L);687 global_State *g = G(L);
652 o->gch.next = g->rootgc;688 o->gch.next = g->rootgc;
@@ -662,13 +698,13 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { · 9 unmodified lines
662 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */698 o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
663 g->rootgc = o;699 g->rootgc = o;
664 if (isgray(o)) { 700 if (isgray(o)) {
665 if (g->gcstate == GCSpropagate) {701 if (g->gcstate == GCSpropagate || g->gcgenerational) {
666 gray2black(o); /* closed upvalues need barrier */702 gray2black(o); /* closed upvalues need barrier */
667 luaC_barrier(L, uv, uv->v);703 luaC_barrier(L, uv, uv->v);
668 }704 }
669 else { /* sweep phase: sweep it (turning it into white) */705 else { /* sweep phase: sweep it (turning it into white) */
670 makewhite(g, o);706 makewhite(g, o);
671 lua_assert(g->gcstate != GCSfinalize);707 lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
672 }708 }
673 }709 }
674}710}
src/lgc.h+19−13
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lgc.h,v 2.5 2004/03/15 21:04:33 roberto Exp $2** $Id: lgc.h,v 2.8 2004/08/30 13:44:44 roberto Exp $
3** Garbage Collector3** Garbage Collector
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -14,10 +14,11 @@ · 8 unmodified lines
14/*14/*
15** Possible states of the Garbage Collector15** Possible states of the Garbage Collector
16*/16*/
17#define GCSpropagate 017#define GCSpause 0
18#define GCSsweepstring 118#define GCSpropagate 1
19#define GCSsweep 219#define GCSsweepstring 2
20#define GCSfinalize 320#define GCSsweep 3
21#define GCSfinalize 4
21 22
22 23
23/*24/*
@@ -39,12 +40,13 @@ · 15 unmodified lines
39 40
40/*41/*
41** Layout for bit use in `marked' field:42** Layout for bit use in `marked' field:
42** bit 0 - object is gray43** bit 0 - object is white (type 0)
43** bit 1 - object is black44** bit 1 - object is white (type 1)
44** bit 2 - For userdata: is finalized;45** bit 2 - object is black
45 for tables: has weak keys46** bit 3 - for userdata: has been finalized
46** bit 3 - for tables: has weak values47** bit 3 - for tables: has weak keys
47** bit 4 - object is fixed (should not be collected)48** bit 4 - for tables: has weak values
49** bit 5 - object is fixed (should not be collected)
48*/50*/
49 51
50#define WHITE0BIT 052#define WHITE0BIT 0
@@ -70,25 +72,29 @@ · 19 unmodified lines
70#define luaC_white(g) cast(lu_byte, (g)->currentwhite)72#define luaC_white(g) cast(lu_byte, (g)->currentwhite)
71 73
72 74
73#define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \75#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
74 luaC_step(L); }76 luaC_step(L); }
75 77
76 78
77#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \79#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
78 luaC_barrierf(L,obj2gco(p),gcvalue(v)); }80 luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
79 81
82#define luaC_barriert(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
83 luaC_barrierback(L,obj2gco(p),gcvalue(v)); }
84
80#define luaC_objbarrier(L,p,o) \85#define luaC_objbarrier(L,p,o) \
81 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \86 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
82 luaC_barrierf(L,obj2gco(p),obj2gco(o)); }87 luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
83 88
84size_t luaC_separateudata (lua_State *L, int all);89size_t luaC_separateudata (lua_State *L, int all);
85void luaC_callGCTM (lua_State *L);90void luaC_callGCTM (lua_State *L);
86void luaC_sweepall (lua_State *L);91void luaC_freeall (lua_State *L);
87void luaC_step (lua_State *L);92void luaC_step (lua_State *L);
88void luaC_fullgc (lua_State *L);93void luaC_fullgc (lua_State *L);
89void luaC_link (lua_State *L, GCObject *o, lu_byte tt);94void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
90void luaC_linkupval (lua_State *L, UpVal *uv);95void luaC_linkupval (lua_State *L, UpVal *uv);
91void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);96void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
97void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v);
92 98
93 99
94#endif100#endif
src/lib/Makefile+2−2
@@ -6,8 +6,8 @@ include $(LUA)/config · 5 unmodified lines
6 6
7EXTRA_DEFS= $(POPEN) $(TMPNAM) $(DEGREES) $(LOADLIB)7EXTRA_DEFS= $(POPEN) $(TMPNAM) $(DEGREES) $(LOADLIB)
8 8
9OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o ltablib.o lstrlib.o loadlib.o9OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o loadlib.o linit.o
10SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c ltablib.c lstrlib.c loadlib.c10SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c ltablib.c lstrlib.c loadlib.c linit.c
11 11
12T= $(LIB)/liblualib.a12T= $(LIB)/liblualib.a
13 13
src/lib/RCS+0−1
@@ -1 +0,0 @@
1../RCS
src/lib/lauxlib.c+96−63
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lauxlib.c,v 1.110 2004/03/23 16:38:43 roberto Exp $2** $Id: lauxlib.c,v 1.123 2004/08/30 18:35:14 roberto Exp $
3** Auxiliary functions for building Lua libraries3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -18,6 +18,7 @@ · 12 unmodified lines
18*/18*/
19 19
20#define lauxlib_c20#define lauxlib_c
21#define LUA_LIB
21 22
22#include "lua.h"23#include "lua.h"
23 24
@@ -62,7 +63,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { · 38 unmodified lines
62 63
63LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {64LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
64 const char *msg = lua_pushfstring(L, "%s expected, got %s",65 const char *msg = lua_pushfstring(L, "%s expected, got %s",
65 tname, lua_typename(L, lua_type(L,narg)));66 tname, luaL_typename(L, narg));
66 return luaL_argerror(L, narg, msg);67 return luaL_argerror(L, narg, msg);
67}68}
68 69
@@ -242,6 +243,8 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, · 173 unmodified lines
242 if (lua_isnil(L, -1)) { /* no? */243 if (lua_isnil(L, -1)) { /* no? */
243 lua_pop(L, 1);244 lua_pop(L, 1);
244 lua_newtable(L); /* create it */245 lua_newtable(L); /* create it */
246 if (lua_getmetatable(L, LUA_GLOBALSINDEX))
247 lua_setmetatable(L, -2); /* share metatable with global table */
245 lua_pushvalue(L, -1);248 lua_pushvalue(L, -1);
246 /* register it with given name */249 /* register it with given name */
247 lua_setglobal(L, libname);250 lua_setglobal(L, libname);
@@ -288,7 +291,7 @@ static void getsizes (lua_State *L) { · 40 unmodified lines
288}291}
289 292
290 293
291void luaL_setn (lua_State *L, int t, int n) {294LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
292 t = abs_index(L, t);295 t = abs_index(L, t);
293 getsizes(L);296 getsizes(L);
294 lua_pushvalue(L, t);297 lua_pushvalue(L, t);
@@ -298,7 +301,32 @@ void luaL_setn (lua_State *L, int t, int n) { · 3 unmodified lines
298}301}
299 302
300 303
301int luaL_getn (lua_State *L, int t) {304/* find an `n' such that t[n] ~= nil and t[n+1] == nil */
305static int countn (lua_State *L, int t) {
306 int i = LUA_FIRSTINDEX - 1;
307 int j = 2;
308 /* find `i' such that i <= n < i*2 (= j) */
309 for (;;) {
310 lua_rawgeti(L, t, j);
311 if (lua_isnil(L, -1)) break;
312 lua_pop(L, 1);
313 i = j;
314 j = i*2;
315 }
316 lua_pop(L, 1);
317 /* i <= n < j; do a binary search */
318 while (i < j-1) {
319 int m = (i+j)/2;
320 lua_rawgeti(L, t, m);
321 if (lua_isnil(L, -1)) j = m;
322 else i = m;
323 lua_pop(L, 1);
324 }
325 return i - LUA_FIRSTINDEX + 1;
326}
327
328
329LUALIB_API int luaL_getn (lua_State *L, int t) {
302 int n;330 int n;
303 t = abs_index(L, t);331 t = abs_index(L, t);
304 getsizes(L); /* try sizes[t] */332 getsizes(L); /* try sizes[t] */
@@ -307,18 +335,61 @@ int luaL_getn (lua_State *L, int t) { · 2 unmodified lines
307 if ((n = checkint(L, 2)) >= 0) return n;335 if ((n = checkint(L, 2)) >= 0) return n;
308 lua_getfield(L, t, "n"); /* else try t.n */336 lua_getfield(L, t, "n"); /* else try t.n */
309 if ((n = checkint(L, 1)) >= 0) return n;337 if ((n = checkint(L, 1)) >= 0) return n;
310 for (n = 1; ; n++) { /* else must count elements */338 return countn(L, t);
311 lua_rawgeti(L, t, n);
312 if (lua_isnil(L, -1)) break;
313 lua_pop(L, 1);
314 }
315 lua_pop(L, 1);
316 return n - 1;
317}339}
318 340
319/* }====================================================== */341/* }====================================================== */
320 342
321 343
344static const char *pushnexttemplate (lua_State *L, const char *path) {
345 const char *l;
346 if (*path == '\0') return NULL; /* no more templates */
347 if (*path == LUA_PATH_SEP) path++; /* skip separator */
348 l = strchr(path, LUA_PATH_SEP); /* find next separator */
349 if (l == NULL) l = path+strlen(path);
350 lua_pushlstring(L, path, l - path); /* template */
351 return l;
352}
353
354
355static const char *luaL_gsub (lua_State *L, const char *s,
356 const char *p, const char *r) {
357 const char *wild;
358 int l = strlen(p);
359 luaL_Buffer b;
360 luaL_buffinit(L, &b);
361 while ((wild = strstr(s, p)) != NULL) {
362 luaL_addlstring(&b, s, wild - s); /* push prefix */
363 luaL_addstring(&b, r); /* push replacement in place of pattern */
364 s = wild + l; /* continue after `p' */
365 }
366 luaL_addstring(&b, s); /* push last suffix (`n' already includes this) */
367 luaL_pushresult(&b);
368 return lua_tostring(L, -1);
369}
370
371
372LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name,
373 const char *path) {
374 FILE *f;
375 const char *p = path;
376 for (;;) {
377 const char *fname;
378 if ((p = pushnexttemplate(L, p)) == NULL) {
379 lua_pushfstring(L, "no readable `%s' in path `%s'", name, path);
380 return NULL;
381 }
382 fname = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
383 lua_remove(L, -2); /* remove path template */
384 f = fopen(fname, "r"); /* try to read it */
385 if (f) {
386 fclose(f);
387 return fname;
388 }
389 lua_pop(L, 1); /* remove file name */
390 }
391}
392
322 393
323/*394/*
324** {======================================================395** {======================================================
@@ -480,9 +551,10 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { · 155 unmodified lines
480}551}
481 552
482 553
483static int errfile (lua_State *L, int fnameindex) {554static int errfile (lua_State *L, const char *what, int fnameindex) {
555 const char *serr = strerror(errno);
484 const char *filename = lua_tostring(L, fnameindex) + 1;556 const char *filename = lua_tostring(L, fnameindex) + 1;
485 lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno));557 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
486 lua_remove(L, fnameindex);558 lua_remove(L, fnameindex);
487 return LUA_ERRFILE;559 return LUA_ERRFILE;
488}560}
@@ -501,7 +573,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { · 12 unmodified lines
501 else {573 else {
502 lua_pushfstring(L, "@%s", filename);574 lua_pushfstring(L, "@%s", filename);
503 lf.f = fopen(filename, "r");575 lf.f = fopen(filename, "r");
504 if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */576 if (lf.f == NULL) return errfile(L, "open", fnameindex);
505 }577 }
506 c = getc(lf.f);578 c = getc(lf.f);
507 if (c == '#') { /* Unix exec. file? */579 if (c == '#') { /* Unix exec. file? */
@@ -512,7 +584,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { · 4 unmodified lines
512 if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */584 if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */
513 fclose(lf.f);585 fclose(lf.f);
514 lf.f = fopen(filename, "rb"); /* reopen in binary mode */586 lf.f = fopen(filename, "rb"); /* reopen in binary mode */
515 if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */587 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
516 /* skip eventual `#!...' */588 /* skip eventual `#!...' */
517 while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;589 while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
518 lf.extraline = 0;590 lf.extraline = 0;
@@ -523,7 +595,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { · 4 unmodified lines
523 if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */595 if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
524 if (readstatus) {596 if (readstatus) {
525 lua_settop(L, fnameindex); /* ignore results from `lua_load' */597 lua_settop(L, fnameindex); /* ignore results from `lua_load' */
526 return errfile(L, fnameindex);598 return errfile(L, "read", fnameindex);
527 }599 }
528 lua_remove(L, fnameindex);600 lua_remove(L, fnameindex);
529 return status;601 return status;
@@ -554,6 +626,7 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, · 24 unmodified lines
554 return lua_load(L, getS, &ls, name);626 return lua_load(L, getS, &ls, name);
555}627}
556 628
629
557/* }====================================================== */630/* }====================================================== */
558 631
559 632
@@ -568,55 +641,15 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { · 8 unmodified lines
568}641}
569 642
570 643
571LUALIB_API lua_State *luaL_newstate (void) {644static int panic (lua_State *L) {
572 return lua_newstate(l_alloc, NULL);645 fprintf(stderr, "PANIC: unprotected error during Lua-API call\n");
573}646 return 0;
574
575
576/*
577** {======================================================
578** compatibility code
579** =======================================================
580*/
581
582
583static void callalert (lua_State *L, int status) {
584 if (status != 0) {
585 lua_getglobal(L, "_ALERT");
586 if (lua_isfunction(L, -1)) {
587 lua_insert(L, -2);
588 lua_call(L, 1, 0);
589 }
590 else { /* no _ALERT function; print it on stderr */
591 fprintf(stderr, "%s\n", lua_tostring(L, -2));
592 lua_pop(L, 2); /* remove error message and _ALERT */
593 }
594 }
595}647}
596 648
597 649
598static int aux_do (lua_State *L, int status) {650LUALIB_API lua_State *luaL_newstate (void) {
599 if (status == 0) { /* parse OK? */651 lua_State *L = lua_newstate(l_alloc, NULL);
600 status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */652 lua_atpanic(L, &panic);
601 }653 return L;
602 callalert(L, status);
603 return status;
604}
605
606
607LUALIB_API int lua_dofile (lua_State *L, const char *filename) {
608 return aux_do(L, luaL_loadfile(L, filename));
609}
610
611
612LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
613 const char *name) {
614 return aux_do(L, luaL_loadbuffer(L, buff, size, name));
615}
616
617
618LUALIB_API int lua_dostring (lua_State *L, const char *str) {
619 return lua_dobuffer(L, str, strlen(str), str);
620}654}
621 655
622/* }====================================================== */
src/lib/lbaselib.c+120−176
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lbaselib.c,v 1.140 2004/03/09 17:34:35 roberto Exp $2** $Id: lbaselib.c,v 1.156 2004/08/30 18:35:14 roberto Exp $
3** Basic library3** Basic library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -12,6 +12,7 @@ · 6 unmodified lines
12#include <string.h>12#include <string.h>
13 13
14#define lbaselib_c14#define lbaselib_c
15#define LUA_LIB
15 16
16#include "lua.h"17#include "lua.h"
17 18
@@ -128,18 +129,9 @@ static void getfunc (lua_State *L) { · 110 unmodified lines
128}129}
129 130
130 131
131static int aux_getfenv (lua_State *L) {
132 lua_getfenv(L, -1);
133 lua_pushliteral(L, "__fenv");
134 lua_rawget(L, -2);
135 return !lua_isnil(L, -1);
136}
137
138
139static int luaB_getfenv (lua_State *L) {132static int luaB_getfenv (lua_State *L) {
140 getfunc(L);133 getfunc(L);
141 if (!aux_getfenv(L)) /* __fenv not defined? */134 lua_getfenv(L, -1);
142 lua_pop(L, 1); /* remove it, to return real environment */
143 return 1;135 return 1;
144}136}
145 137
@@ -147,16 +139,14 @@ static int luaB_getfenv (lua_State *L) { · 1 unmodified line
147static int luaB_setfenv (lua_State *L) {139static int luaB_setfenv (lua_State *L) {
148 luaL_checktype(L, 2, LUA_TTABLE);140 luaL_checktype(L, 2, LUA_TTABLE);
149 getfunc(L);141 getfunc(L);
150 if (aux_getfenv(L)) /* __fenv defined? */
151 luaL_error(L, "`setfenv' cannot change a protected environment");
152 else
153 lua_pop(L, 2); /* remove __fenv and real environment table */
154 lua_pushvalue(L, 2);142 lua_pushvalue(L, 2);
155 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)143 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
156 lua_replace(L, LUA_GLOBALSINDEX);144 lua_replace(L, LUA_GLOBALSINDEX);
145 return 0;
146 }
157 else if (lua_setfenv(L, -2) == 0)147 else if (lua_setfenv(L, -2) == 0)
158 luaL_error(L, "`setfenv' cannot change environment of given function");148 luaL_error(L, "`setfenv' cannot change environment of given function");
159 return 0;149 return 1;
160}150}
161 151
162 152
@@ -192,22 +182,11 @@ static int luaB_gcinfo (lua_State *L) { · 29 unmodified lines
192 182
193static int luaB_collectgarbage (lua_State *L) {183static int luaB_collectgarbage (lua_State *L) {
194 static const char *const opts[] = {"stop", "restart", "collect", "count",184 static const char *const opts[] = {"stop", "restart", "collect", "count",
195 NULL};185 "step", NULL};
196 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART,186 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART,
197 LUA_GCCOLLECT, LUA_GCCOUNT};187 LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP};
198 int o;188 int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts);
199 int ex;189 int ex = luaL_optint(L, 2, 0);
200#if 1
201 if (lua_isnumber(L, 1)) {
202 int v = lua_tointeger(L, 1);
203 lua_settop(L, 0);
204 if (v == 0) lua_pushstring(L, "collect");
205 else if (v >= 10000) lua_pushstring(L, "stop");
206 else lua_pushstring(L, "restart");
207 }
208#endif
209 o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts);
210 ex = luaL_optint(L, 2, 0);
211 luaL_argcheck(L, o >= 0, 1, "invalid option");190 luaL_argcheck(L, o >= 0, 1, "invalid option");
212 lua_pushinteger(L, lua_gc(L, optsnum[o], ex));191 lua_pushinteger(L, lua_gc(L, optsnum[o], ex));
213 return 1;192 return 1;
@@ -216,7 +195,7 @@ static int luaB_collectgarbage (lua_State *L) { · 2 unmodified lines
216 195
217static int luaB_type (lua_State *L) {196static int luaB_type (lua_State *L) {
218 luaL_checkany(L, 1);197 luaL_checkany(L, 1);
219 lua_pushstring(L, lua_typename(L, lua_type(L, 1)));198 lua_pushstring(L, luaL_typename(L, 1));
220 return 1;199 return 1;
221}200}
222 201
@@ -235,28 +214,29 @@ static int luaB_next (lua_State *L) { · 12 unmodified lines
235 214
236static int luaB_pairs (lua_State *L) {215static int luaB_pairs (lua_State *L) {
237 luaL_checktype(L, 1, LUA_TTABLE);216 luaL_checktype(L, 1, LUA_TTABLE);
238 lua_getglobal(L, "next"); /* return generator, */217 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
239 lua_pushvalue(L, 1); /* state, */218 lua_pushvalue(L, 1); /* state, */
240 lua_pushnil(L); /* and initial value */219 lua_pushnil(L); /* and initial value */
241 return 3;220 return 3;
242}221}
243 222
244 223
224static int ipairsaux (lua_State *L) {
225 int i = luaL_checkint(L, 2);
226 luaL_checktype(L, 1, LUA_TTABLE);
227 i++; /* next value */
228 lua_pushinteger(L, i);
229 lua_rawgeti(L, 1, i);
230 return (lua_isnil(L, -1)) ? 0 : 2;
231}
232
233
245static int luaB_ipairs (lua_State *L) {234static int luaB_ipairs (lua_State *L) {
246 int i = (int)lua_tointeger(L, 2);
247 luaL_checktype(L, 1, LUA_TTABLE);235 luaL_checktype(L, 1, LUA_TTABLE);
248 if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */236 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
249 lua_getglobal(L, "ipairs"); /* return generator, */237 lua_pushvalue(L, 1); /* state, */
250 lua_pushvalue(L, 1); /* state, */238 lua_pushinteger(L, LUA_FIRSTINDEX - 1); /* and initial value */
251 lua_pushinteger(L, 0); /* and initial value */239 return 3;
252 return 3;
253 }
254 else { /* `for' step */
255 i++; /* next value */
256 lua_pushinteger(L, i);
257 lua_rawgeti(L, 1, i);
258 return (lua_isnil(L, -1)) ? 0 : 2;
259 }
260}240}
261 241
262 242
@@ -281,7 +261,15 @@ static int luaB_loadstring (lua_State *L) { · 18 unmodified lines
281 261
282static int luaB_loadfile (lua_State *L) {262static int luaB_loadfile (lua_State *L) {
283 const char *fname = luaL_optstring(L, 1, NULL);263 const char *fname = luaL_optstring(L, 1, NULL);
284 return load_aux(L, luaL_loadfile(L, fname));264 const char *path = luaL_optstring(L, 2, NULL);
265 int status;
266 if (path == NULL)
267 status = luaL_loadfile(L, fname);
268 else {
269 fname = luaL_searchpath(L, fname, path);
270 status = (fname) ? luaL_loadfile(L, fname) : 1;
271 }
272 return load_aux(L, status);
285}273}
286 274
287 275
@@ -339,22 +327,41 @@ static int luaB_assert (lua_State *L) { · 51 unmodified lines
339 luaL_checkany(L, 1);327 luaL_checkany(L, 1);
340 if (!lua_toboolean(L, 1))328 if (!lua_toboolean(L, 1))
341 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));329 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
342 lua_settop(L, 1);330 return lua_gettop(L);
343 return 1;
344}331}
345 332
346 333
347static int luaB_unpack (lua_State *L) {334static int luaB_unpack (lua_State *L) {
348 int n, i;335 int i = luaL_optint(L, 2, LUA_FIRSTINDEX);
336 int e = luaL_optint(L, 3, -1);
337 int n;
349 luaL_checktype(L, 1, LUA_TTABLE);338 luaL_checktype(L, 1, LUA_TTABLE);
350 n = luaL_getn(L, 1);339 if (e == -1)
340 e = luaL_getn(L, 1) + LUA_FIRSTINDEX - 1;
341 n = e - i + 1; /* number of elements */
342 if (n <= 0) return 0; /* empty range */
351 luaL_checkstack(L, n, "table too big to unpack");343 luaL_checkstack(L, n, "table too big to unpack");
352 for (i=1; i<=n; i++) /* push arg[1...n] */344 for (; i<=e; i++) /* push arg[i...e] */
353 lua_rawgeti(L, 1, i);345 lua_rawgeti(L, 1, i);
354 return n;346 return n;
355}347}
356 348
357 349
350static int luaB_select (lua_State *L) {
351 int n = lua_gettop(L);
352 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
353 lua_pushinteger(L, n-1);
354 return 1;
355 }
356 else {
357 int i = luaL_checkint(L, 1);
358 if (i <= 0) i = 1;
359 else if (i >= n) i = n;
360 return n - i;
361 }
362}
363
364
358static int luaB_pcall (lua_State *L) {365static int luaB_pcall (lua_State *L) {
359 int status;366 int status;
360 luaL_checkany(L, 1);367 luaL_checkany(L, 1);
@@ -378,45 +385,36 @@ static int luaB_xpcall (lua_State *L) { · 17 unmodified lines
378 385
379 386
380static int luaB_tostring (lua_State *L) {387static int luaB_tostring (lua_State *L) {
381 char buff[4*sizeof(void *) + 2]; /* enough space for a `%p' */
382 const char *tn = "";
383 const void *p = NULL;
384 luaL_checkany(L, 1);388 luaL_checkany(L, 1);
385 if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */389 if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
386 return 1; /* use its value */390 return 1; /* use its value */
387 switch (lua_type(L, 1)) {391 switch (lua_type(L, 1)) {
388 case LUA_TNUMBER:392 case LUA_TNUMBER:
389 lua_pushstring(L, lua_tostring(L, 1));393 lua_pushstring(L, lua_tostring(L, 1));
390 return 1;394 break;
391 case LUA_TSTRING:395 case LUA_TSTRING:
392 lua_pushvalue(L, 1);396 lua_pushvalue(L, 1);
393 return 1;397 break;
394 case LUA_TBOOLEAN:398 case LUA_TBOOLEAN:
395 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));399 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
396 return 1;400 break;
397 case LUA_TNIL:401 case LUA_TNIL:
398 lua_pushliteral(L, "nil");402 lua_pushliteral(L, "nil");
399 return 1;403 break;
400 case LUA_TTABLE:404 case LUA_TTABLE:
401 p = lua_topointer(L, 1);405 lua_pushfstring(L, "table: %p", lua_topointer(L, 1));
402 tn = "table";
403 break;406 break;
404 case LUA_TFUNCTION:407 case LUA_TFUNCTION:
405 p = lua_topointer(L, 1);408 lua_pushfstring(L, "function: %p", lua_topointer(L, 1));
406 tn = "function";
407 break;409 break;
408 case LUA_TUSERDATA:410 case LUA_TUSERDATA:
409 case LUA_TLIGHTUSERDATA:411 case LUA_TLIGHTUSERDATA:
410 p = lua_touserdata(L, 1);412 lua_pushfstring(L, "userdata: %p", lua_topointer(L, 1));
411 tn = "userdata";
412 break;413 break;
413 case LUA_TTHREAD:414 case LUA_TTHREAD:
414 p = lua_tothread(L, 1);415 lua_pushfstring(L, "thread: %p", lua_topointer(L, 1));
415 tn = "thread";
416 break;416 break;
417 }417 }
418 sprintf(buff, "%p", p);
419 lua_pushfstring(L, "%s: %s", tn, buff);
420 return 1;418 return 1;
421}419}
422 420
@@ -454,112 +452,38 @@ static int luaB_newproxy (lua_State *L) { · 31 unmodified lines
454*/452*/
455 453
456 454
457/* name of global that holds table with loaded packages */
458#define REQTAB "_LOADED"
459
460/* name of global that holds the search path for packages */
461#define LUA_PATH "LUA_PATH"
462
463#ifndef LUA_PATH_SEP
464#define LUA_PATH_SEP ';'
465#endif
466
467#ifndef LUA_PATH_MARK
468#define LUA_PATH_MARK '?'
469#endif
470
471#ifndef LUA_PATH_DEFAULT
472#define LUA_PATH_DEFAULT "?;?.lua"
473#endif
474
475
476static const char *getpath (lua_State *L) {455static const char *getpath (lua_State *L) {
477 const char *path;456 /* try first `LUA_PATH' for compatibility */
478 lua_getglobal(L, LUA_PATH); /* try global variable */457 lua_getfield(L, LUA_GLOBALSINDEX, "LUA_PATH");
479 path = lua_tostring(L, -1);458 if (!lua_isstring(L, -1)) {
480 lua_pop(L, 1);459 lua_pop(L, 1);
481 if (path) return path;460 lua_getfield(L, LUA_GLOBALSINDEX, "_PATH");
482 path = getenv(LUA_PATH); /* else try environment variable */
483 if (path) return path;
484 return LUA_PATH_DEFAULT; /* else use default */
485}
486
487
488static const char *pushnextpath (lua_State *L, const char *path) {
489 const char *l;
490 if (*path == '\0') return NULL; /* no more paths */
491 if (*path == LUA_PATH_SEP) path++; /* skip separator */
492 l = strchr(path, LUA_PATH_SEP); /* find next separator */
493 if (l == NULL) l = path+strlen(path);
494 lua_pushlstring(L, path, l - path); /* directory name */
495 return l;
496}
497
498
499static void pushcomposename (lua_State *L) {
500 const char *path = lua_tostring(L, -1);
501 const char *wild;
502 int n = 1;
503 while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) {
504 /* is there stack space for prefix, name, and eventual last suffix? */
505 luaL_checkstack(L, 3, "too many marks in a path component");
506 lua_pushlstring(L, path, wild - path); /* push prefix */
507 lua_pushvalue(L, 1); /* push package name (in place of MARK) */
508 path = wild + 1; /* continue after MARK */
509 n += 2;
510 }461 }
511 lua_pushstring(L, path); /* push last suffix (`n' already includes this) */462 if (!lua_isstring(L, -1))
512 lua_concat(L, n);463 luaL_error(L, "global _PATH must be a string");
464 return lua_tostring(L, -1);
513}465}
514 466
515 467
516static int luaB_require (lua_State *L) {468static int luaB_require (lua_State *L) {
517 const char *path;469 const char *name = luaL_checkstring(L, 1);
518 int status = LUA_ERRFILE; /* not found (yet) */470 const char *fname;
519 luaL_checkstring(L, 1);471 lua_getfield(L, lua_upvalueindex(1), name);
520 lua_settop(L, 1);
521 lua_getglobal(L, REQTAB);
522 if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table");
523 path = getpath(L);
524 lua_pushvalue(L, 1); /* check package's name in book-keeping table */
525 lua_rawget(L, 2);
526 if (lua_toboolean(L, -1)) /* is it there? */472 if (lua_toboolean(L, -1)) /* is it there? */
527 return 1; /* package is already loaded; return its result */473 return 1; /* package is already loaded; return its result */
528 else { /* must load it */474 /* else must load it; first mark it as loaded */
529 while (status == LUA_ERRFILE) {475 lua_pushboolean(L, 1);
530 lua_settop(L, 3); /* reset stack position */476 lua_setfield(L, lua_upvalueindex(1), name); /* _LOADED[name] = true */
531 if ((path = pushnextpath(L, path)) == NULL) break;477 fname = luaL_searchpath(L, name, getpath(L));
532 pushcomposename(L);478 if (fname == NULL || luaL_loadfile(L, fname) != 0)
533 status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */479 return luaL_error(L, "error loading package `%s' (%s)", name,
534 }480 lua_tostring(L, -1));
535 }481 lua_pushvalue(L, 1); /* pass name as argument to module */
536 switch (status) {482 lua_call(L, 1, 1); /* run loaded module */
537 case 0: {483 if (!lua_isnil(L, -1)) /* nil return? */
538 lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */484 lua_setfield(L, lua_upvalueindex(1), name);
539 lua_insert(L, -2); /* put it below function */485 lua_getfield(L, lua_upvalueindex(1), name); /* return _LOADED[name] */
540 lua_pushvalue(L, 1);486 return 1;
541 lua_setglobal(L, "_REQUIREDNAME"); /* set new name */
542 lua_call(L, 0, 1); /* run loaded module */
543 lua_insert(L, -2); /* put result below previous name */
544 lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */
545 if (lua_isnil(L, -1)) { /* no/nil return? */
546 lua_pushboolean(L, 1);
547 lua_replace(L, -2); /* replace to true */
548 }
549 lua_pushvalue(L, 1);
550 lua_pushvalue(L, -2);
551 lua_rawset(L, 2); /* mark it as loaded */
552 return 1; /* return value */
553 }
554 case LUA_ERRFILE: { /* file not found */
555 return luaL_error(L, "could not load package `%s' from path `%s'",
556 lua_tostring(L, 1), getpath(L));
557 }
558 default: {
559 return luaL_error(L, "error loading package `%s' (%s)",
560 lua_tostring(L, 1), lua_tostring(L, -1));
561 }
562 }
563}487}
564 488
565/* }====================================================== */489/* }====================================================== */
@@ -572,14 +496,13 @@ static const luaL_reg base_funcs[] = { · 6 unmodified lines
572 {"getfenv", luaB_getfenv},496 {"getfenv", luaB_getfenv},
573 {"setfenv", luaB_setfenv},497 {"setfenv", luaB_setfenv},
574 {"next", luaB_next},498 {"next", luaB_next},
575 {"ipairs", luaB_ipairs},
576 {"pairs", luaB_pairs},
577 {"print", luaB_print},499 {"print", luaB_print},
578 {"tonumber", luaB_tonumber},500 {"tonumber", luaB_tonumber},
579 {"tostring", luaB_tostring},501 {"tostring", luaB_tostring},
580 {"type", luaB_type},502 {"type", luaB_type},
581 {"assert", luaB_assert},503 {"assert", luaB_assert},
582 {"unpack", luaB_unpack},504 {"unpack", luaB_unpack},
505 {"select", luaB_select},
583 {"rawequal", luaB_rawequal},506 {"rawequal", luaB_rawequal},
584 {"rawget", luaB_rawget},507 {"rawget", luaB_rawget},
585 {"rawset", luaB_rawset},508 {"rawset", luaB_rawset},
@@ -591,7 +514,6 @@ static const luaL_reg base_funcs[] = { · 5 unmodified lines
591 {"dofile", luaB_dofile},514 {"dofile", luaB_dofile},
592 {"loadstring", luaB_loadstring},515 {"loadstring", luaB_loadstring},
593 {"load", luaB_load},516 {"load", luaB_load},
594 {"require", luaB_require},
595 {NULL, NULL}517 {NULL, NULL}
596};518};
597 519
@@ -704,12 +626,23 @@ static const luaL_reg co_funcs[] = { · 106 unmodified lines
704/* }====================================================== */626/* }====================================================== */
705 627
706 628
629static void auxopen (lua_State *L, const char *name,
630 lua_CFunction f, lua_CFunction u) {
631 lua_pushcfunction(L, u);
632 lua_pushcclosure(L, f, 1);
633 lua_setfield(L, -2, name);
634}
635
707 636
708static void base_open (lua_State *L) {637static void base_open (lua_State *L) {
638 const char *path;
709 lua_pushvalue(L, LUA_GLOBALSINDEX);639 lua_pushvalue(L, LUA_GLOBALSINDEX);
710 luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */640 luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */
711 lua_pushliteral(L, LUA_VERSION);641 lua_pushliteral(L, LUA_VERSION);
712 lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */642 lua_setfield(L, LUA_GLOBALSINDEX, "_VERSION"); /* set global _VERSION */
643 /* `ipairs' and `pairs' need auxliliary functions as upvalues */
644 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
645 auxopen(L, "pairs", luaB_pairs, luaB_next);
713 /* `newproxy' needs a weaktable as upvalue */646 /* `newproxy' needs a weaktable as upvalue */
714 lua_newtable(L); /* new table `w' */647 lua_newtable(L); /* new table `w' */
715 lua_pushvalue(L, -1); /* `w' will be its own metatable */648 lua_pushvalue(L, -1); /* `w' will be its own metatable */
@@ -717,16 +650,27 @@ static void base_open (lua_State *L) { · 1 unmodified line
717 lua_pushliteral(L, "kv");650 lua_pushliteral(L, "kv");
718 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */651 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
719 lua_pushcclosure(L, luaB_newproxy, 1);652 lua_pushcclosure(L, luaB_newproxy, 1);
720 lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */653 lua_setfield(L, LUA_GLOBALSINDEX, "newproxy"); /* set global `newproxy' */
721 lua_setfield(L, -1, "_G"); /* set global _G */654 /* `require' needs a table to keep loaded chunks */
655 lua_newtable(L);
656 lua_pushvalue(L, -1);
657 lua_setglobal(L, "_LOADED");
658 lua_pushcclosure(L, luaB_require, 1);
659 lua_setfield(L, LUA_GLOBALSINDEX, "require");
660 /* set global _G */
661 lua_pushvalue(L, LUA_GLOBALSINDEX);
662 lua_setfield(L, LUA_GLOBALSINDEX, "_G");
663 /* set global _PATH */
664 path = getenv(LUA_PATH);
665 if (path == NULL) path = LUA_PATH_DEFAULT;
666 lua_pushstring(L, path);
667 lua_setfield(L, LUA_GLOBALSINDEX, "_PATH");
722}668}
723 669
724 670
725LUALIB_API int luaopen_base (lua_State *L) {671LUALIB_API int luaopen_base (lua_State *L) {
726 base_open(L);672 base_open(L);
727 luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);673 luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
728 lua_newtable(L);
729 lua_setglobal(L, REQTAB);
730 return 2;674 return 2;
731}675}
732 676
src/lib/ldblib.c+16−17
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldblib.c,v 1.84 2003/11/05 11:59:14 roberto Exp $2** $Id: ldblib.c,v 1.87 2004/08/13 18:02:36 roberto Exp $
3** Interface from Lua to its debug API3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -10,6 +10,7 @@ · 4 unmodified lines
10#include <string.h>10#include <string.h>
11 11
12#define ldblib_c12#define ldblib_c
13#define LUA_LIB
13 14
14#include "lua.h"15#include "lua.h"
15 16
@@ -260,7 +261,11 @@ static int debug (lua_State *L) { · 244 unmodified lines
260 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||261 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
261 strcmp(buffer, "cont\n") == 0)262 strcmp(buffer, "cont\n") == 0)
262 return 0;263 return 0;
263 lua_dostring(L, buffer);264 if (luaL_loadbuffer(L, buffer, strlen(buffer), "=debug command") ||
265 lua_pcall(L, 0, 0, 0)) {
266 fputs(lua_tostring(L, -1), stderr);
267 fputs("\n", stderr);
268 }
264 lua_settop(L, 0); /* remove eventual returns */269 lua_settop(L, 0); /* remove eventual returns */
265 }270 }
266}271}
@@ -298,22 +303,16 @@ static int errorfb (lua_State *L) { · 31 unmodified lines
298 lua_pushfstring(L, "%s:", ar.short_src);303 lua_pushfstring(L, "%s:", ar.short_src);
299 if (ar.currentline > 0)304 if (ar.currentline > 0)
300 lua_pushfstring(L, "%d:", ar.currentline);305 lua_pushfstring(L, "%d:", ar.currentline);
301 switch (*ar.namewhat) {306 if (*ar.namewhat != '\0') /* is there a name? */
302 case 'g': /* global */
303 case 'l': /* local */
304 case 'f': /* field */
305 case 'm': /* method */
306 lua_pushfstring(L, " in function `%s'", ar.name);307 lua_pushfstring(L, " in function `%s'", ar.name);
307 break;308 else {
308 default: {309 if (*ar.what == 'm') /* main? */
309 if (*ar.what == 'm') /* main? */310 lua_pushfstring(L, " in main chunk");
310 lua_pushfstring(L, " in main chunk");311 else if (*ar.what == 'C' || *ar.what == 't')
311 else if (*ar.what == 'C' || *ar.what == 't')312 lua_pushliteral(L, " ?"); /* C function or tail call */
312 lua_pushliteral(L, " ?"); /* C function or tail call */313 else
313 else314 lua_pushfstring(L, " in function <%s:%d>",
314 lua_pushfstring(L, " in function <%s:%d>",315 ar.short_src, ar.linedefined);
315 ar.short_src, ar.linedefined);
316 }
317 }316 }
318 lua_concat(L, lua_gettop(L) - arg);317 lua_concat(L, lua_gettop(L) - arg);
319 }318 }
src/lib/linit.c+38−0
@@ -0,0 +1,38 @@
1/*
2** $Id: linit.c,v 1.8 2004/07/09 15:47:48 roberto Exp $
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_TABLIBNAME, luaopen_table},
20 {LUA_IOLIBNAME, luaopen_io},
21 {LUA_OSLIBNAME, luaopen_os},
22 {LUA_STRLIBNAME, luaopen_string},
23 {LUA_MATHLIBNAME, luaopen_math},
24 {LUA_DBLIBNAME, luaopen_debug},
25 {"", luaopen_loadlib},
26 {NULL, NULL}
27};
28
29
30LUALIB_API int luaopen_stdlibs (lua_State *L) {
31 const luaL_reg *lib = lualibs;
32 for (; lib->func; lib++) {
33 lib->func(L); /* open library */
34 lua_settop(L, 0); /* discard any results */
35 }
36 return 0;
37}
38
src/lib/liolib.c+69−309
@@ -1,18 +1,17 @@
1/*1/*
2** $Id: liolib.c,v 2.49 2003/10/10 13:29:28 roberto Exp $2** $Id: liolib.c,v 2.57 2004/08/13 19:52:13 roberto Exp $
3** Standard I/O (and system) library3** Standard I/O (and system) library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
6 6
7 7
8#include <errno.h>8#include <errno.h>
9#include <locale.h>
10#include <stdio.h>9#include <stdio.h>
11#include <stdlib.h>10#include <stdlib.h>
12#include <string.h>11#include <string.h>
13#include <time.h>
14 12
15#define liolib_c13#define liolib_c
14#define LUA_LIB
16 15
17#include "lua.h"16#include "lua.h"
18 17
@@ -21,50 +20,13 @@ · 2 unmodified lines
21 20
22 21
23 22
24/*
25** by default, gcc does not get `tmpname'
26*/
27#ifndef USE_TMPNAME
28#ifdef __GNUC__
29#define USE_TMPNAME 0
30#else
31#define USE_TMPNAME 1
32#endif
33#endif
34
35
36/*
37** by default, posix systems get `popen'
38*/
39#ifndef USE_POPEN
40#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2
41#define USE_POPEN 1
42#else
43#define USE_POPEN 0
44#endif
45#endif
46
47
48
49
50/*
51** {======================================================
52** FILE Operations
53** =======================================================
54*/
55
56
57#if !USE_POPEN
58#define pclose(f) (-1)
59#endif
60
61
62#define FILEHANDLE "FILE*"
63
64#define IO_INPUT 123#define IO_INPUT 1
65#define IO_OUTPUT 224#define IO_OUTPUT 2
66 25
67 26
27static const char *const fnames[] = {"input", "output"};
28
29
68static int pushresult (lua_State *L, int i, const char *filename) {30static int pushresult (lua_State *L, int i, const char *filename) {
69 if (i) {31 if (i) {
70 lua_pushboolean(L, 1);32 lua_pushboolean(L, 1);
@@ -82,15 +44,21 @@ static int pushresult (lua_State *L, int i, const char *filename) { · 11 unmodified lines
82}44}
83 45
84 46
85static FILE **topfile (lua_State *L, int findex) {47static void fileerror (lua_State *L, int arg, const char *filename) {
86 FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);48 lua_pushfstring(L, "%s: %s", filename, strerror(errno));
87 if (f == NULL) luaL_argerror(L, findex, "bad file");49 luaL_argerror(L, arg, lua_tostring(L, -1));
50}
51
52
53static FILE **topfile (lua_State *L) {
54 FILE **f = (FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE);
55 if (f == NULL) luaL_argerror(L, 1, "bad file");
88 return f;56 return f;
89}57}
90 58
91 59
92static int io_type (lua_State *L) {60static int io_type (lua_State *L) {
93 FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);61 FILE **f = (FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE);
94 if (f == NULL) lua_pushnil(L);62 if (f == NULL) lua_pushnil(L);
95 else if (*f == NULL)63 else if (*f == NULL)
96 lua_pushliteral(L, "closed file");64 lua_pushliteral(L, "closed file");
@@ -100,8 +68,8 @@ static int io_type (lua_State *L) { · 3 unmodified lines
100}68}
101 69
102 70
103static FILE *tofile (lua_State *L, int findex) {71static FILE *tofile (lua_State *L) {
104 FILE **f = topfile(L, findex);72 FILE **f = topfile(L);
105 if (*f == NULL)73 if (*f == NULL)
106 luaL_error(L, "attempt to use a closed file");74 luaL_error(L, "attempt to use a closed file");
107 return *f;75 return *f;
@@ -117,18 +85,18 @@ static FILE *tofile (lua_State *L, int findex) { · 9 unmodified lines
117static FILE **newfile (lua_State *L) {85static FILE **newfile (lua_State *L) {
118 FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));86 FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
119 *pf = NULL; /* file handle is currently `closed' */87 *pf = NULL; /* file handle is currently `closed' */
120 luaL_getmetatable(L, FILEHANDLE);88 luaL_getmetatable(L, LUA_FILEHANDLE);
121 lua_setmetatable(L, -2);89 lua_setmetatable(L, -2);
122 return pf;90 return pf;
123}91}
124 92
125 93
126static int aux_close (lua_State *L) {94static int aux_close (lua_State *L) {
127 FILE *f = tofile(L, 1);95 FILE *f = tofile(L);
128 if (f == stdin || f == stdout || f == stderr)96 if (f == stdin || f == stdout || f == stderr)
129 return 0; /* file cannot be closed */97 return 0; /* file cannot be closed */
130 else {98 else {
131 int ok = (pclose(f) != -1) || (fclose(f) == 0);99 int ok = (fclose(f) == 0);
132 if (ok)100 if (ok)
133 *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */101 *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
134 return ok;102 return ok;
@@ -144,7 +112,7 @@ static int io_close (lua_State *L) { · 9 unmodified lines
144 112
145 113
146static int io_gc (lua_State *L) {114static int io_gc (lua_State *L) {
147 FILE **f = topfile(L, 1);115 FILE **f = topfile(L);
148 if (*f != NULL) /* ignore closed files */116 if (*f != NULL) /* ignore closed files */
149 aux_close(L);117 aux_close(L);
150 return 0;118 return 0;
@@ -152,13 +120,11 @@ static int io_gc (lua_State *L) { · 1 unmodified line
152 120
153 121
154static int io_tostring (lua_State *L) {122static int io_tostring (lua_State *L) {
155 char buff[4*sizeof(void *) + 2]; /* enough space for a `%p' */123 FILE *f = *topfile(L);
156 FILE **f = topfile(L, 1);124 if (f == NULL)
157 if (*f == NULL)125 lua_pushstring(L, "file (closed)");
158 strcpy(buff, "closed");
159 else126 else
160 sprintf(buff, "%p", lua_touserdata(L, 1));127 lua_pushfstring(L, "file (%p)", f);
161 lua_pushfstring(L, "file (%s)", buff);
162 return 1;128 return 1;
163}129}
164 130
@@ -172,20 +138,6 @@ static int io_open (lua_State *L) { · 7 unmodified lines
172}138}
173 139
174 140
175static int io_popen (lua_State *L) {
176#if !USE_POPEN
177 luaL_error(L, "`popen' not supported");
178 return 0;
179#else
180 const char *filename = luaL_checkstring(L, 1);
181 const char *mode = luaL_optstring(L, 2, "r");
182 FILE **pf = newfile(L);
183 *pf = popen(filename, mode);
184 return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
185#endif
186}
187
188
189static int io_tmpfile (lua_State *L) {141static int io_tmpfile (lua_State *L) {
190 FILE **pf = newfile(L);142 FILE **pf = newfile(L);
191 *pf = tmpfile();143 *pf = tmpfile();
@@ -193,9 +145,14 @@ static int io_tmpfile (lua_State *L) { · 1 unmodified line
193}145}
194 146
195 147
196static FILE *getiofile (lua_State *L, int f) {148static FILE *getiofile (lua_State *L, int findex) {
197 lua_rawgeti(L, lua_upvalueindex(1), f);149 FILE *f;
198 return tofile(L, -1);150 lua_rawgeti(L, lua_upvalueindex(1), findex);
151 lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE));
152 f = *(FILE **)lua_touserdata(L, -1);
153 if (f == NULL)
154 luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
155 return f;
199}156}
200 157
201 158
@@ -205,15 +162,14 @@ static int g_iofile (lua_State *L, int f, const char *mode) { · 3 unmodified lines
205 if (filename) {162 if (filename) {
206 FILE **pf = newfile(L);163 FILE **pf = newfile(L);
207 *pf = fopen(filename, mode);164 *pf = fopen(filename, mode);
208 if (*pf == NULL) {165 if (*pf == NULL)
209 lua_pushfstring(L, "%s: %s", filename, strerror(errno));166 fileerror(L, 1, filename);
210 luaL_argerror(L, 1, lua_tostring(L, -1));
211 }
212 }167 }
213 else {168 else {
214 tofile(L, 1); /* check that it's a valid file handle */169 tofile(L); /* check that it's a valid file handle */
215 lua_pushvalue(L, 1);170 lua_pushvalue(L, 1);
216 }171 }
172 lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE));
217 lua_rawseti(L, lua_upvalueindex(1), f);173 lua_rawseti(L, lua_upvalueindex(1), f);
218 }174 }
219 /* return current value */175 /* return current value */
@@ -236,7 +192,7 @@ static int io_readline (lua_State *L); · 16 unmodified lines
236 192
237 193
238static void aux_lines (lua_State *L, int idx, int close) {194static void aux_lines (lua_State *L, int idx, int close) {
239 lua_getfield(L, LUA_REGISTRYINDEX, FILEHANDLE);195 lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
240 lua_pushvalue(L, idx);196 lua_pushvalue(L, idx);
241 lua_pushboolean(L, close); /* close/not close file when finished */197 lua_pushboolean(L, close); /* close/not close file when finished */
242 lua_pushcclosure(L, io_readline, 3);198 lua_pushcclosure(L, io_readline, 3);
@@ -244,7 +200,7 @@ static void aux_lines (lua_State *L, int idx, int close) { · 1 unmodified line
244 200
245 201
246static int f_lines (lua_State *L) {202static int f_lines (lua_State *L) {
247 tofile(L, 1); /* check that it's a valid file handle */203 tofile(L); /* check that it's a valid file handle */
248 aux_lines(L, 1, 0);204 aux_lines(L, 1, 0);
249 return 1;205 return 1;
250}206}
@@ -260,7 +216,8 @@ static int io_lines (lua_State *L) { · 9 unmodified lines
260 const char *filename = luaL_checkstring(L, 1);216 const char *filename = luaL_checkstring(L, 1);
261 FILE **pf = newfile(L);217 FILE **pf = newfile(L);
262 *pf = fopen(filename, "r");218 *pf = fopen(filename, "r");
263 luaL_argcheck(L, *pf, 1, strerror(errno));219 if (*pf == NULL)
220 fileerror(L, 1, filename);
264 aux_lines(L, lua_gettop(L), 1);221 aux_lines(L, lua_gettop(L), 1);
265 return 1;222 return 1;
266 }223 }
@@ -336,6 +293,7 @@ static int g_read (lua_State *L, FILE *f, int first) { · 69 unmodified lines
336 int nargs = lua_gettop(L) - 1;293 int nargs = lua_gettop(L) - 1;
337 int success;294 int success;
338 int n;295 int n;
296 clearerr(f);
339 if (nargs == 0) { /* no arguments? */297 if (nargs == 0) { /* no arguments? */
340 success = read_line(L, f);298 success = read_line(L, f);
341 n = first+1; /* to return 1 result */299 n = first+1; /* to return 1 result */
@@ -370,6 +328,8 @@ static int g_read (lua_State *L, FILE *f, int first) { · 28 unmodified lines
370 }328 }
371 }329 }
372 }330 }
331 if (ferror(f))
332 return pushresult(L, 0, NULL);
373 if (!success) {333 if (!success) {
374 lua_pop(L, 1); /* remove last result */334 lua_pop(L, 1); /* remove last result */
375 lua_pushnil(L); /* push nil instead */335 lua_pushnil(L); /* push nil instead */
@@ -384,15 +344,19 @@ static int io_read (lua_State *L) { · 8 unmodified lines
384 344
385 345
386static int f_read (lua_State *L) {346static int f_read (lua_State *L) {
387 return g_read(L, tofile(L, 1), 2);347 return g_read(L, tofile(L), 2);
388}348}
389 349
390 350
391static int io_readline (lua_State *L) {351static int io_readline (lua_State *L) {
392 FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2));352 FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2));
353 int sucess;
393 if (f == NULL) /* file is already closed? */354 if (f == NULL) /* file is already closed? */
394 luaL_error(L, "file is already closed");355 luaL_error(L, "file is already closed");
395 if (read_line(L, f)) return 1;356 sucess = read_line(L, f);
357 if (ferror(f))
358 luaL_error(L, "%s", strerror(errno));
359 if (sucess) return 1;
396 else { /* EOF */360 else { /* EOF */
397 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */361 if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
398 lua_settop(L, 0);362 lua_settop(L, 0);
@@ -431,14 +395,14 @@ static int io_write (lua_State *L) { · 32 unmodified lines
431 395
432 396
433static int f_write (lua_State *L) {397static int f_write (lua_State *L) {
434 return g_write(L, tofile(L, 1), 2);398 return g_write(L, tofile(L), 2);
435}399}
436 400
437 401
438static int f_seek (lua_State *L) {402static int f_seek (lua_State *L) {
439 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};403 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
440 static const char *const modenames[] = {"set", "cur", "end", NULL};404 static const char *const modenames[] = {"set", "cur", "end", NULL};
441 FILE *f = tofile(L, 1);405 FILE *f = tofile(L);
442 int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames);406 int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames);
443 lua_Integer offset = luaL_optinteger(L, 3, 0);407 lua_Integer offset = luaL_optinteger(L, 3, 0);
444 luaL_argcheck(L, op != -1, 2, "invalid mode");408 luaL_argcheck(L, op != -1, 2, "invalid mode");
@@ -455,7 +419,7 @@ static int f_seek (lua_State *L) { · 10 unmodified lines
455static int f_setvbuf (lua_State *L) {419static int f_setvbuf (lua_State *L) {
456 static const int mode[] = {_IONBF, _IOFBF, _IOLBF};420 static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
457 static const char *const modenames[] = {"no", "full", "line", NULL};421 static const char *const modenames[] = {"no", "full", "line", NULL};
458 FILE *f = tofile(L, 1);422 FILE *f = tofile(L);
459 int op = luaL_findstring(luaL_checkstring(L, 2), modenames);423 int op = luaL_findstring(luaL_checkstring(L, 2), modenames);
460 luaL_argcheck(L, op != -1, 2, "invalid mode");424 luaL_argcheck(L, op != -1, 2, "invalid mode");
461 return pushresult(L, setvbuf(f, NULL, mode[op], 0) == 0, NULL);425 return pushresult(L, setvbuf(f, NULL, mode[op], 0) == 0, NULL);
@@ -469,7 +433,7 @@ static int io_flush (lua_State *L) { · 7 unmodified lines
469 433
470 434
471static int f_flush (lua_State *L) {435static int f_flush (lua_State *L) {
472 return pushresult(L, fflush(tofile(L, 1)) == 0, NULL);436 return pushresult(L, fflush(tofile(L)) == 0, NULL);
473}437}
474 438
475 439
@@ -480,7 +444,6 @@ static const luaL_reg iolib[] = { · 4 unmodified lines
480 {"close", io_close},444 {"close", io_close},
481 {"flush", io_flush},445 {"flush", io_flush},
482 {"open", io_open},446 {"open", io_open},
483 {"popen", io_popen},
484 {"read", io_read},447 {"read", io_read},
485 {"tmpfile", io_tmpfile},448 {"tmpfile", io_tmpfile},
486 {"type", io_type},449 {"type", io_type},
@@ -504,239 +467,36 @@ static const luaL_reg flib[] = { · 17 unmodified lines
504 467
505 468
506static void createmeta (lua_State *L) {469static void createmeta (lua_State *L) {
507 luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */470 luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
508 /* create (and set) default files */
509 *newfile(L) = stdin;
510 lua_rawseti(L, -2, IO_INPUT);
511 *newfile(L) = stdout;
512 lua_rawseti(L, -2, IO_OUTPUT);
513 /* file methods */
514 lua_pushvalue(L, -1); /* push metatable */471 lua_pushvalue(L, -1); /* push metatable */
515 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */472 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
516 luaL_openlib(L, NULL, flib, 0);473 luaL_openlib(L, NULL, flib, 0); /* file methods */
517}
518
519/* }====================================================== */
520
521
522/*
523** {======================================================
524** Other O.S. Operations
525** =======================================================
526*/
527
528static int io_execute (lua_State *L) {
529 lua_pushinteger(L, system(luaL_checkstring(L, 1)));
530 return 1;
531}
532
533
534static int io_remove (lua_State *L) {
535 const char *filename = luaL_checkstring(L, 1);
536 return pushresult(L, remove(filename) == 0, filename);
537}
538
539
540static int io_rename (lua_State *L) {
541 const char *fromname = luaL_checkstring(L, 1);
542 const char *toname = luaL_checkstring(L, 2);
543 return pushresult(L, rename(fromname, toname) == 0, fromname);
544}
545
546
547static int io_tmpname (lua_State *L) {
548#if !USE_TMPNAME
549 luaL_error(L, "`tmpname' not supported");
550 return 0;
551#else
552 char buff[L_tmpnam];
553 if (tmpnam(buff) != buff)
554 return luaL_error(L, "unable to generate a unique filename in `tmpname'");
555 lua_pushstring(L, buff);
556 return 1;
557#endif
558}474}
559 475
560 476
561static int io_getenv (lua_State *L) {477static void createupval (lua_State *L) {
562 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */478 lua_newtable(L);
563 return 1;479 /* create (and set) default files */
564}480 *newfile(L) = stdin;
565 481 lua_rawseti(L, -2, IO_INPUT);
566 482 *newfile(L) = stdout;
567static int io_clock (lua_State *L) {483 lua_rawseti(L, -2, IO_OUTPUT);
568 lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
569 return 1;
570}
571
572
573/*
574** {======================================================
575** Time/Date operations
576** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
577** wday=%w+1, yday=%j, isdst=? }
578** =======================================================
579*/
580
581static void setfield (lua_State *L, const char *key, int value) {
582 lua_pushstring(L, key);
583 lua_pushinteger(L, value);
584 lua_rawset(L, -3);
585}
586
587static void setboolfield (lua_State *L, const char *key, int value) {
588 lua_pushstring(L, key);
589 lua_pushboolean(L, value);
590 lua_rawset(L, -3);
591}
592
593static int getboolfield (lua_State *L, const char *key) {
594 int res;
595 lua_getfield(L, -1, key);
596 res = lua_toboolean(L, -1);
597 lua_pop(L, 1);
598 return res;
599}
600
601
602static int getfield (lua_State *L, const char *key, int d) {
603 int res;
604 lua_getfield(L, -1, key);
605 if (lua_isnumber(L, -1))
606 res = (int)lua_tointeger(L, -1);
607 else {
608 if (d < 0)
609 return luaL_error(L, "field `%s' missing in date table", key);
610 res = d;
611 }
612 lua_pop(L, 1);
613 return res;
614}
615
616
617static int io_date (lua_State *L) {
618 const char *s = luaL_optstring(L, 1, "%c");
619 lua_Number n = luaL_optnumber(L, 2, -1);
620 time_t t = (n == -1) ? time(NULL) : (time_t)n;
621 struct tm *stm;
622 if (*s == '!') { /* UTC? */
623 stm = gmtime(&t);
624 s++; /* skip `!' */
625 }
626 else
627 stm = localtime(&t);
628 if (stm == NULL) /* invalid date? */
629 lua_pushnil(L);
630 else if (strcmp(s, "*t") == 0) {
631 lua_createtable(L, 0, 9); /* 9 = number of fields */
632 setfield(L, "sec", stm->tm_sec);
633 setfield(L, "min", stm->tm_min);
634 setfield(L, "hour", stm->tm_hour);
635 setfield(L, "day", stm->tm_mday);
636 setfield(L, "month", stm->tm_mon+1);
637 setfield(L, "year", stm->tm_year+1900);
638 setfield(L, "wday", stm->tm_wday+1);
639 setfield(L, "yday", stm->tm_yday+1);
640 setboolfield(L, "isdst", stm->tm_isdst);
641 }
642 else {
643 char b[256];
644 if (strftime(b, sizeof(b), s, stm))
645 lua_pushstring(L, b);
646 else
647 return luaL_error(L, "`date' format too long");
648 }
649 return 1;
650}
651
652
653static int io_time (lua_State *L) {
654 if (lua_isnoneornil(L, 1)) /* called without args? */
655 lua_pushnumber(L, time(NULL)); /* return current time */
656 else {
657 time_t t;
658 struct tm ts;
659 luaL_checktype(L, 1, LUA_TTABLE);
660 lua_settop(L, 1); /* make sure table is at the top */
661 ts.tm_sec = getfield(L, "sec", 0);
662 ts.tm_min = getfield(L, "min", 0);
663 ts.tm_hour = getfield(L, "hour", 12);
664 ts.tm_mday = getfield(L, "day", -1);
665 ts.tm_mon = getfield(L, "month", -1) - 1;
666 ts.tm_year = getfield(L, "year", -1) - 1900;
667 ts.tm_isdst = getboolfield(L, "isdst");
668 t = mktime(&ts);
669 if (t == (time_t)(-1))
670 lua_pushnil(L);
671 else
672 lua_pushnumber(L, t);
673 }
674 return 1;
675}
676
677
678static int io_difftime (lua_State *L) {
679 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
680 (time_t)(luaL_optnumber(L, 2, 0))));
681 return 1;
682}
683
684/* }====================================================== */
685
686
687static int io_setloc (lua_State *L) {
688 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
689 LC_NUMERIC, LC_TIME};
690 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
691 "numeric", "time", NULL};
692 const char *l = lua_tostring(L, 1);
693 int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames);
694 luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
695 luaL_argcheck(L, op != -1, 2, "invalid option");
696 lua_pushstring(L, setlocale(cat[op], l));
697 return 1;
698}
699
700
701static int io_exit (lua_State *L) {
702 exit(luaL_optint(L, 1, EXIT_SUCCESS));
703 return 0; /* to avoid warnings */
704}484}
705 485
706static const luaL_reg syslib[] = {
707 {"clock", io_clock},
708 {"date", io_date},
709 {"difftime", io_difftime},
710 {"execute", io_execute},
711 {"exit", io_exit},
712 {"getenv", io_getenv},
713 {"remove", io_remove},
714 {"rename", io_rename},
715 {"setlocale", io_setloc},
716 {"time", io_time},
717 {"tmpname", io_tmpname},
718 {NULL, NULL}
719};
720
721/* }====================================================== */
722
723 486
724 487
725LUALIB_API int luaopen_io (lua_State *L) {488LUALIB_API int luaopen_io (lua_State *L) {
726 luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
727 createmeta(L);489 createmeta(L);
490 createupval(L);
728 lua_pushvalue(L, -1);491 lua_pushvalue(L, -1);
729 luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);492 luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
730 /* put predefined file handles into `io' table */493 /* put predefined file handles into `io' table */
731 lua_pushliteral(L, "stdin");494 lua_rawgeti(L, -2, IO_INPUT); /* get current input from metatable */
732 lua_rawgeti(L, 2, IO_INPUT);495 lua_setfield(L, -2, "stdin"); /* io.stdin = metatable[IO_INPUT] */
733 lua_rawset(L, 3);496 lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from metatable */
734 lua_pushliteral(L, "stdout");497 lua_setfield(L, -2, "stdout"); /* io.stdout = metatable[IO_OUTPUT] */
735 lua_rawgeti(L, 2, IO_OUTPUT);
736 lua_rawset(L, 3);
737 lua_pushliteral(L, "stderr");
738 *newfile(L) = stderr;498 *newfile(L) = stderr;
739 lua_rawset(L, 3);499 lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */
740 return 1;500 return 1;
741}501}
742 502
src/lib/lmathlib.c+9−21
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lmathlib.c,v 1.59 2003/11/05 11:59:14 roberto Exp $2** $Id: lmathlib.c,v 1.61 2004/05/10 18:11:32 roberto Exp $
3** Standard mathematical library3** Standard mathematical library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -9,6 +9,7 @@ · 3 unmodified lines
9#include <math.h>9#include <math.h>
10 10
11#define lmathlib_c11#define lmathlib_c
12#define LUA_LIB
12 13
13#include "lua.h"14#include "lua.h"
14 15
@@ -22,56 +23,43 @@ · 7 unmodified lines
22 23
23 24
24 25
25/*
26** If you want Lua to operate in degrees (instead of radians),
27** define USE_DEGREES
28*/
29#ifdef USE_DEGREES
30#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
31#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
32#else
33#define FROMRAD(a) (a)
34#define TORAD(a) (a)
35#endif
36
37
38static int math_abs (lua_State *L) {26static int math_abs (lua_State *L) {
39 lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));27 lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
40 return 1;28 return 1;
41}29}
42 30
43static int math_sin (lua_State *L) {31static int math_sin (lua_State *L) {
44 lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1))));32 lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
45 return 1;33 return 1;
46}34}
47 35
48static int math_cos (lua_State *L) {36static int math_cos (lua_State *L) {
49 lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1))));37 lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
50 return 1;38 return 1;
51}39}
52 40
53static int math_tan (lua_State *L) {41static int math_tan (lua_State *L) {
54 lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1))));42 lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
55 return 1;43 return 1;
56}44}
57 45
58static int math_asin (lua_State *L) {46static int math_asin (lua_State *L) {
59 lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1))));47 lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
60 return 1;48 return 1;
61}49}
62 50
63static int math_acos (lua_State *L) {51static int math_acos (lua_State *L) {
64 lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1))));52 lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
65 return 1;53 return 1;
66}54}
67 55
68static int math_atan (lua_State *L) {56static int math_atan (lua_State *L) {
69 lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1))));57 lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
70 return 1;58 return 1;
71}59}
72 60
73static int math_atan2 (lua_State *L) {61static int math_atan2 (lua_State *L) {
74 lua_pushnumber(L, FROMRAD(atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))));62 lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
75 return 1;63 return 1;
76}64}
77 65
src/lib/loadlib.c+4−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: loadlib.c,v 1.5 2003/05/14 21:01:53 roberto Exp $2** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 roberto Exp $
3** Dynamic library loader for Lua3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*5*
@@ -26,6 +26,9 @@ · 20 unmodified lines
26*26*
27*/27*/
28 28
29#define loadlib_c
30#define LUA_LIB
31
29#include "lua.h"32#include "lua.h"
30#include "lauxlib.h"33#include "lauxlib.h"
31#include "lualib.h"34#include "lualib.h"
src/lib/loslib.c+241−0
@@ -0,0 +1,241 @@
1/*
2** $Id: loslib.c,v 1.2 2004/08/05 19:30:37 roberto Exp $
3** Standard Operating System library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <errno.h>
9#include <locale.h>
10#include <stdlib.h>
11#include <string.h>
12#include <time.h>
13
14#define loslib_c
15#define LUA_LIB
16
17#include "lua.h"
18
19#include "lauxlib.h"
20#include "lualib.h"
21
22
23static int pushresult (lua_State *L, int i, const char *filename) {
24 if (i) {
25 lua_pushboolean(L, 1);
26 return 1;
27 }
28 else {
29 lua_pushnil(L);
30 if (filename)
31 lua_pushfstring(L, "%s: %s", filename, strerror(errno));
32 else
33 lua_pushfstring(L, "%s", strerror(errno));
34 lua_pushinteger(L, errno);
35 return 3;
36 }
37}
38
39
40static int io_execute (lua_State *L) {
41 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
42 return 1;
43}
44
45
46static int io_remove (lua_State *L) {
47 const char *filename = luaL_checkstring(L, 1);
48 return pushresult(L, remove(filename) == 0, filename);
49}
50
51
52static int io_rename (lua_State *L) {
53 const char *fromname = luaL_checkstring(L, 1);
54 const char *toname = luaL_checkstring(L, 2);
55 return pushresult(L, rename(fromname, toname) == 0, fromname);
56}
57
58
59static int io_tmpname (lua_State *L) {
60#if !USE_TMPNAME
61 luaL_error(L, "`tmpname' not supported");
62 return 0;
63#else
64 char buff[L_tmpnam];
65 if (tmpnam(buff) != buff)
66 return luaL_error(L, "unable to generate a unique filename in `tmpname'");
67 lua_pushstring(L, buff);
68 return 1;
69#endif
70}
71
72
73static int io_getenv (lua_State *L) {
74 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
75 return 1;
76}
77
78
79static int io_clock (lua_State *L) {
80 lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
81 return 1;
82}
83
84
85/*
86** {======================================================
87** Time/Date operations
88** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
89** wday=%w+1, yday=%j, isdst=? }
90** =======================================================
91*/
92
93static void setfield (lua_State *L, const char *key, int value) {
94 lua_pushstring(L, key);
95 lua_pushinteger(L, value);
96 lua_rawset(L, -3);
97}
98
99static void setboolfield (lua_State *L, const char *key, int value) {
100 lua_pushstring(L, key);
101 lua_pushboolean(L, value);
102 lua_rawset(L, -3);
103}
104
105static int getboolfield (lua_State *L, const char *key) {
106 int res;
107 lua_getfield(L, -1, key);
108 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
109 lua_pop(L, 1);
110 return res;
111}
112
113
114static int getfield (lua_State *L, const char *key, int d) {
115 int res;
116 lua_getfield(L, -1, key);
117 if (lua_isnumber(L, -1))
118 res = (int)lua_tointeger(L, -1);
119 else {
120 if (d < 0)
121 return luaL_error(L, "field `%s' missing in date table", key);
122 res = d;
123 }
124 lua_pop(L, 1);
125 return res;
126}
127
128
129static int io_date (lua_State *L) {
130 const char *s = luaL_optstring(L, 1, "%c");
131 lua_Number n = luaL_optnumber(L, 2, -1);
132 time_t t = (n == -1) ? time(NULL) : (time_t)n;
133 struct tm *stm;
134 if (*s == '!') { /* UTC? */
135 stm = gmtime(&t);
136 s++; /* skip `!' */
137 }
138 else
139 stm = localtime(&t);
140 if (stm == NULL) /* invalid date? */
141 lua_pushnil(L);
142 else if (strcmp(s, "*t") == 0) {
143 lua_createtable(L, 0, 9); /* 9 = number of fields */
144 setfield(L, "sec", stm->tm_sec);
145 setfield(L, "min", stm->tm_min);
146 setfield(L, "hour", stm->tm_hour);
147 setfield(L, "day", stm->tm_mday);
148 setfield(L, "month", stm->tm_mon+1);
149 setfield(L, "year", stm->tm_year+1900);
150 setfield(L, "wday", stm->tm_wday+1);
151 setfield(L, "yday", stm->tm_yday+1);
152 setboolfield(L, "isdst", stm->tm_isdst);
153 }
154 else {
155 char b[256];
156 if (strftime(b, sizeof(b), s, stm))
157 lua_pushstring(L, b);
158 else
159 return luaL_error(L, "`date' format too long");
160 }
161 return 1;
162}
163
164
165static int io_time (lua_State *L) {
166 time_t t;
167 if (lua_isnoneornil(L, 1)) /* called without args? */
168 t = time(NULL); /* get current time */
169 else {
170 struct tm ts;
171 luaL_checktype(L, 1, LUA_TTABLE);
172 lua_settop(L, 1); /* make sure table is at the top */
173 ts.tm_sec = getfield(L, "sec", 0);
174 ts.tm_min = getfield(L, "min", 0);
175 ts.tm_hour = getfield(L, "hour", 12);
176 ts.tm_mday = getfield(L, "day", -1);
177 ts.tm_mon = getfield(L, "month", -1) - 1;
178 ts.tm_year = getfield(L, "year", -1) - 1900;
179 ts.tm_isdst = getboolfield(L, "isdst");
180 t = mktime(&ts);
181 }
182 if (t == (time_t)(-1))
183 lua_pushnil(L);
184 else
185 lua_pushnumber(L, t);
186 return 1;
187}
188
189
190static int io_difftime (lua_State *L) {
191 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
192 (time_t)(luaL_optnumber(L, 2, 0))));
193 return 1;
194}
195
196/* }====================================================== */
197
198
199static int io_setloc (lua_State *L) {
200 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
201 LC_NUMERIC, LC_TIME};
202 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
203 "numeric", "time", NULL};
204 const char *l = lua_tostring(L, 1);
205 int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames);
206 luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
207 luaL_argcheck(L, op != -1, 2, "invalid option");
208 lua_pushstring(L, setlocale(cat[op], l));
209 return 1;
210}
211
212
213static int io_exit (lua_State *L) {
214 exit(luaL_optint(L, 1, EXIT_SUCCESS));
215 return 0; /* to avoid warnings */
216}
217
218static const luaL_reg syslib[] = {
219 {"clock", io_clock},
220 {"date", io_date},
221 {"difftime", io_difftime},
222 {"execute", io_execute},
223 {"exit", io_exit},
224 {"getenv", io_getenv},
225 {"remove", io_remove},
226 {"rename", io_rename},
227 {"setlocale", io_setloc},
228 {"time", io_time},
229 {"tmpname", io_tmpname},
230 {NULL, NULL}
231};
232
233/* }====================================================== */
234
235
236
237LUALIB_API int luaopen_os (lua_State *L) {
238 luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
239 return 1;
240}
241
src/lib/lstrlib.c+16−14
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstrlib.c,v 1.101 2004/01/02 11:54:14 roberto Exp $2** $Id: lstrlib.c,v 1.106 2004/08/09 13:30:33 roberto Exp $
3** Standard library for string operations and pattern-matching3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -12,6 +12,7 @@ · 6 unmodified lines
12#include <string.h>12#include <string.h>
13 13
14#define lstrlib_c14#define lstrlib_c
15#define LUA_LIB
15 16
16#include "lua.h"17#include "lua.h"
17 18
@@ -20,9 +21,7 @@ · 2 unmodified lines
20 21
21 22
22/* macro to `unsign' a character */23/* macro to `unsign' a character */
23#ifndef uchar
24#define uchar(c) ((unsigned char)(c))24#define uchar(c) ((unsigned char)(c))
25#endif
26 25
27 26
28typedef lua_Integer sint32; /* a signed version for size_t */27typedef lua_Integer sint32; /* a signed version for size_t */
@@ -108,11 +107,17 @@ static int str_rep (lua_State *L) { · 79 unmodified lines
108static int str_byte (lua_State *L) {107static int str_byte (lua_State *L) {
109 size_t l;108 size_t l;
110 const char *s = luaL_checklstring(L, 1, &l);109 const char *s = luaL_checklstring(L, 1, &l);
111 sint32 pos = posrelat(luaL_optinteger(L, 2, 1), l);110 sint32 posi = posrelat(luaL_optinteger(L, 2, 1), l);
112 if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */111 sint32 pose = posrelat(luaL_optinteger(L, 3, posi), l);
113 return 0; /* no answer */112 int n, i;
114 lua_pushinteger(L, uchar(s[pos-1]));113 if (posi <= 0) posi = 1;
115 return 1;114 if ((size_t)pose > l) pose = l;
115 if (posi > pose) return 0; /* empty interval; return no values */
116 n = pose - posi + 1;
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;
116}121}
117 122
118 123
@@ -134,15 +139,16 @@ static int str_char (lua_State *L) { · 15 unmodified lines
134static int writer (lua_State *L, const void* b, size_t size, void* B) {139static int writer (lua_State *L, const void* b, size_t size, void* B) {
135 (void)L;140 (void)L;
136 luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);141 luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
137 return 1;142 return 0;
138}143}
139 144
140 145
141static int str_dump (lua_State *L) {146static int str_dump (lua_State *L) {
142 luaL_Buffer b;147 luaL_Buffer b;
143 luaL_checktype(L, 1, LUA_TFUNCTION);148 luaL_checktype(L, 1, LUA_TFUNCTION);
149 lua_settop(L, 1);
144 luaL_buffinit(L,&b);150 luaL_buffinit(L,&b);
145 if (!lua_dump(L, writer, &b))151 if (lua_dump(L, writer, &b) != 0)
146 luaL_error(L, "unable to dump given function");152 luaL_error(L, "unable to dump given function");
147 luaL_pushresult(&b);153 luaL_pushresult(&b);
148 return 1;154 return 1;
@@ -156,10 +162,6 @@ static int str_dump (lua_State *L) { · 7 unmodified lines
156** =======================================================162** =======================================================
157*/163*/
158 164
159#ifndef MAX_CAPTURES
160#define MAX_CAPTURES 32 /* arbitrary limit */
161#endif
162
163 165
164#define CAP_UNFINISHED (-1)166#define CAP_UNFINISHED (-1)
165#define CAP_POSITION (-2)167#define CAP_POSITION (-2)
src/lib/ltablib.c+25−22
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltablib.c,v 1.22 2003/10/07 20:13:41 roberto Exp $2** $Id: ltablib.c,v 1.26 2004/06/15 13:37:21 roberto Exp $
3** Library for Table Manipulation3** Library for Table Manipulation
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <stddef.h>8#include <stddef.h>
9 9
10#define ltablib_c10#define ltablib_c
11#define LUA_LIB
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -22,7 +23,7 @@ static int luaB_foreachi (lua_State *L) { · 8 unmodified lines
22 int i;23 int i;
23 int n = aux_getn(L, 1);24 int n = aux_getn(L, 1);
24 luaL_checktype(L, 2, LUA_TFUNCTION);25 luaL_checktype(L, 2, LUA_TFUNCTION);
25 for (i=1; i<=n; i++) {26 for (i=LUA_FIRSTINDEX; i < n+LUA_FIRSTINDEX; i++) {
26 lua_pushvalue(L, 2); /* function */27 lua_pushvalue(L, 2); /* function */
27 lua_pushinteger(L, i); /* 1st argument */28 lua_pushinteger(L, i); /* 1st argument */
28 lua_rawgeti(L, 1, i); /* 2nd argument */29 lua_rawgeti(L, 1, i); /* 2nd argument */
@@ -62,25 +63,26 @@ static int luaB_getn (lua_State *L) { · 33 unmodified lines
62static int luaB_setn (lua_State *L) {63static int luaB_setn (lua_State *L) {
63 luaL_checktype(L, 1, LUA_TTABLE);64 luaL_checktype(L, 1, LUA_TTABLE);
64 luaL_setn(L, 1, luaL_checkint(L, 2));65 luaL_setn(L, 1, luaL_checkint(L, 2));
65 return 0;66 lua_pushvalue(L, 1);
67 return 1;
66}68}
67 69
68 70
69static int luaB_tinsert (lua_State *L) {71static int luaB_tinsert (lua_State *L) {
70 int v = lua_gettop(L); /* number of arguments */72 int v = lua_gettop(L); /* number of arguments */
71 int n = aux_getn(L, 1) + 1;73 int e = aux_getn(L, 1) + LUA_FIRSTINDEX; /* first empty element */
72 int pos; /* where to insert new element */74 int pos; /* where to insert new element */
73 if (v == 2) /* called with only 2 arguments */75 if (v == 2) /* called with only 2 arguments */
74 pos = n; /* insert new element at the end */76 pos = e; /* insert new element at the end */
75 else {77 else {
76 pos = luaL_checkint(L, 2); /* 2nd argument is the position */78 pos = luaL_checkint(L, 2); /* 2nd argument is the position */
77 if (pos > n) n = pos; /* `grow' array if necessary */79 if (pos > e) e = pos; /* `grow' array if necessary */
78 v = 3; /* function may be called with more than 3 args */80 v = 3; /* function may be called with more than 3 args */
79 }81 }
80 luaL_setn(L, 1, n); /* new size */82 luaL_setn(L, 1, e - LUA_FIRSTINDEX + 1); /* new size */
81 while (--n >= pos) { /* move up elements */83 while (--e >= pos) { /* move up elements */
82 lua_rawgeti(L, 1, n);84 lua_rawgeti(L, 1, e);
83 lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */85 lua_rawseti(L, 1, e+1); /* t[e+1] = t[e] */
84 }86 }
85 lua_pushvalue(L, v);87 lua_pushvalue(L, v);
86 lua_rawseti(L, 1, pos); /* t[pos] = v */88 lua_rawseti(L, 1, pos); /* t[pos] = v */
@@ -89,17 +91,17 @@ static int luaB_tinsert (lua_State *L) { · 2 unmodified lines
89 91
90 92
91static int luaB_tremove (lua_State *L) {93static int luaB_tremove (lua_State *L) {
92 int n = aux_getn(L, 1);94 int e = aux_getn(L, 1) + LUA_FIRSTINDEX - 1;
93 int pos = luaL_optint(L, 2, n);95 int pos = luaL_optint(L, 2, e);
94 if (n <= 0) return 0; /* table is `empty' */96 if (e < LUA_FIRSTINDEX) return 0; /* table is `empty' */
95 luaL_setn(L, 1, n-1); /* t.n = n-1 */97 luaL_setn(L, 1, e - LUA_FIRSTINDEX); /* t.n = n-1 */
96 lua_rawgeti(L, 1, pos); /* result = t[pos] */98 lua_rawgeti(L, 1, pos); /* result = t[pos] */
97 for ( ;pos<n; pos++) {99 for ( ;pos<e; pos++) {
98 lua_rawgeti(L, 1, pos+1);100 lua_rawgeti(L, 1, pos+1);
99 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */101 lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
100 }102 }
101 lua_pushnil(L);103 lua_pushnil(L);
102 lua_rawseti(L, 1, n); /* t[n] = nil */104 lua_rawseti(L, 1, e); /* t[e] = nil */
103 return 1;105 return 1;
104}106}
105 107
@@ -108,16 +110,17 @@ static int str_concat (lua_State *L) { · 2 unmodified lines
108 luaL_Buffer b;110 luaL_Buffer b;
109 size_t lsep;111 size_t lsep;
110 const char *sep = luaL_optlstring(L, 2, "", &lsep);112 const char *sep = luaL_optlstring(L, 2, "", &lsep);
111 int i = luaL_optint(L, 3, 1);113 int i = luaL_optint(L, 3, LUA_FIRSTINDEX);
112 int n = luaL_optint(L, 4, 0);114 int last = luaL_optint(L, 4, -2);
113 luaL_checktype(L, 1, LUA_TTABLE);115 luaL_checktype(L, 1, LUA_TTABLE);
114 if (n == 0) n = luaL_getn(L, 1);116 if (last == -2)
117 last = luaL_getn(L, 1) + LUA_FIRSTINDEX - 1;
115 luaL_buffinit(L, &b);118 luaL_buffinit(L, &b);
116 for (; i <= n; i++) {119 for (; i <= last; i++) {
117 lua_rawgeti(L, 1, i);120 lua_rawgeti(L, 1, i);
118 luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");121 luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");
119 luaL_addvalue(&b);122 luaL_addvalue(&b);
120 if (i != n)123 if (i != last)
121 luaL_addlstring(&b, sep, lsep);124 luaL_addlstring(&b, sep, lsep);
122 }125 }
123 luaL_pushresult(&b);126 luaL_pushresult(&b);
@@ -223,7 +226,7 @@ static int luaB_sort (lua_State *L) { · 99 unmodified lines
223 if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */226 if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
224 luaL_checktype(L, 2, LUA_TFUNCTION);227 luaL_checktype(L, 2, LUA_TFUNCTION);
225 lua_settop(L, 2); /* make sure there is two arguments */228 lua_settop(L, 2); /* make sure there is two arguments */
226 auxsort(L, 1, n);229 auxsort(L, LUA_FIRSTINDEX, n + LUA_FIRSTINDEX - 1);
227 return 0;230 return 0;
228}231}
229 232
src/llex.c+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: llex.c,v 2.2 2004/03/12 19:53:56 roberto Exp $2** $Id: llex.c,v 2.3 2004/04/30 20:13:38 roberto Exp $
3** Lexical Analyzer3** Lexical Analyzer
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -9,6 +9,7 @@ · 3 unmodified lines
9#include <string.h>9#include <string.h>
10 10
11#define llex_c11#define llex_c
12#define LUA_CORE
12 13
13#include "lua.h"14#include "lua.h"
14 15
src/llimits.h+2−95
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: llimits.h,v 1.57 2003/12/01 16:33:30 roberto Exp $2** $Id: llimits.h,v 1.59 2004/06/23 15:57:29 roberto Exp $
3** Limits, basic types, and some other `installation-dependent' definitions3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -15,48 +15,9 @@ · 9 unmodified lines
15#include "lua.h"15#include "lua.h"
16 16
17 17
18/*
19** try to find number of bits in an integer
20*/
21#ifndef BITS_INT
22/* avoid overflows in comparison */
23#if INT_MAX-20 < 32760
24#define BITS_INT 16
25#elif INT_MAX > 2147483640L
26/* machine has at least 32 bits */
27#define BITS_INT 32
28#else
29#error "you must define BITS_INT with number of bits in an integer"
30#endif
31#endif
32
33
34/*
35** the following types define integer types for values that may not
36** fit in a `small int' (16 bits), but may waste space in a
37** `large long' (64 bits). The current definitions should work in
38** any machine, but may not be optimal.
39*/
40
41
42/*
43** an unsigned integer with at least 32 bits
44*/
45#ifndef LUA_UINT32
46#define LUA_UINT32 unsigned long
47#endif
48 18
49typedef LUA_UINT32 lu_int32;19typedef LUA_UINT32 lu_int32;
50 20
51
52/*
53** a signed integer with at least 32 bits
54*/
55#ifndef LUA_INT32
56#define LUA_INT32 long
57#define LUA_MAXINT32 LONG_MAX
58#endif
59
60typedef LUA_INT32 l_int32;21typedef LUA_INT32 l_int32;
61 22
62 23
@@ -95,24 +56,11 @@ typedef unsigned char lu_byte; · 32 unmodified lines
95 56
96 57
97/* type to ensure maximum alignment */58/* type to ensure maximum alignment */
98#ifndef LUSER_ALIGNMENT_T
99typedef union { double u; void *s; long l; } L_Umaxalign;
100#else
101typedef LUSER_ALIGNMENT_T L_Umaxalign;59typedef LUSER_ALIGNMENT_T L_Umaxalign;
102#endif
103 60
104 61
105/* result of `usual argument conversion' over lua_Number */62/* result of a `usual argument conversion' over lua_Number */
106#ifndef LUA_UACNUMBER
107typedef double l_uacNumber;
108#else
109typedef LUA_UACNUMBER l_uacNumber;63typedef LUA_UACNUMBER l_uacNumber;
110#endif
111
112
113#ifndef lua_assert
114#define lua_assert(c) /* empty */
115#endif
116 64
117 65
118#ifndef check_exp66#ifndef check_exp
@@ -138,43 +86,11 @@ typedef LUA_UACNUMBER l_uacNumber; · 19 unmodified lines
138typedef lu_int32 Instruction;86typedef lu_int32 Instruction;
139 87
140 88
141/* maximum depth for calls (unsigned short) */
142#ifndef LUA_MAXCALLS
143#define LUA_MAXCALLS 4096
144#endif
145
146
147/*
148** maximum depth for C calls (unsigned short): Not too big, or may
149** overflow the C stack...
150*/
151
152#ifndef LUA_MAXCCALLS
153#define LUA_MAXCCALLS 200
154#endif
155
156
157/* maximum size for the virtual stack of a C function */
158#ifndef LUA_MAXCSTACK
159#define LUA_MAXCSTACK 2048
160#endif
161
162 89
163/* maximum stack for a Lua function */90/* maximum stack for a Lua function */
164#define MAXSTACK 25091#define MAXSTACK 250
165 92
166 93
167/* maximum number of variables declared in a function */
168#ifndef MAXVARS
169#define MAXVARS 200 /* <MAXSTACK */
170#endif
171
172
173/* maximum number of upvalues per function */
174#ifndef MAXUPVALUES
175#define MAXUPVALUES 32 /* <MAXSTACK */
176#endif
177
178 94
179/* minimum size for the string table (must be power of 2) */95/* minimum size for the string table (must be power of 2) */
180#ifndef MINSTRTABSIZE96#ifndef MINSTRTABSIZE
@@ -188,13 +104,4 @@ typedef lu_int32 Instruction; · 7 unmodified lines
188#endif104#endif
189 105
190 106
191/*
192** maximum number of syntactical nested non-terminals: Not too big,
193** or may overflow the C stack...
194*/
195#ifndef LUA_MAXPARSERLEVEL
196#define LUA_MAXPARSERLEVEL 200
197#endif
198
199
200#endif107#endif
src/lmem.c+3−3
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lmem.c,v 1.63 2003/11/27 18:18:37 roberto Exp $2** $Id: lmem.c,v 1.65 2004/08/30 13:44:44 roberto Exp $
3** Interface to Memory Manager3** Interface to Memory Manager
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <stddef.h>8#include <stddef.h>
9 9
10#define lmem_c10#define lmem_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -76,8 +77,7 @@ void *luaM_realloc (lua_State *L, void *block, lu_mem osize, lu_mem nsize) { · 62 unmodified lines
76 if (block == NULL && nsize > 0)77 if (block == NULL && nsize > 0)
77 luaD_throw(L, LUA_ERRMEM);78 luaD_throw(L, LUA_ERRMEM);
78 lua_assert((nsize == 0) == (block == NULL));79 lua_assert((nsize == 0) == (block == NULL));
79 g->nblocks -= osize;80 g->totalbytes = (g->totalbytes - osize) + nsize;
80 g->nblocks += nsize;
81 return block;81 return block;
82}82}
83 83
src/lobject.c+18−12
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lobject.c,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: lobject.c,v 2.4 2004/07/09 16:01:38 roberto Exp $
3** Some generic functions over Lua objects3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -10,6 +10,7 @@ · 4 unmodified lines
10#include <string.h>10#include <string.h>
11 11
12#define lobject_c12#define lobject_c
13#define LUA_CORE
13 14
14#include "lua.h"15#include "lua.h"
15 16
@@ -21,11 +22,6 @@ · 5 unmodified lines
21#include "lvm.h"22#include "lvm.h"
22 23
23 24
24/* function to convert a string to a lua_Number */
25#ifndef lua_str2number
26#define lua_str2number(s,p) strtod((s), (p))
27#endif
28
29 25
30const TValue luaO_nilobject = {LUA_TNIL, {NULL}};26const TValue luaO_nilobject = {LUA_TNIL, {NULL}};
31 27
@@ -98,7 +94,7 @@ static void pushstr (lua_State *L, const char *str) { · 66 unmodified lines
98}94}
99 95
100 96
101/* this function handles only `%d', `%c', %f, and `%s' formats */97/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
102const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {98const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
103 int n = 1;99 int n = 1;
104 pushstr(L, "");100 pushstr(L, "");
@@ -108,9 +104,10 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 3 unmodified lines
108 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));104 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
109 incr_top(L);105 incr_top(L);
110 switch (*(e+1)) {106 switch (*(e+1)) {
111 case 's':107 case 's': {
112 pushstr(L, va_arg(argp, char *));108 pushstr(L, va_arg(argp, char *));
113 break;109 break;
110 }
114 case 'c': {111 case 'c': {
115 char buff[2];112 char buff[2];
116 buff[0] = cast(char, va_arg(argp, int));113 buff[0] = cast(char, va_arg(argp, int));
@@ -118,17 +115,26 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 1 unmodified line
118 pushstr(L, buff);115 pushstr(L, buff);
119 break;116 break;
120 }117 }
121 case 'd':118 case 'd': {
122 setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));119 setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
123 incr_top(L);120 incr_top(L);
124 break;121 break;
125 case 'f':122 }
123 case 'f': {
126 setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));124 setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
127 incr_top(L);125 incr_top(L);
128 break;126 break;
129 case '%':127 }
128 case 'p': {
129 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
130 sprintf(buff, "%p", va_arg(argp, void *));
131 pushstr(L, buff);
132 break;
133 }
134 case '%': {
130 pushstr(L, "%");135 pushstr(L, "%");
131 break;136 break;
137 }
132 default: {138 default: {
133 char buff[3];139 char buff[3];
134 buff[0] = '%';140 buff[0] = '%';
@@ -177,7 +183,7 @@ void luaO_chunkid (char *out, const char *source, int bufflen) { · 42 unmodified lines
177 strcat(out, source);183 strcat(out, source);
178 }184 }
179 else { /* out = [string "string"] */185 else { /* out = [string "string"] */
180 int len = strcspn(source, "\n"); /* stop at first newline */186 int len = strcspn(source, "\n\r"); /* stop at first newline */
181 bufflen -= sizeof(" [string \"...\"] ");187 bufflen -= sizeof(" [string \"...\"] ");
182 if (len > bufflen) len = bufflen;188 if (len > bufflen) len = bufflen;
183 strcpy(out, "[string \"");189 strcpy(out, "[string \"");
src/lobject.h+5−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lobject.h,v 2.4 2004/03/15 21:04:33 roberto Exp $2** $Id: lobject.h,v 2.5 2004/05/31 18:51:50 roberto Exp $
3** Type definitions for Lua objects3** Type definitions for Lua objects
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -249,6 +249,10 @@ typedef struct Proto { · 243 unmodified lines
249} Proto;249} Proto;
250 250
251 251
252/* mask for new-style vararg */
253#define NEWSTYLEVARARG 2
254
255
252typedef struct LocVar {256typedef struct LocVar {
253 TString *varname;257 TString *varname;
254 int startpc; /* first point where variable is active */258 int startpc; /* first point where variable is active */
src/lopcodes.c+5−5
@@ -1,10 +1,11 @@
1/*1/*
2** $Id: lopcodes.c,v 1.25 2003/05/14 21:09:53 roberto Exp $2** $Id: lopcodes.c,v 1.28 2004/07/16 13:15:32 roberto Exp $
3** See Copyright Notice in lua.h3** See Copyright Notice in lua.h
4*/4*/
5 5
6 6
7#define lopcodes_c7#define lopcodes_c
8#define LUA_CORE
8 9
9#include "lua.h"10#include "lua.h"
10 11
@@ -14,8 +15,6 @@ · 3 unmodified lines
14 15
15/* ORDER OP */16/* ORDER OP */
16 17
17#ifdef LUA_OPNAMES
18
19const char *const luaP_opnames[NUM_OPCODES] = {18const char *const luaP_opnames[NUM_OPCODES] = {
20 "MOVE",19 "MOVE",
21 "LOADK",20 "LOADK",
@@ -52,10 +51,10 @@ const char *const luaP_opnames[NUM_OPCODES] = { · 30 unmodified lines
52 "SETLIST",51 "SETLIST",
53 "SETLISTO",52 "SETLISTO",
54 "CLOSE",53 "CLOSE",
55 "CLOSURE"54 "CLOSURE",
55 "VARARG"
56};56};
57 57
58#endif
59 58
60#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))59#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
61 60
@@ -97,5 +96,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { · 35 unmodified lines
97 ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */96 ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */
98 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */97 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
99 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */98 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
99 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
100};100};
101 101
src/lopcodes.h+41−17
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lopcodes.h,v 1.106 2003/05/15 19:46:03 roberto Exp $2** $Id: lopcodes.h,v 1.111 2004/08/04 20:18:13 roberto Exp $
3** Opcodes for Lua virtual machine3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -41,18 +41,19 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ · 35 unmodified lines
41 41
42#define SIZE_OP 642#define SIZE_OP 6
43 43
44#define POS_C SIZE_OP44#define POS_OP 0
45#define POS_A (POS_OP + SIZE_OP)
46#define POS_C (POS_A + SIZE_A)
45#define POS_B (POS_C + SIZE_C)47#define POS_B (POS_C + SIZE_C)
46#define POS_Bx POS_C48#define POS_Bx POS_C
47#define POS_A (POS_B + SIZE_B)
48 49
49 50
50/*51/*
51** limits for opcode arguments.52** limits for opcode arguments.
52** we use (signed) int to manipulate most arguments,53** we use (signed) int to manipulate most arguments,
53** so they must fit in BITS_INT-1 bits (-1 for sign)54** so they must fit in LUA_BITSINT-1 bits (-1 for sign)
54*/55*/
55#if SIZE_Bx < BITS_INT-156#if SIZE_Bx < LUA_BITSINT-1
56#define MAXARG_Bx ((1<<SIZE_Bx)-1)57#define MAXARG_Bx ((1<<SIZE_Bx)-1)
57#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */58#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
58#else59#else
@@ -76,10 +77,11 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ · 17 unmodified lines
76** the following macros help to manipulate instructions77** the following macros help to manipulate instructions
77*/78*/
78 79
79#define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0)))80#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
80#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)))81#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82 ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
81 83
82#define GETARG_A(i) (cast(int, (i)>>POS_A))84#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
83#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \85#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
84 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))86 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
85 87
@@ -99,16 +101,33 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ · 13 unmodified lines
99#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))101#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
100 102
101 103
102#define CREATE_ABC(o,a,b,c) (cast(Instruction, o) \104#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
103 | (cast(Instruction, a)<<POS_A) \105 | (cast(Instruction, a)<<POS_A) \
104 | (cast(Instruction, b)<<POS_B) \106 | (cast(Instruction, b)<<POS_B) \
105 | (cast(Instruction, c)<<POS_C))107 | (cast(Instruction, c)<<POS_C))
106 108
107#define CREATE_ABx(o,a,bc) (cast(Instruction, o) \109#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
108 | (cast(Instruction, a)<<POS_A) \110 | (cast(Instruction, a)<<POS_A) \
109 | (cast(Instruction, bc)<<POS_Bx))111 | (cast(Instruction, bc)<<POS_Bx))
110 112
111 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)
112 131
113 132
114/*133/*
@@ -120,7 +139,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ · 5 unmodified lines
120/*139/*
121** R(x) - register140** R(x) - register
122** Kst(x) - constant (in constant table)141** Kst(x) - constant (in constant table)
123** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)142** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
124*/143*/
125 144
126 145
@@ -183,25 +202,30 @@ OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */ · 56 unmodified lines
183OP_SETLISTO,/* A Bx */202OP_SETLISTO,/* A Bx */
184 203
185OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/204OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
186OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */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 */
187} OpCode;208} OpCode;
188 209
189 210
190#define NUM_OPCODES (cast(int, OP_CLOSURE+1))211#define NUM_OPCODES (cast(int, OP_VARARG+1))
191 212
192 213
193 214
194/*===========================================================================215/*===========================================================================
195 Notes:216 Notes:
196 (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,217 (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
197 and can be 0: OP_CALL then sets `top' to last_result+1, so218 and can be 0: OP_CALL then sets `top' to last_result+1, so
198 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.219 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
199 220
200 (2) In OP_RETURN, if (B == 0) then return up to `top'221 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222 set top (like in OP_CALL).
223
224 (*) In OP_RETURN, if (B == 0) then return up to `top'
201 225
202 (3) For comparisons, B specifies what conditions the test should accept.226 (*) For comparisons, B specifies what conditions the test should accept.
203 227
204 (4) All `skips' (pc++) assume that next instruction is a jump228 (*) All `skips' (pc++) assume that next instruction is a jump
205===========================================================================*/229===========================================================================*/
206 230
207 231
src/lparser.c+33−35
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lparser.c,v 2.2 2004/03/12 19:53:56 roberto Exp $2** $Id: lparser.c,v 2.5 2004/05/31 18:51:50 roberto Exp $
3** Lua Parser3** Lua Parser
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <string.h>8#include <string.h>
9 9
10#define lparser_c10#define lparser_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -26,6 +27,8 @@ · 12 unmodified lines
26 27
27 28
28 29
30#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
31
29#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])32#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
30 33
31#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) luaY_errorlimit(fs,l,m)34#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) luaY_errorlimit(fs,l,m)
@@ -271,11 +274,11 @@ static TString *singlevar (LexState *ls, expdesc *var, int base) { · 239 unmodified lines
271static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {274static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
272 FuncState *fs = ls->fs;275 FuncState *fs = ls->fs;
273 int extra = nvars - nexps;276 int extra = nvars - nexps;
274 if (e->k == VCALL) {277 if (hasmultret(e->k)) {
275 extra++; /* includes call itself */278 extra++; /* includes call itself */
276 if (extra <= 0) extra = 0;279 if (extra < 0) extra = 0;
277 else luaK_reserveregs(fs, extra-1);280 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
278 luaK_setcallreturns(fs, e, extra); /* call provides the difference */281 if (extra > 1) luaK_reserveregs(fs, extra-1);
279 }282 }
280 else {283 else {
281 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */284 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
@@ -391,6 +394,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { · 109 unmodified lines
391 lexstate.nestlevel = 0;394 lexstate.nestlevel = 0;
392 luaX_setinput(L, &lexstate, z, luaS_new(L, name));395 luaX_setinput(L, &lexstate, z, luaS_new(L, name));
393 open_func(&lexstate, &funcstate);396 open_func(&lexstate, &funcstate);
397 funcstate.f->is_vararg = NEWSTYLEVARARG;
394 next(&lexstate); /* read first token */398 next(&lexstate); /* read first token */
395 chunk(&lexstate);399 chunk(&lexstate);
396 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");400 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
@@ -480,9 +484,10 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) { · 83 unmodified lines
480 484
481static void lastlistfield (FuncState *fs, struct ConsControl *cc) {485static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
482 if (cc->tostore == 0) return;486 if (cc->tostore == 0) return;
483 if (cc->v.k == VCALL) {487 if (hasmultret(cc->v.k)) {
484 luaK_setcallreturns(fs, &cc->v, LUA_MULTRET);488 luaK_setmultret(fs, &cc->v);
485 luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);489 luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
490 cc->na--; /* do not count last expression (unknown number of elements) */
486 }491 }
487 else {492 else {
488 if (cc->v.k != VVOID)493 if (cc->v.k != VVOID)
@@ -556,12 +561,8 @@ static void parlist (LexState *ls) { · 67 unmodified lines
556 if (ls->t.token != ')') { /* is `parlist' not empty? */561 if (ls->t.token != ')') { /* is `parlist' not empty? */
557 do {562 do {
558 switch (ls->t.token) {563 switch (ls->t.token) {
559 case TK_NAME: { /* param -> NAME [ `=' `...' ] */564 case TK_NAME: { /* param -> NAME */
560 new_localvar(ls, str_checkname(ls), nparams++);565 new_localvar(ls, str_checkname(ls), nparams++);
561 if (testnext(ls, '=')) {
562 check(ls, TK_DOTS);
563 f->is_vararg = 1;
564 }
565 break;566 break;
566 }567 }
567 case TK_DOTS: { /* param -> `...' */568 case TK_DOTS: { /* param -> `...' */
@@ -627,7 +628,7 @@ static void funcargs (LexState *ls, expdesc *f) { · 59 unmodified lines
627 args.k = VVOID;628 args.k = VVOID;
628 else {629 else {
629 explist1(ls, &args);630 explist1(ls, &args);
630 luaK_setcallreturns(fs, &args, LUA_MULTRET);631 luaK_setmultret(fs, &args);
631 }632 }
632 check_match(ls, ')', '(', line);633 check_match(ls, ')', '(', line);
633 break;634 break;
@@ -648,7 +649,7 @@ static void funcargs (LexState *ls, expdesc *f) { · 14 unmodified lines
648 }649 }
649 lua_assert(f->k == VNONRELOC);650 lua_assert(f->k == VNONRELOC);
650 base = f->info; /* base register for call */651 base = f->info; /* base register for call */
651 if (args.k == VCALL)652 if (hasmultret(args.k))
652 nparams = LUA_MULTRET; /* open call */653 nparams = LUA_MULTRET; /* open call */
653 else {654 else {
654 if (args.k != VVOID)655 if (args.k != VVOID)
@@ -737,43 +738,47 @@ static void simpleexp (LexState *ls, expdesc *v) { · 82 unmodified lines
737 switch (ls->t.token) {738 switch (ls->t.token) {
738 case TK_NUMBER: {739 case TK_NUMBER: {
739 init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r));740 init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r));
740 next(ls); /* must use `seminfo' before `next' */
741 break;741 break;
742 }742 }
743 case TK_STRING: {743 case TK_STRING: {
744 codestring(ls, v, ls->t.seminfo.ts);744 codestring(ls, v, ls->t.seminfo.ts);
745 next(ls); /* must use `seminfo' before `next' */
746 break;745 break;
747 }746 }
748 case TK_NIL: {747 case TK_NIL: {
749 init_exp(v, VNIL, 0);748 init_exp(v, VNIL, 0);
750 next(ls);
751 break;749 break;
752 }750 }
753 case TK_TRUE: {751 case TK_TRUE: {
754 init_exp(v, VTRUE, 0);752 init_exp(v, VTRUE, 0);
755 next(ls);
756 break;753 break;
757 }754 }
758 case TK_FALSE: {755 case TK_FALSE: {
759 init_exp(v, VFALSE, 0);756 init_exp(v, VFALSE, 0);
760 next(ls);757 break;
758 }
759 case TK_DOTS: { /* vararg */
760 FuncState *fs = ls->fs;
761 check_condition(ls, fs->f->is_vararg,
762 "cannot use `...' outside a vararg function");
763 fs->f->is_vararg = NEWSTYLEVARARG;
764 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
761 break;765 break;
762 }766 }
763 case '{': { /* constructor */767 case '{': { /* constructor */
764 constructor(ls, v);768 constructor(ls, v);
765 break;769 return;
766 }770 }
767 case TK_FUNCTION: {771 case TK_FUNCTION: {
768 next(ls);772 next(ls);
769 body(ls, v, 0, ls->linenumber);773 body(ls, v, 0, ls->linenumber);
770 break;774 return;
771 }775 }
772 default: {776 default: {
773 primaryexp(ls, v);777 primaryexp(ls, v);
774 break;778 return;
775 }779 }
776 }780 }
781 next(ls);
777}782}
778 783
779 784
@@ -950,7 +955,7 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { · 170 unmodified lines
950 ls->fs->freereg -= nexps - nvars; /* remove extra values */955 ls->fs->freereg -= nexps - nvars; /* remove extra values */
951 }956 }
952 else {957 else {
953 luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */958 luaK_setoneret(ls->fs, &e); /* close last expression */
954 luaK_storevar(ls->fs, &lh->v, &e);959 luaK_storevar(ls->fs, &lh->v, &e);
955 return; /* avoid default */960 return; /* avoid default */
956 }961 }
@@ -976,12 +981,6 @@ static int cond (LexState *ls) { · 19 unmodified lines
976** after its body (and thus avoiding one jump in the loop).981** after its body (and thus avoiding one jump in the loop).
977*/982*/
978 983
979/*
980** maximum size of expressions for optimizing `while' code
981*/
982#ifndef MAXEXPWHILE
983#define MAXEXPWHILE 100
984#endif
985 984
986/*985/*
987** the call `luaK_goiffalse' may grow the size of an expression by986** the call `luaK_goiffalse' may grow the size of an expression by
@@ -1240,9 +1239,8 @@ static void exprstat (LexState *ls) { · 252 unmodified lines
1240 FuncState *fs = ls->fs;1239 FuncState *fs = ls->fs;
1241 struct LHS_assign v;1240 struct LHS_assign v;
1242 primaryexp(ls, &v.v);1241 primaryexp(ls, &v.v);
1243 if (v.v.k == VCALL) { /* stat -> func */1242 if (v.v.k == VCALL) /* stat -> func */
1244 luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */1243 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1245 }
1246 else { /* stat -> assignment */1244 else { /* stat -> assignment */
1247 v.prev = NULL;1245 v.prev = NULL;
1248 assignment(ls, &v, 1);1246 assignment(ls, &v, 1);
@@ -1260,9 +1258,9 @@ static void retstat (LexState *ls) { · 11 unmodified lines
1260 first = nret = 0; /* return no values */1258 first = nret = 0; /* return no values */
1261 else {1259 else {
1262 nret = explist1(ls, &e); /* optional return values */1260 nret = explist1(ls, &e); /* optional return values */
1263 if (e.k == VCALL) {1261 if (hasmultret(e.k)) {
1264 luaK_setcallreturns(fs, &e, LUA_MULTRET);1262 luaK_setmultret(fs, &e);
1265 if (nret == 1) { /* tail call? */1263 if (e.k == VCALL && nret == 1) { /* tail call? */
1266 SET_OPCODE(getcode(fs,&e), OP_TAILCALL);1264 SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1267 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);1265 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1268 }1266 }
src/lparser.h+3−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lparser.h,v 1.50 2003/08/25 19:51:54 roberto Exp $2** $Id: lparser.h,v 1.51 2004/05/31 18:51:50 roberto Exp $
3** Lua Parser3** Lua Parser
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -30,7 +30,8 @@ typedef enum { · 24 unmodified lines
30 VJMP, /* info = instruction pc */30 VJMP, /* info = instruction pc */
31 VRELOCABLE, /* info = instruction pc */31 VRELOCABLE, /* info = instruction pc */
32 VNONRELOC, /* info = result register */32 VNONRELOC, /* info = result register */
33 VCALL /* info = result register */33 VCALL, /* info = instruction pc */
34 VVARARG /* info = instruction pc */
34} expkind;35} expkind;
35 36
36typedef struct expdesc {37typedef struct expdesc {
src/lstate.c+22−10
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstate.c,v 2.5 2004/03/23 12:57:12 roberto Exp $2** $Id: lstate.c,v 2.12 2004/08/30 13:44:44 roberto Exp $
3** Global State3** Global State
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <stddef.h>8#include <stddef.h>
9 9
10#define lstate_c10#define lstate_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -56,6 +57,7 @@ static void stack_init (lua_State *L1, lua_State *L) { · 42 unmodified lines
56 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;57 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
57 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);58 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
58 L1->ci = L1->base_ci;59 L1->ci = L1->base_ci;
60 L1->ci->func = L1->top;
59 setnilvalue(L1->top++); /* `function' entry for this `ci' */61 setnilvalue(L1->top++); /* `function' entry for this `ci' */
60 L1->base = L1->ci->base = L1->top;62 L1->base = L1->ci->base = L1->top;
61 L1->ci->top = L1->top + LUA_MINSTACK;63 L1->ci->top = L1->top + LUA_MINSTACK;
@@ -75,22 +77,25 @@ static void freestack (lua_State *L, lua_State *L1) { · 13 unmodified lines
75*/77*/
76static void f_luaopen (lua_State *L, void *ud) {78static void f_luaopen (lua_State *L, void *ud) {
77 Udata *u; /* head of udata list */79 Udata *u; /* head of udata list */
80 global_State *g = G(L);
78 UNUSED(ud);81 UNUSED(ud);
79 u = cast(Udata *, luaM_malloc(L, sizeudata(0)));82 u = cast(Udata *, luaM_malloc(L, sizeudata(0)));
80 u->uv.len = 0;83 u->uv.len = 0;
81 u->uv.metatable = NULL;84 u->uv.metatable = NULL;
82 G(L)->firstudata = obj2gco(u);85 g->firstudata = obj2gco(u);
83 luaC_link(L, obj2gco(u), LUA_TUSERDATA);86 luaC_link(L, obj2gco(u), LUA_TUSERDATA);
84 setbit(u->uv.marked, FIXEDBIT);87 setbit(u->uv.marked, FIXEDBIT);
85 setbit(L->marked, FIXEDBIT);88 setbit(L->marked, FIXEDBIT);
86 stack_init(L, L); /* init stack */89 stack_init(L, L); /* init stack */
87 sethvalue(L, gt(L), luaH_new(L, 0, 4)); /* table of globals */90 sethvalue(L, gt(L), luaH_new(L, 0, 4)); /* table of globals */
91 hvalue(gt(L))->metatable = luaH_new(L, 0, 0); /* globals metatable */
88 sethvalue(L, registry(L), luaH_new(L, 4, 4)); /* registry */92 sethvalue(L, registry(L), luaH_new(L, 4, 4)); /* registry */
89 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */93 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
90 luaT_init(L);94 luaT_init(L);
91 luaX_init(L);95 luaX_init(L);
92 luaS_fix(luaS_newliteral(L, MEMERRMSG));96 luaS_fix(luaS_newliteral(L, MEMERRMSG));
93 G(L)->GCthreshold = 4*G(L)->nblocks;97 g->GCthreshold = 4*g->totalbytes;
98 g->prevestimate = g->estimate = g->totalbytes;
94}99}
95 100
96 101
@@ -119,12 +124,13 @@ static void preinit_state (lua_State *L, global_State *g) { · 22 unmodified lines
119static void close_state (lua_State *L) {124static void close_state (lua_State *L) {
120 global_State *g = G(L);125 global_State *g = G(L);
121 luaF_close(L, L->stack); /* close all upvalues for this thread */126 luaF_close(L, L->stack); /* close all upvalues for this thread */
122 luaC_sweepall(L); /* collect all elements */127 luaC_freeall(L); /* collect all objects */
123 lua_assert(g->rootgc == obj2gco(L));128 lua_assert(g->rootgc == NULL);
124 luaS_freeall(L);129 lua_assert(g->strt.nuse == 0);
130 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
125 luaZ_freebuffer(L, &g->buff);131 luaZ_freebuffer(L, &g->buff);
126 freestack(L, L);132 freestack(L, L);
127 lua_assert(g->nblocks == sizeof(LG));133 lua_assert(g->totalbytes == sizeof(LG));
128 (*g->realloc)(g->ud, fromstate(L), state_size(LG), 0);134 (*g->realloc)(g->ud, fromstate(L), state_size(LG), 0);
129}135}
130 136
@@ -136,6 +142,10 @@ lua_State *luaE_newthread (lua_State *L) { · 5 unmodified lines
136 preinit_state(L1, G(L));142 preinit_state(L1, G(L));
137 stack_init(L1, L); /* init stack */143 stack_init(L1, L); /* init stack */
138 setobj2n(L, gt(L1), gt(L)); /* share table of globals */144 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
145 L1->hookmask = L->hookmask;
146 L1->basehookcount = L->basehookcount;
147 L1->hook = L->hook;
148 resethookcount(L1);
139 lua_assert(iswhite(obj2gco(L1)));149 lua_assert(iswhite(obj2gco(L1)));
140 return L1;150 return L1;
141}151}
@@ -169,7 +179,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 27 unmodified lines
169 setnilvalue(registry(L));179 setnilvalue(registry(L));
170 luaZ_initbuffer(L, &g->buff);180 luaZ_initbuffer(L, &g->buff);
171 g->panic = NULL;181 g->panic = NULL;
172 g->gcstate = GCSfinalize;182 g->gcstate = GCSpause;
183 g->gcgenerational = 0;
173 g->rootgc = obj2gco(L);184 g->rootgc = obj2gco(L);
174 g->sweepstrgc = 0;185 g->sweepstrgc = 0;
175 g->sweepgc = &g->rootgc;186 g->sweepgc = &g->rootgc;
@@ -181,13 +192,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 5 unmodified lines
181 setnilvalue(gkey(g->dummynode));192 setnilvalue(gkey(g->dummynode));
182 setnilvalue(gval(g->dummynode));193 setnilvalue(gval(g->dummynode));
183 g->dummynode->next = NULL;194 g->dummynode->next = NULL;
184 g->nblocks = sizeof(LG);195 g->totalbytes = sizeof(LG);
185 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {196 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
186 /* memory allocation error: free partial state */197 /* memory allocation error: free partial state */
187 close_state(L);198 close_state(L);
188 L = NULL;199 L = NULL;
189 }200 }
190 lua_userstateopen(L);201 else
202 lua_userstateopen(L);
191 return L;203 return L;
192}204}
193 205
src/lstate.h+15−41
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstate.h,v 2.2 2004/03/23 17:02:58 roberto Exp $2** $Id: lstate.h,v 2.7 2004/08/30 13:44:44 roberto Exp $
3** Global State3** Global State
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -14,30 +14,6 @@ · 8 unmodified lines
14#include "lzio.h"14#include "lzio.h"
15 15
16 16
17/*
18** macros for thread synchronization inside Lua core machine:
19** all accesses to the global state and to global objects are synchronized.
20** Because threads can read the stack of other threads
21** (when running garbage collection),
22** a thread must also synchronize any write-access to its own stack.
23** Unsynchronized accesses are allowed only when reading its own stack,
24** or when reading immutable fields from global objects
25** (such as string values and udata values).
26*/
27#ifndef lua_lock
28#define lua_lock(L) ((void) 0)
29#endif
30
31#ifndef lua_unlock
32#define lua_unlock(L) ((void) 0)
33#endif
34
35
36#ifndef lua_userstateopen
37#define lua_userstateopen(l)
38#endif
39
40
41 17
42struct lua_longjmp; /* defined in ldo.c */18struct lua_longjmp; /* defined in ldo.c */
43 19
@@ -70,25 +46,20 @@ typedef struct stringtable { · 26 unmodified lines
70** informations about a call46** informations about a call
71*/47*/
72typedef struct CallInfo {48typedef struct CallInfo {
73 StkId base; /* base for called function */49 StkId base; /* base for this function */
50 StkId func; /* function index in the stack */
74 StkId top; /* top for this function */51 StkId top; /* top for this function */
75 union {52 int nresults; /* expected number of results from this function */
76 struct { /* for Lua functions */53 const Instruction *savedpc;
77 const Instruction *savedpc;54 int tailcalls; /* number of tail calls lost under this entry */
78 int tailcalls; /* number of tail calls lost under this entry */
79 } l;
80 struct { /* for C functions */
81 int dummy; /* just to avoid an empty struct */
82 } c;
83 } u;
84} CallInfo;55} CallInfo;
85 56
86 57
87 58
88#define curr_func(L) (clvalue(L->base - 1))59#define curr_func(L) (clvalue(L->ci->func))
89#define ci_func(ci) (clvalue((ci)->base - 1))60#define ci_func(ci) (clvalue((ci)->func))
90#define f_isLua(ci) (!ci_func(ci)->c.isC)61#define f_isLua(ci) (!ci_func(ci)->c.isC)
91#define isLua(ci) (ttisfunction((ci)->base - 1) && f_isLua(ci))62#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
92 63
93 64
94/*65/*
@@ -98,7 +69,9 @@ typedef struct global_State { · 3 unmodified lines
98 stringtable strt; /* hash table for strings */69 stringtable strt; /* hash table for strings */
99 lua_Alloc realloc; /* function to reallocate memory */70 lua_Alloc realloc; /* function to reallocate memory */
100 void *ud; /* auxiliary data to `realloc' */71 void *ud; /* auxiliary data to `realloc' */
101 int currentwhite;72 lu_byte currentwhite;
73 lu_byte gcstate; /* state of garbage collector */
74 lu_byte gcgenerational;
102 GCObject *rootgc; /* list of all collectable objects */75 GCObject *rootgc; /* list of all collectable objects */
103 GCObject *firstudata; /* udata go to the end of `rootgc' */76 GCObject *firstudata; /* udata go to the end of `rootgc' */
104 GCObject **sweepgc; /* position of sweep in `rootgc' */77 GCObject **sweepgc; /* position of sweep in `rootgc' */
@@ -107,10 +80,11 @@ typedef struct global_State { · 2 unmodified lines
107 GCObject *grayagain; /* list of objects to be traversed atomically */80 GCObject *grayagain; /* list of objects to be traversed atomically */
108 GCObject *weak; /* list of weak tables (to be cleared) */81 GCObject *weak; /* list of weak tables (to be cleared) */
109 GCObject *tmudata; /* list of userdata to be GC */82 GCObject *tmudata; /* list of userdata to be GC */
110 int gcstate; /* state of garbage collector */
111 Mbuffer buff; /* temporary buffer for string concatentation */83 Mbuffer buff; /* temporary buffer for string concatentation */
112 lu_mem GCthreshold;84 lu_mem GCthreshold;
113 lu_mem nblocks; /* number of `bytes' currently allocated */85 lu_mem totalbytes; /* number of bytes currently allocated */
86 lu_mem estimate; /* an estimate of number of bytes actually in use */
87 lu_mem prevestimate; /* previous estimate */
114 lua_CFunction panic; /* to be called in unprotected errors */88 lua_CFunction panic; /* to be called in unprotected errors */
115 TValue _registry;89 TValue _registry;
116 struct lua_State *mainthread;90 struct lua_State *mainthread;
src/lstring.c+4−8
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstring.c,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: lstring.c,v 2.3 2004/08/24 20:12:06 roberto Exp $
3** String table (keeps all strings handled by Lua)3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <string.h>8#include <string.h>
9 9
10#define lstring_c10#define lstring_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -18,17 +19,12 @@ · 4 unmodified lines
18 19
19 20
20 21
21void luaS_freeall (lua_State *L) {
22 lua_assert(G(L)->strt.nuse==0);
23 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
24}
25
26
27void luaS_resize (lua_State *L, int newsize) {22void luaS_resize (lua_State *L, int newsize) {
28 GCObject **newhash;23 GCObject **newhash;
29 stringtable *tb;24 stringtable *tb;
30 int i;25 int i;
31 if (G(L)->sweepstrgc > 0) return; /* cannot resize during GC traverse */26 if (G(L)->gcstate == GCSsweepstring)
27 return; /* cannot resize during GC traverse */
32 newhash = luaM_newvector(L, newsize, GCObject *);28 newhash = luaM_newvector(L, newsize, GCObject *);
33 tb = &G(L)->strt;29 tb = &G(L)->strt;
34 for (i=0; i<newsize; i++) newhash[i] = NULL;30 for (i=0; i<newsize; i++) newhash[i] = NULL;
src/lstring.h+1−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstring.h,v 1.38 2003/11/17 19:50:05 roberto Exp $2** $Id: lstring.h,v 1.39 2004/08/24 20:12:06 roberto Exp $
3** String table (keep all strings handled by Lua)3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -26,7 +26,6 @@ · 20 unmodified lines
26 26
27void luaS_resize (lua_State *L, int newsize);27void luaS_resize (lua_State *L, int newsize);
28Udata *luaS_newudata (lua_State *L, size_t s);28Udata *luaS_newudata (lua_State *L, size_t s);
29void luaS_freeall (lua_State *L);
30TString *luaS_newlstr (lua_State *L, const char *str, size_t l);29TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
31 30
32 31
src/ltable.c+16−47
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltable.c,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: ltable.c,v 2.5 2004/08/31 17:57:33 roberto Exp $
3** Lua tables (hash)3** Lua tables (hash)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -21,6 +21,7 @@ · 15 unmodified lines
21#include <string.h>21#include <string.h>
22 22
23#define ltable_c23#define ltable_c
24#define LUA_CORE
24 25
25#include "lua.h"26#include "lua.h"
26 27
@@ -36,19 +37,14 @@ · 9 unmodified lines
36/*37/*
37** max size of array part is 2^MAXBITS38** max size of array part is 2^MAXBITS
38*/39*/
39#if BITS_INT > 2640#if LUA_BITSINT > 26
40#define MAXBITS 2441#define MAXBITS 24
41#else42#else
42#define MAXBITS (BITS_INT-2)43#define MAXBITS (LUA_BITSINT-2)
43#endif44#endif
44 45
45#define MAXASIZE (1 << MAXBITS)46#define MAXASIZE (1 << MAXBITS)
46 47
47/* function to convert a lua_Number to int (with any rounding method) */
48#ifndef lua_number2int
49#define lua_number2int(i,n) ((i)=(int)(n))
50#endif
51
52 48
53#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))49#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
54 50
@@ -270,7 +266,7 @@ static void setnodevector (lua_State *L, Table *t, int lsize) { · 215 unmodified lines
270}266}
271 267
272 268
273static void resize (lua_State *L, Table *t, int nasize, int nhsize) {269void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
274 int i;270 int i;
275 int oldasize = t->sizearray;271 int oldasize = t->sizearray;
276 int oldhsize = t->lsizenode;272 int oldhsize = t->lsizenode;
@@ -315,7 +311,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { · 38 unmodified lines
315static void rehash (lua_State *L, Table *t) {311static void rehash (lua_State *L, Table *t) {
316 int nasize, nhsize;312 int nasize, nhsize;
317 numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */313 numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */
318 resize(L, t, nasize, luaO_log2(nhsize)+1);314 luaH_resize(L, t, nasize, luaO_log2(nhsize)+1);
319}315}
320 316
321 317
@@ -349,26 +345,6 @@ void luaH_free (lua_State *L, Table *t) { · 27 unmodified lines
349}345}
350 346
351 347
352#if 0
353/*
354** try to remove an element from a hash table; cannot move any element
355** (because gc can call `remove' during a table traversal)
356*/
357void luaH_remove (Table *t, Node *e) {
358 Node *mp = luaH_mainposition(t, gkey(e));
359 if (e != mp) { /* element not in its main position? */
360 while (mp->next != e) mp = mp->next; /* find previous */
361 mp->next = e->next; /* remove `e' from its list */
362 }
363 else {
364 if (e->next != NULL) ??
365 }
366 lua_assert(ttisnil(gval(node)));
367 setnilvalue(gkey(e)); /* clear node `e' */
368 e->next = NULL;
369}
370#endif
371
372 348
373/*349/*
374** inserts a new key into a hash table; first, check whether key's main 350** inserts a new key into a hash table; first, check whether key's main
@@ -399,7 +375,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { · 24 unmodified lines
399 }375 }
400 }376 }
401 setobj2t(L, gkey(mp), key);377 setobj2t(L, gkey(mp), key);
402 luaC_barrier(L, t, key);378 luaC_barriert(L, t, key);
403 lua_assert(ttisnil(gval(mp)));379 lua_assert(ttisnil(gval(mp)));
404 for (;;) { /* correct `firstfree' */380 for (;;) { /* correct `firstfree' */
405 if (ttisnil(gkey(t->firstfree)))381 if (ttisnil(gkey(t->firstfree)))
@@ -417,21 +393,6 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { · 11 unmodified lines
417}393}
418 394
419 395
420/*
421** generic search function
422*/
423static const TValue *luaH_getany (Table *t, const TValue *key) {
424 if (!ttisnil(key)) {
425 Node *n = luaH_mainposition(t, key);
426 do { /* check whether `key' is somewhere in the chain */
427 if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
428 else n = n->next;
429 } while (n);
430 }
431 return &luaO_nilobject;
432}
433
434
435/*396/*
436** search function for integers397** search function for integers
437*/398*/
@@ -470,6 +431,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { · 32 unmodified lines
470*/431*/
471const TValue *luaH_get (Table *t, const TValue *key) {432const TValue *luaH_get (Table *t, const TValue *key) {
472 switch (ttype(key)) {433 switch (ttype(key)) {
434 case LUA_TNIL: return &luaO_nilobject;
473 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));435 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
474 case LUA_TNUMBER: {436 case LUA_TNUMBER: {
475 int k;437 int k;
@@ -478,7 +440,14 @@ const TValue *luaH_get (Table *t, const TValue *key) { · 2 unmodified lines
478 return luaH_getnum(t, k); /* use specialized version */440 return luaH_getnum(t, k); /* use specialized version */
479 /* else go through */441 /* else go through */
480 }442 }
481 default: return luaH_getany(t, key);443 default: {
444 Node *n = luaH_mainposition(t, key);
445 do { /* check whether `key' is somewhere in the chain */
446 if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
447 else n = n->next;
448 } while (n);
449 return &luaO_nilobject;
450 }
482 }451 }
483}452}
484 453
src/ltable.h+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltable.h,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: ltable.h,v 2.2 2004/03/26 14:02:41 roberto Exp $
3** Lua tables (hash)3** Lua tables (hash)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -22,6 +22,7 @@ TValue *luaH_setstr (lua_State *L, Table *t, TString *key); · 16 unmodified lines
22const TValue *luaH_get (Table *t, const TValue *key);22const TValue *luaH_get (Table *t, const TValue *key);
23TValue *luaH_set (lua_State *L, Table *t, const TValue *key);23TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
24Table *luaH_new (lua_State *L, int narray, int lnhash);24Table *luaH_new (lua_State *L, int narray, int lnhash);
25void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
25void luaH_free (lua_State *L, Table *t);26void luaH_free (lua_State *L, Table *t);
26int luaH_next (lua_State *L, Table *t, StkId key);27int luaH_next (lua_State *L, Table *t, StkId key);
27 28
src/ltests.c+0−852
@@ -1,852 +0,0 @@
1/*
2** $Id: ltests.c,v 1.158 2003/04/07 14:35:00 roberto Exp $
3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h
5*/
6
7
8#include <ctype.h>
9#include <limits.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define ltests_c
15
16#include "lua.h"
17
18#include "lapi.h"
19#include "lauxlib.h"
20#include "lcode.h"
21#include "ldebug.h"
22#include "ldo.h"
23#include "lfunc.h"
24#include "lmem.h"
25#include "lopcodes.h"
26#include "lstate.h"
27#include "lstring.h"
28#include "ltable.h"
29#include "lualib.h"
30
31
32
33/*
34** The whole module only makes sense with LUA_DEBUG on
35*/
36#ifdef LUA_DEBUG
37
38
39#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
40
41
42static lua_State *lua_state = NULL;
43
44int islocked = 0;
45
46
47#define func_at(L,k) (L->ci->base+(k) - 1)
48
49
50static void setnameval (lua_State *L, const char *name, int val) {
51 lua_pushstring(L, name);
52 lua_pushintegral(L, val);
53 lua_settable(L, -3);
54}
55
56
57/*
58** {======================================================================
59** Controlled version for realloc.
60** =======================================================================
61*/
62
63#define MARK 0x55 /* 01010101 (a nice pattern) */
64
65#ifndef EXTERNMEMCHECK
66/* full memory check */
67#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
68#define MARKSIZE 16 /* size of marks after each block */
69#define blockhead(b) (cast(char *, b) - HEADER)
70#define setsize(newblock, size) (*cast(size_t *, newblock) = size)
71#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
72#define fillmem(mem,size) memset(mem, -MARK, size)
73#else
74/* external memory check: don't do it twice */
75#define HEADER 0
76#define MARKSIZE 0
77#define blockhead(b) (b)
78#define setsize(newblock, size) /* empty */
79#define checkblocksize(b,size) (1)
80#define fillmem(mem,size) /* empty */
81#endif
82
83unsigned long memdebug_numblocks = 0;
84unsigned long memdebug_total = 0;
85unsigned long memdebug_maxmem = 0;
86unsigned long memdebug_memlimit = ULONG_MAX;
87
88
89static void *checkblock (void *block, size_t size) {
90 void *b = blockhead(block);
91 int i;
92 for (i=0;i<MARKSIZE;i++)
93 lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
94 return b;
95}
96
97
98static void freeblock (void *block, size_t size) {
99 if (block) {
100 lua_assert(checkblocksize(block, size));
101 block = checkblock(block, size);
102 fillmem(block, size+HEADER+MARKSIZE); /* erase block */
103 free(block); /* free original block */
104 memdebug_numblocks--;
105 memdebug_total -= size;
106 }
107}
108
109
110void *debug_realloc (void *block, size_t oldsize, size_t size) {
111 lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
112 /* ISO does not specify what realloc(NULL, 0) does */
113 lua_assert(block != NULL || size > 0);
114 if (size == 0) {
115 freeblock(block, oldsize);
116 return NULL;
117 }
118 else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
119 return NULL; /* to test memory allocation errors */
120 else {
121 void *newblock;
122 int i;
123 size_t realsize = HEADER+size+MARKSIZE;
124 size_t commonsize = (oldsize < size) ? oldsize : size;
125 if (realsize < size) return NULL; /* overflow! */
126 newblock = malloc(realsize); /* alloc a new block */
127 if (newblock == NULL) return NULL;
128 if (block) {
129 memcpy(cast(char *, newblock)+HEADER, block, commonsize);
130 freeblock(block, oldsize); /* erase (and check) old copy */
131 }
132 /* initialize new part of the block with something `weird' */
133 fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
134 memdebug_total += size;
135 if (memdebug_total > memdebug_maxmem)
136 memdebug_maxmem = memdebug_total;
137 memdebug_numblocks++;
138 setsize(newblock, size);
139 for (i=0;i<MARKSIZE;i++)
140 *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
141 return cast(char *, newblock)+HEADER;
142 }
143}
144
145
146/* }====================================================================== */
147
148
149
150/*
151** {======================================================
152** Disassembler
153** =======================================================
154*/
155
156
157static char *buildop (Proto *p, int pc, char *buff) {
158 Instruction i = p->code[pc];
159 OpCode o = GET_OPCODE(i);
160 const char *name = luaP_opnames[o];
161 int line = getline(p, pc);
162 sprintf(buff, "(%4d) %4d - ", line, pc);
163 switch (getOpMode(o)) {
164 case iABC:
165 sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
166 GETARG_A(i), GETARG_B(i), GETARG_C(i));
167 break;
168 case iABx:
169 sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
170 break;
171 case iAsBx:
172 sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
173 break;
174 }
175 return buff;
176}
177
178
179#if 0
180void luaI_printcode (Proto *pt, int size) {
181 int pc;
182 for (pc=0; pc<size; pc++) {
183 char buff[100];
184 printf("%s\n", buildop(pt, pc, buff));
185 }
186 printf("-------\n");
187}
188#endif
189
190
191static int listcode (lua_State *L) {
192 int pc;
193 Proto *p;
194 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
195 1, "Lua function expected");
196 p = clvalue(func_at(L, 1))->l.p;
197 lua_newtable(L);
198 setnameval(L, "maxstack", p->maxstacksize);
199 setnameval(L, "numparams", p->numparams);
200 for (pc=0; pc<p->sizecode; pc++) {
201 char buff[100];
202 lua_pushintegral(L, pc+1);
203 lua_pushstring(L, buildop(p, pc, buff));
204 lua_settable(L, -3);
205 }
206 return 1;
207}
208
209
210static int listk (lua_State *L) {
211 Proto *p;
212 int i;
213 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
214 1, "Lua function expected");
215 p = clvalue(func_at(L, 1))->l.p;
216 lua_newtable(L);
217 for (i=0; i<p->sizek; i++) {
218 lua_pushintegral(L, i+1);
219 luaA_pushobject(L, p->k+i);
220 lua_settable(L, -3);
221 }
222 return 1;
223}
224
225
226static int listlocals (lua_State *L) {
227 Proto *p;
228 int pc = luaL_checkint(L, 2) - 1;
229 int i = 0;
230 const char *name;
231 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
232 1, "Lua function expected");
233 p = clvalue(func_at(L, 1))->l.p;
234 while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
235 lua_pushstring(L, name);
236 return i-1;
237}
238
239/* }====================================================== */
240
241
242
243
244static int get_limits (lua_State *L) {
245 lua_newtable(L);
246 setnameval(L, "BITS_INT", BITS_INT);
247 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
248 setnameval(L, "MAXVARS", MAXVARS);
249 setnameval(L, "MAXPARAMS", MAXPARAMS);
250 setnameval(L, "MAXSTACK", MAXSTACK);
251 setnameval(L, "MAXUPVALUES", MAXUPVALUES);
252 return 1;
253}
254
255
256static int mem_query (lua_State *L) {
257 if (lua_isnone(L, 1)) {
258 lua_pushintegral(L, memdebug_total);
259 lua_pushintegral(L, memdebug_numblocks);
260 lua_pushintegral(L, memdebug_maxmem);
261 return 3;
262 }
263 else {
264 memdebug_memlimit = luaL_checkint(L, 1);
265 return 0;
266 }
267}
268
269
270static int hash_query (lua_State *L) {
271 if (lua_isnone(L, 2)) {
272 luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
273 lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
274 }
275 else {
276 TObject *o = func_at(L, 1);
277 Table *t;
278 luaL_checktype(L, 2, LUA_TTABLE);
279 t = hvalue(func_at(L, 2));
280 lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
281 }
282 return 1;
283}
284
285
286static int stacklevel (lua_State *L) {
287 unsigned long a = 0;
288 lua_pushintegral(L, (int)(L->top - L->stack));
289 lua_pushintegral(L, (int)(L->stack_last - L->stack));
290 lua_pushintegral(L, (int)(L->ci - L->base_ci));
291 lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
292 lua_pushintegral(L, (unsigned long)&a);
293 return 5;
294}
295
296
297static int table_query (lua_State *L) {
298 const Table *t;
299 int i = luaL_optint(L, 2, -1);
300 luaL_checktype(L, 1, LUA_TTABLE);
301 t = hvalue(func_at(L, 1));
302 if (i == -1) {
303 lua_pushintegral(L, t->sizearray);
304 lua_pushintegral(L, sizenode(t));
305 lua_pushintegral(L, t->firstfree - t->node);
306 }
307 else if (i < t->sizearray) {
308 lua_pushintegral(L, i);
309 luaA_pushobject(L, &t->array[i]);
310 lua_pushnil(L);
311 }
312 else if ((i -= t->sizearray) < sizenode(t)) {
313 if (!ttisnil(gval(gnode(t, i))) ||
314 ttisnil(gkey(gnode(t, i))) ||
315 ttisnumber(gkey(gnode(t, i)))) {
316 luaA_pushobject(L, gkey(gnode(t, i)));
317 }
318 else
319 lua_pushstring(L, "<undef>");
320 luaA_pushobject(L, gval(gnode(t, i)));
321 if (t->node[i].next)
322 lua_pushintegral(L, t->node[i].next - t->node);
323 else
324 lua_pushnil(L);
325 }
326 return 3;
327}
328
329
330static int string_query (lua_State *L) {
331 stringtable *tb = &G(L)->strt;
332 int s = luaL_optint(L, 2, 0) - 1;
333 if (s==-1) {
334 lua_pushintegral(L ,tb->nuse);
335 lua_pushintegral(L ,tb->size);
336 return 2;
337 }
338 else if (s < tb->size) {
339 GCObject *ts;
340 int n = 0;
341 for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
342 setsvalue2s(L->top, gcotots(ts));
343 incr_top(L);
344 n++;
345 }
346 return n;
347 }
348 return 0;
349}
350
351
352static int tref (lua_State *L) {
353 int level = lua_gettop(L);
354 int lock = luaL_optint(L, 2, 1);
355 luaL_checkany(L, 1);
356 lua_pushvalue(L, 1);
357 lua_pushintegral(L, lua_ref(L, lock));
358 assert(lua_gettop(L) == level+1); /* +1 for result */
359 return 1;
360}
361
362static int getref (lua_State *L) {
363 int level = lua_gettop(L);
364 lua_getref(L, luaL_checkint(L, 1));
365 assert(lua_gettop(L) == level+1);
366 return 1;
367}
368
369static int unref (lua_State *L) {
370 int level = lua_gettop(L);
371 lua_unref(L, luaL_checkint(L, 1));
372 assert(lua_gettop(L) == level);
373 return 0;
374}
375
376static int metatable (lua_State *L) {
377 luaL_checkany(L, 1);
378 if (lua_isnone(L, 2)) {
379 if (lua_getmetatable(L, 1) == 0)
380 lua_pushnil(L);
381 }
382 else {
383 lua_settop(L, 2);
384 luaL_checktype(L, 2, LUA_TTABLE);
385 lua_setmetatable(L, 1);
386 }
387 return 1;
388}
389
390
391static int upvalue (lua_State *L) {
392 int n = luaL_checkint(L, 2);
393 luaL_checktype(L, 1, LUA_TFUNCTION);
394 if (lua_isnone(L, 3)) {
395 const char *name = lua_getupvalue(L, 1, n);
396 if (name == NULL) return 0;
397 lua_pushstring(L, name);
398 return 2;
399 }
400 else {
401 const char *name = lua_setupvalue(L, 1, n);
402 lua_pushstring(L, name);
403 return 1;
404 }
405}
406
407
408static int newuserdata (lua_State *L) {
409 size_t size = luaL_checkint(L, 1);
410 char *p = cast(char *, lua_newuserdata(L, size));
411 while (size--) *p++ = '\0';
412 return 1;
413}
414
415
416static int pushuserdata (lua_State *L) {
417 lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
418 return 1;
419}
420
421
422static int udataval (lua_State *L) {
423 lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
424 return 1;
425}
426
427
428static int doonnewstack (lua_State *L) {
429 lua_State *L1 = lua_newthread(L);
430 size_t l;
431 const char *s = luaL_checklstring(L, 1, &l);
432 int status = luaL_loadbuffer(L1, s, l, s);
433 if (status == 0)
434 status = lua_pcall(L1, 0, 0, 0);
435 lua_pushintegral(L, status);
436 return 1;
437}
438
439
440static int s2d (lua_State *L) {
441 lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
442 return 1;
443}
444
445static int d2s (lua_State *L) {
446 double d = luaL_checknumber(L, 1);
447 lua_pushlstring(L, cast(char *, &d), sizeof(d));
448 return 1;
449}
450
451
452static int newstate (lua_State *L) {
453 lua_State *L1 = lua_open();
454 if (L1) {
455 lua_userstateopen(L1); /* init lock */
456 lua_pushintegral(L, (unsigned long)L1);
457 }
458 else
459 lua_pushnil(L);
460 return 1;
461}
462
463
464static int loadlib (lua_State *L) {
465 static const luaL_reg libs[] = {
466 {"mathlibopen", luaopen_math},
467 {"strlibopen", luaopen_string},
468 {"iolibopen", luaopen_io},
469 {"tablibopen", luaopen_table},
470 {"dblibopen", luaopen_debug},
471 {"baselibopen", luaopen_base},
472 {NULL, NULL}
473 };
474 lua_State *L1 = cast(lua_State *,
475 cast(unsigned long, luaL_checknumber(L, 1)));
476 lua_pushvalue(L1, LUA_GLOBALSINDEX);
477 luaL_openlib(L1, NULL, libs, 0);
478 return 0;
479}
480
481static int closestate (lua_State *L) {
482 lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
483 lua_close(L1);
484 lua_unlock(L); /* close cannot unlock that */
485 return 0;
486}
487
488static int doremote (lua_State *L) {
489 lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
490 size_t lcode;
491 const char *code = luaL_checklstring(L, 2, &lcode);
492 int status;
493 lua_settop(L1, 0);
494 status = luaL_loadbuffer(L1, code, lcode, code);
495 if (status == 0)
496 status = lua_pcall(L1, 0, LUA_MULTRET, 0);
497 if (status != 0) {
498 lua_pushnil(L);
499 lua_pushintegral(L, status);
500 lua_pushstring(L, lua_tostring(L1, -1));
501 return 3;
502 }
503 else {
504 int i = 0;
505 while (!lua_isnone(L1, ++i))
506 lua_pushstring(L, lua_tostring(L1, i));
507 lua_pop(L1, i-1);
508 return i-1;
509 }
510}
511
512
513static int log2_aux (lua_State *L) {
514 lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
515 return 1;
516}
517
518static int int2fb_aux (lua_State *L) {
519 int b = luaO_int2fb(luaL_checkint(L, 1));
520 lua_pushintegral(L, b);
521 lua_pushintegral(L, fb2int(b));
522 return 2;
523}
524
525
526static int test_do (lua_State *L) {
527 const char *p = luaL_checkstring(L, 1);
528 if (*p == '@')
529 lua_dofile(L, p+1);
530 else
531 lua_dostring(L, p);
532 return lua_gettop(L);
533}
534
535
536
537/*
538** {======================================================
539** function to test the API with C. It interprets a kind of assembler
540** language with calls to the API, so the test can be driven by Lua code
541** =======================================================
542*/
543
544static const char *const delimits = " \t\n,;";
545
546static void skip (const char **pc) {
547 while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
548}
549
550static int getnum_aux (lua_State *L, const char **pc) {
551 int res = 0;
552 int sig = 1;
553 skip(pc);
554 if (**pc == '.') {
555 res = cast(int, lua_tonumber(L, -1));
556 lua_pop(L, 1);
557 (*pc)++;
558 return res;
559 }
560 else if (**pc == '-') {
561 sig = -1;
562 (*pc)++;
563 }
564 while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0';
565 return sig*res;
566}
567
568static const char *getname_aux (char *buff, const char **pc) {
569 int i = 0;
570 skip(pc);
571 while (**pc != '\0' && !strchr(delimits, **pc))
572 buff[i++] = *(*pc)++;
573 buff[i] = '\0';
574 return buff;
575}
576
577
578#define EQ(s1) (strcmp(s1, inst) == 0)
579
580#define getnum (getnum_aux(L, &pc))
581#define getname (getname_aux(buff, &pc))
582
583
584static int testC (lua_State *L) {
585 char buff[30];
586 const char *pc = luaL_checkstring(L, 1);
587 for (;;) {
588 const char *inst = getname;
589 if EQ("") return 0;
590 else if EQ("isnumber") {
591 lua_pushintegral(L, lua_isnumber(L, getnum));
592 }
593 else if EQ("isstring") {
594 lua_pushintegral(L, lua_isstring(L, getnum));
595 }
596 else if EQ("istable") {
597 lua_pushintegral(L, lua_istable(L, getnum));
598 }
599 else if EQ("iscfunction") {
600 lua_pushintegral(L, lua_iscfunction(L, getnum));
601 }
602 else if EQ("isfunction") {
603 lua_pushintegral(L, lua_isfunction(L, getnum));
604 }
605 else if EQ("isuserdata") {
606 lua_pushintegral(L, lua_isuserdata(L, getnum));
607 }
608 else if EQ("isudataval") {
609 lua_pushintegral(L, lua_islightuserdata(L, getnum));
610 }
611 else if EQ("isnil") {
612 lua_pushintegral(L, lua_isnil(L, getnum));
613 }
614 else if EQ("isnull") {
615 lua_pushintegral(L, lua_isnone(L, getnum));
616 }
617 else if EQ("tonumber") {
618 lua_pushnumber(L, lua_tonumber(L, getnum));
619 }
620 else if EQ("tostring") {
621 const char *s = lua_tostring(L, getnum);
622 lua_pushstring(L, s);
623 }
624 else if EQ("strlen") {
625 lua_pushintegral(L, lua_strlen(L, getnum));
626 }
627 else if EQ("tocfunction") {
628 lua_pushcfunction(L, lua_tocfunction(L, getnum));
629 }
630 else if EQ("return") {
631 return getnum;
632 }
633 else if EQ("gettop") {
634 lua_pushintegral(L, lua_gettop(L));
635 }
636 else if EQ("settop") {
637 lua_settop(L, getnum);
638 }
639 else if EQ("pop") {
640 lua_pop(L, getnum);
641 }
642 else if EQ("pushnum") {
643 lua_pushintegral(L, getnum);
644 }
645 else if EQ("pushnil") {
646 lua_pushnil(L);
647 }
648 else if EQ("pushbool") {
649 lua_pushboolean(L, getnum);
650 }
651 else if EQ("tobool") {
652 lua_pushintegral(L, lua_toboolean(L, getnum));
653 }
654 else if EQ("pushvalue") {
655 lua_pushvalue(L, getnum);
656 }
657 else if EQ("pushcclosure") {
658 lua_pushcclosure(L, testC, getnum);
659 }
660 else if EQ("pushupvalues") {
661 lua_pushupvalues(L);
662 }
663 else if EQ("remove") {
664 lua_remove(L, getnum);
665 }
666 else if EQ("insert") {
667 lua_insert(L, getnum);
668 }
669 else if EQ("replace") {
670 lua_replace(L, getnum);
671 }
672 else if EQ("gettable") {
673 lua_gettable(L, getnum);
674 }
675 else if EQ("settable") {
676 lua_settable(L, getnum);
677 }
678 else if EQ("next") {
679 lua_next(L, -2);
680 }
681 else if EQ("concat") {
682 lua_concat(L, getnum);
683 }
684 else if EQ("lessthan") {
685 int a = getnum;
686 lua_pushboolean(L, lua_lessthan(L, a, getnum));
687 }
688 else if EQ("equal") {
689 int a = getnum;
690 lua_pushboolean(L, lua_equal(L, a, getnum));
691 }
692 else if EQ("rawcall") {
693 int narg = getnum;
694 int nres = getnum;
695 lua_call(L, narg, nres);
696 }
697 else if EQ("call") {
698 int narg = getnum;
699 int nres = getnum;
700 lua_pcall(L, narg, nres, 0);
701 }
702 else if EQ("loadstring") {
703 size_t sl;
704 const char *s = luaL_checklstring(L, getnum, &sl);
705 luaL_loadbuffer(L, s, sl, s);
706 }
707 else if EQ("loadfile") {
708 luaL_loadfile(L, luaL_checkstring(L, getnum));
709 }
710 else if EQ("setmetatable") {
711 lua_setmetatable(L, getnum);
712 }
713 else if EQ("getmetatable") {
714 if (lua_getmetatable(L, getnum) == 0)
715 lua_pushnil(L);
716 }
717 else if EQ("type") {
718 lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
719 }
720 else if EQ("getn") {
721 int i = getnum;
722 lua_pushintegral(L, luaL_getn(L, i));
723 }
724 else if EQ("setn") {
725 int i = getnum;
726 int n = cast(int, lua_tonumber(L, -1));
727 luaL_setn(L, i, n);
728 lua_pop(L, 1);
729 }
730 else luaL_error(L, "unknown instruction %s", buff);
731 }
732 return 0;
733}
734
735/* }====================================================== */
736
737
738/*
739** {======================================================
740** tests for yield inside hooks
741** =======================================================
742*/
743
744static void yieldf (lua_State *L, lua_Debug *ar) {
745 lua_yield(L, 0);
746}
747
748static int setyhook (lua_State *L) {
749 if (lua_isnoneornil(L, 1))
750 lua_sethook(L, NULL, 0, 0); /* turn off hooks */
751 else {
752 const char *smask = luaL_checkstring(L, 1);
753 int count = luaL_optint(L, 2, 0);
754 int mask = 0;
755 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
756 if (count > 0) mask |= LUA_MASKCOUNT;
757 lua_sethook(L, yieldf, mask, count);
758 }
759 return 0;
760}
761
762
763static int coresume (lua_State *L) {
764 int status;
765 lua_State *co = lua_tothread(L, 1);
766 luaL_argcheck(L, co, 1, "coroutine expected");
767 status = lua_resume(co, 0);
768 if (status != 0) {
769 lua_pushboolean(L, 0);
770 lua_insert(L, -2);
771 return 2; /* return false + error message */
772 }
773 else {
774 lua_pushboolean(L, 1);
775 return 1;
776 }
777}
778
779/* }====================================================== */
780
781
782
783static const struct luaL_reg tests_funcs[] = {
784 {"hash", hash_query},
785 {"limits", get_limits},
786 {"listcode", listcode},
787 {"listk", listk},
788 {"listlocals", listlocals},
789 {"loadlib", loadlib},
790 {"stacklevel", stacklevel},
791 {"querystr", string_query},
792 {"querytab", table_query},
793 {"doit", test_do},
794 {"testC", testC},
795 {"ref", tref},
796 {"getref", getref},
797 {"unref", unref},
798 {"d2s", d2s},
799 {"s2d", s2d},
800 {"metatable", metatable},
801 {"upvalue", upvalue},
802 {"newuserdata", newuserdata},
803 {"pushuserdata", pushuserdata},
804 {"udataval", udataval},
805 {"doonnewstack", doonnewstack},
806 {"newstate", newstate},
807 {"closestate", closestate},
808 {"doremote", doremote},
809 {"log2", log2_aux},
810 {"int2fb", int2fb_aux},
811 {"totalmem", mem_query},
812 {"resume", coresume},
813 {"setyhook", setyhook},
814 {NULL, NULL}
815};
816
817
818static void fim (void) {
819 if (!islocked)
820 lua_close(lua_state);
821 lua_assert(memdebug_numblocks == 0);
822 lua_assert(memdebug_total == 0);
823}
824
825
826static int l_panic (lua_State *L) {
827 UNUSED(L);
828 fprintf(stderr, "unable to recover; exiting\n");
829 return 0;
830}
831
832
833int luaB_opentests (lua_State *L) {
834 lua_atpanic(L, l_panic);
835 lua_userstateopen(L); /* init lock */
836 lua_state = L; /* keep first state to be opened */
837 luaL_openlib(L, "T", tests_funcs, 0);
838 atexit(fim);
839 return 0;
840}
841
842
843#undef main
844int main (int argc, char *argv[]) {
845 char *limit = getenv("MEMLIMIT");
846 if (limit)
847 memdebug_memlimit = strtoul(limit, NULL, 10);
848 l_main(argc, argv);
849 return 0;
850}
851
852#endif
src/ltm.c+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltm.c,v 2.2 2004/02/16 19:09:52 roberto Exp $2** $Id: ltm.c,v 2.3 2004/04/30 20:13:38 roberto Exp $
3** Tag methods3** Tag methods
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <string.h>8#include <string.h>
9 9
10#define ltm_c10#define ltm_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
src/lua/RCS+0−1
@@ -1 +0,0 @@
1../RCS
src/lua/README+2−2
@@ -1,4 +1,4 @@
1This is lua, a sample Lua interpreter.1This is lua, the stand-alone Lua interpreter.
2It can be used as a batch interpreter and also interactively.2It can be used as a batch interpreter and also interactively.
3There are man pages for it in both nroff and html in ../../doc.3There are man pages for it in both nroff and html in ../../doc.
4 4
@@ -10,7 +10,7 @@ Usage: lua [options] [script [args]]. Available options are: · 5 unmodified lines
10 -v show version information10 -v show version information
11 -- stop handling options11 -- stop handling options
12 12
13This interpreter is suitable for using Lua as a standalone language; it loads13This interpreter is suitable for using Lua as a stand-alone language; it loads
14all standard libraries. For a minimal interpreter, see ../../etc/min.c.14all standard libraries. For a minimal interpreter, see ../../etc/min.c.
15 15
16If your application simply exports new functions to Lua (which is common),16If your application simply exports new functions to Lua (which is common),
src/lua/lua.c+101−146
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lua.c,v 1.124 2003/10/23 18:06:22 roberto Exp $2** $Id: lua.c,v 1.132 2004/08/30 18:35:14 roberto Exp $
3** Lua stand-alone interpreter3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -26,73 +26,25 @@ · 20 unmodified lines
26#endif26#endif
27 27
28 28
29/*
30** definition of `isatty'
31*/
32#ifdef _POSIX_C_SOURCE
33#include <unistd.h>
34#define stdin_is_tty() isatty(0)
35#else
36#define stdin_is_tty() 1 /* assume stdin is a tty */
37#endif
38
39
40
41#ifndef PROMPT
42#define PROMPT "> "
43#endif
44
45
46#ifndef PROMPT2
47#define PROMPT2 ">> "
48#endif
49
50#ifndef PROGNAME
51#define PROGNAME "lua"
52#endif
53
54#ifndef lua_userinit
55#define lua_userinit(L) openstdlibs(L)
56#endif
57
58
59#ifndef LUA_EXTRALIBS
60#define LUA_EXTRALIBS /* empty */
61#endif
62 29
63 30
64static lua_State *L = NULL;31static lua_State *globalL = NULL;
65 32
66static const char *progname = PROGNAME;33static const char *progname = PROGNAME;
67 34
68 35
69 36
70static const luaL_reg lualibs[] = {37static void lstop (lua_State *L, lua_Debug *ar) {
71 {"base", luaopen_base},
72 {"table", luaopen_table},
73 {"io", luaopen_io},
74 {"string", luaopen_string},
75 {"math", luaopen_math},
76 {"debug", luaopen_debug},
77 {"loadlib", luaopen_loadlib},
78 /* add your libraries here */
79 LUA_EXTRALIBS
80 {NULL, NULL}
81};
82
83
84
85static void lstop (lua_State *l, lua_Debug *ar) {
86 (void)ar; /* unused arg. */38 (void)ar; /* unused arg. */
87 lua_sethook(l, NULL, 0, 0);39 lua_sethook(L, NULL, 0, 0);
88 luaL_error(l, "interrupted!");40 luaL_error(L, "interrupted!");
89}41}
90 42
91 43
92static void laction (int i) {44static void laction (int i) {
93 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,45 signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
94 terminate process (default action) */46 terminate process (default action) */
95 lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);47 lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
96}48}
97 49
98 50
@@ -116,7 +68,7 @@ static void l_message (const char *pname, const char *msg) { · 17 unmodified lines
116}68}
117 69
118 70
119static int report (int status) {71static int report (lua_State *L, int status) {
120 if (status && !lua_isnil(L, -1)) {72 if (status && !lua_isnil(L, -1)) {
121 const char *msg = lua_tostring(L, -1);73 const char *msg = lua_tostring(L, -1);
122 if (msg == NULL) msg = "(error object is not a string)";74 if (msg == NULL) msg = "(error object is not a string)";
@@ -127,7 +79,7 @@ static int report (int status) { · 4 unmodified lines
127}79}
128 80
129 81
130static int lcall (int narg, int clear) {82static int docall (lua_State *L, int narg, int clear) {
131 int status;83 int status;
132 int base = lua_gettop(L) - narg; /* function index */84 int base = lua_gettop(L) - narg; /* function index */
133 lua_pushliteral(L, "_TRACEBACK");85 lua_pushliteral(L, "_TRACEBACK");
@@ -146,55 +98,46 @@ static void print_version (void) { · 12 unmodified lines
146}98}
147 99
148 100
149static void getargs (char *argv[], int n) {101static int getargs (lua_State *L, char *argv[], int n) {
150 int i;102 int i, narg;
103 for (i=n+1; argv[i]; i++) {
104 luaL_checkstack(L, 1, "too many arguments to script");
105 lua_pushstring(L, argv[i]);
106 }
107 narg = i-(n+1); /* number of arguments to the script (not to `lua.c') */
151 lua_newtable(L);108 lua_newtable(L);
152 for (i=0; argv[i]; i++) {109 for (i=0; argv[i]; i++) {
153 lua_pushnumber(L, i - n);
154 lua_pushstring(L, argv[i]);110 lua_pushstring(L, argv[i]);
155 lua_rawset(L, -3);111 lua_rawseti(L, -2, i - n);
156 }112 }
113 return narg;
157}114}
158 115
159 116
160static int docall (int status) {117static int dofile (lua_State *L, const char *name) {
161 if (status == 0) status = lcall(0, 1);118 int status = luaL_loadfile(L, name) || docall(L, 0, 1);
162 return report(status);119 return report(L, status);
163}
164
165
166static int file_input (const char *name) {
167 return docall(luaL_loadfile(L, name));
168}120}
169 121
170 122
171static int dostring (const char *s, const char *name) {123static int dostring (lua_State *L, const char *s, const char *name) {
172 return docall(luaL_loadbuffer(L, s, strlen(s), name));124 int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
125 return report(L, status);
173}126}
174 127
175 128
176static int load_file (const char *name) {129static int dolibrary (lua_State *L, const char *name) {
177 lua_pushliteral(L, "require");130 lua_getfield(L, LUA_GLOBALSINDEX, "_PATH");
178 lua_rawget(L, LUA_GLOBALSINDEX);131 if (!lua_isstring(L, -1)) {
179 if (!lua_isfunction(L, -1)) { /* no `require' defined? */132 l_message(progname, "global _PATH must be a string");
180 lua_pop(L, 1);133 return 1;
181 return file_input(name);
182 }
183 else {
184 lua_pushstring(L, name);
185 return report(lcall(1, 1));
186 }134 }
135 name = luaL_searchpath(L, name, lua_tostring(L, -1));
136 if (name == NULL) return report(L, 1);
137 else return dofile(L, name);
187}138}
188 139
189 140
190/*
191** this macro can be used by some `history' system to save lines
192** read in manual input
193*/
194#ifndef lua_saveline
195#define lua_saveline(L,line) /* empty */
196#endif
197
198 141
199/*142/*
200** this macro defines a function to show the prompt and reads the143** this macro defines a function to show the prompt and reads the
@@ -209,7 +152,7 @@ static int load_file (const char *name) { · 8 unmodified lines
209#endif152#endif
210 153
211 154
212static int readline (lua_State *l, const char *prompt) {155static int readline (lua_State *L, const char *prompt) {
213 static char buffer[MAXINPUT];156 static char buffer[MAXINPUT];
214 if (prompt) {157 if (prompt) {
215 fputs(prompt, stdout);158 fputs(prompt, stdout);
@@ -218,7 +161,7 @@ static int readline (lua_State *l, const char *prompt) { · 2 unmodified lines
218 if (fgets(buffer, sizeof(buffer), stdin) == NULL)161 if (fgets(buffer, sizeof(buffer), stdin) == NULL)
219 return 0; /* read fails */162 return 0; /* read fails */
220 else {163 else {
221 lua_pushstring(l, buffer);164 lua_pushstring(L, buffer);
222 return 1;165 return 1;
223 }166 }
224}167}
@@ -226,7 +169,7 @@ static int readline (lua_State *l, const char *prompt) { · 1 unmodified line
226#endif169#endif
227 170
228 171
229static const char *get_prompt (int firstline) {172static const char *get_prompt (lua_State *L, int firstline) {
230 const char *p = NULL;173 const char *p = NULL;
231 lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2");174 lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2");
232 lua_rawget(L, LUA_GLOBALSINDEX);175 lua_rawget(L, LUA_GLOBALSINDEX);
@@ -237,7 +180,7 @@ static const char *get_prompt (int firstline) { · 4 unmodified lines
237}180}
238 181
239 182
240static int incomplete (int status) {183static int incomplete (lua_State *L, int status) {
241 if (status == LUA_ERRSYNTAX &&184 if (status == LUA_ERRSYNTAX &&
242 strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {185 strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
243 lua_pop(L, 1);186 lua_pop(L, 1);
@@ -248,10 +191,10 @@ static int incomplete (int status) { · 4 unmodified lines
248}191}
249 192
250 193
251static int load_string (void) {194static int loadline (lua_State *L) {
252 int status;195 int status;
253 lua_settop(L, 0);196 lua_settop(L, 0);
254 if (lua_readline(L, get_prompt(1)) == 0) /* no input? */197 if (lua_readline(L, get_prompt(L, 1)) == 0) /* no input? */
255 return -1;198 return -1;
256 if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */199 if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */
257 lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */200 lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */
@@ -259,8 +202,8 @@ static int load_string (void) { · 1 unmodified line
259 }202 }
260 for (;;) { /* repeat until gets a complete line */203 for (;;) { /* repeat until gets a complete line */
261 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");204 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
262 if (!incomplete(status)) break; /* cannot try to add lines? */205 if (!incomplete(L, status)) break; /* cannot try to add lines? */
263 if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */206 if (lua_readline(L, get_prompt(L, 0)) == 0) /* no more input? */
264 return -1;207 return -1;
265 lua_concat(L, lua_gettop(L)); /* join lines */208 lua_concat(L, lua_gettop(L)); /* join lines */
266 }209 }
@@ -270,13 +213,14 @@ static int load_string (void) { · 3 unmodified lines
270}213}
271 214
272 215
273static void manual_input (void) {216static void dotty (lua_State *L) {
274 int status;217 int status;
275 const char *oldprogname = progname;218 const char *oldprogname = progname;
276 progname = NULL;219 progname = NULL;
277 while ((status = load_string()) != -1) {220 print_version();
278 if (status == 0) status = lcall(0, 0);221 while ((status = loadline(L)) != -1) {
279 report(status);222 if (status == 0) status = docall(L, 0, 0);
223 report(L, status);
280 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */224 if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
281 lua_getglobal(L, "print");225 lua_getglobal(L, "print");
282 lua_insert(L, 1);226 lua_insert(L, 1);
@@ -291,14 +235,23 @@ static void manual_input (void) { · 8 unmodified lines
291}235}
292 236
293 237
294static int handle_argv (char *argv[], int *interactive) {238static int checkvar (lua_State *L) {
295 if (argv[1] == NULL) { /* no more arguments? */239 const char *name = lua_tostring(L, 2);
296 if (stdin_is_tty()) {240 if (name)
297 print_version();241 luaL_error(L, "attempt to access undefined variable `%s'", name);
298 manual_input();242 return 0;
299 }243}
244
245
246#define clearinteractive(i) (*i &= 2)
247
248static int handle_argv (lua_State *L, char *argv[], int *interactive) {
249 if (argv[1] == NULL) { /* no arguments? */
250 *interactive = 0;
251 if (stdin_is_tty())
252 dotty(L);
300 else253 else
301 file_input(NULL); /* executes stdin as a file */254 dofile(L, NULL); /* executes stdin as a file */
302 }255 }
303 else { /* other arguments; loop over them */256 else { /* other arguments; loop over them */
304 int i;257 int i;
@@ -314,25 +267,35 @@ static int handle_argv (char *argv[], int *interactive) { · 9 unmodified lines
314 goto endloop; /* stop handling arguments */267 goto endloop; /* stop handling arguments */
315 }268 }
316 case '\0': {269 case '\0': {
317 file_input(NULL); /* executes stdin as a file */270 clearinteractive(interactive);
271 dofile(L, NULL); /* executes stdin as a file */
318 break;272 break;
319 }273 }
320 case 'i': {274 case 'i': {
321 *interactive = 1;275 *interactive = 2; /* force interactive mode after arguments */
322 break;276 break;
323 }277 }
324 case 'v': {278 case 'v': {
279 clearinteractive(interactive);
325 print_version();280 print_version();
326 break;281 break;
327 }282 }
283 case 'w': {
284 if (lua_getmetatable(L, LUA_GLOBALSINDEX)) {
285 lua_pushcfunction(L, checkvar);
286 lua_setfield(L, -2, "__index");
287 }
288 break;
289 }
328 case 'e': {290 case 'e': {
329 const char *chunk = argv[i] + 2;291 const char *chunk = argv[i] + 2;
292 clearinteractive(interactive);
330 if (*chunk == '\0') chunk = argv[++i];293 if (*chunk == '\0') chunk = argv[++i];
331 if (chunk == NULL) {294 if (chunk == NULL) {
332 print_usage();295 print_usage();
333 return 1;296 return 1;
334 }297 }
335 if (dostring(chunk, "=<command line>") != 0)298 if (dostring(L, chunk, "=<command line>") != 0)
336 return 1;299 return 1;
337 break;300 break;
338 }301 }
@@ -343,19 +306,12 @@ static int handle_argv (char *argv[], int *interactive) { · 4 unmodified lines
343 print_usage();306 print_usage();
344 return 1;307 return 1;
345 }308 }
346 if (load_file(filename))309 if (dolibrary(L, filename))
347 return 1; /* stop if file fails */310 return 1; /* stop if file fails */
348 break;311 break;
349 }312 }
350 case 'c': {
351 l_message(progname, "option `-c' is deprecated");
352 break;
353 }
354 case 's': {
355 l_message(progname, "option `-s' is deprecated");
356 break;
357 }
358 default: {313 default: {
314 clearinteractive(interactive);
359 print_usage();315 print_usage();
360 return 1;316 return 1;
361 }317 }
@@ -363,31 +319,30 @@ static int handle_argv (char *argv[], int *interactive) { · 1 unmodified line
363 } endloop:319 } endloop:
364 if (argv[i] != NULL) {320 if (argv[i] != NULL) {
365 const char *filename = argv[i];321 const char *filename = argv[i];
366 getargs(argv, i); /* collect arguments */322 int narg = getargs(L, argv, i); /* collect arguments */
323 int status;
367 lua_setglobal(L, "arg");324 lua_setglobal(L, "arg");
368 return file_input(filename); /* stop scanning arguments */325 clearinteractive(interactive);
326 status = luaL_loadfile(L, filename);
327 lua_insert(L, -(narg+1));
328 if (status == 0)
329 status = docall(L, narg, 0);
330 else
331 lua_pop(L, narg);
332 return report(L, status);
369 }333 }
370 }334 }
371 return 0;335 return 0;
372}336}
373 337
374 338
375static void openstdlibs (lua_State *l) {339static int handle_luainit (lua_State *L) {
376 const luaL_reg *lib = lualibs;
377 for (; lib->func; lib++) {
378 lib->func(l); /* open library */
379 lua_settop(l, 0); /* discard any results */
380 }
381}
382
383
384static int handle_luainit (void) {
385 const char *init = getenv("LUA_INIT");340 const char *init = getenv("LUA_INIT");
386 if (init == NULL) return 0; /* status OK */341 if (init == NULL) return 0; /* status OK */
387 else if (init[0] == '@')342 else if (init[0] == '@')
388 return file_input(init+1);343 return dofile(L, init+1);
389 else344 else
390 return dostring(init, "=LUA_INIT");345 return dostring(L, init, "=LUA_INIT");
391}346}
392 347
393 348
@@ -398,17 +353,17 @@ struct Smain { · 4 unmodified lines
398};353};
399 354
400 355
401static int pmain (lua_State *l) {356static int pmain (lua_State *L) {
402 struct Smain *s = (struct Smain *)lua_touserdata(l, 1);357 struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
403 int status;358 int status;
404 int interactive = 0;359 int interactive = 1;
405 if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];360 if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
406 L = l;361 globalL = L;
407 lua_userinit(l); /* open libraries */362 lua_userinit(L); /* open libraries */
408 status = handle_luainit();363 status = handle_luainit(L);
409 if (status == 0) {364 if (status == 0) {
410 status = handle_argv(s->argv, &interactive);365 status = handle_argv(L, s->argv, &interactive);
411 if (status == 0 && interactive) manual_input();366 if (status == 0 && interactive) dotty(L);
412 }367 }
413 s->status = status;368 s->status = status;
414 return 0;369 return 0;
@@ -418,16 +373,16 @@ static int pmain (lua_State *l) { · 3 unmodified lines
418int main (int argc, char *argv[]) {373int main (int argc, char *argv[]) {
419 int status;374 int status;
420 struct Smain s;375 struct Smain s;
421 lua_State *l = lua_open(); /* create state */376 lua_State *L = lua_open(); /* create state */
422 if (l == NULL) {377 if (L == NULL) {
423 l_message(argv[0], "cannot create state: not enough memory");378 l_message(argv[0], "cannot create state: not enough memory");
424 return EXIT_FAILURE;379 return EXIT_FAILURE;
425 }380 }
426 s.argc = argc;381 s.argc = argc;
427 s.argv = argv;382 s.argv = argv;
428 status = lua_cpcall(l, &pmain, &s);383 status = lua_cpcall(L, &pmain, &s);
429 report(status);384 report(L, status);
430 lua_close(l);385 lua_close(L);
431 return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;386 return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
432}387}
433 388
src/luac/Makefile+1−5
@@ -5,7 +5,7 @@ LUA= ../.. · 4 unmodified lines
5include $(LUA)/config5include $(LUA)/config
6 6
7INCS= -I$(INC) -I.. $(EXTRA_INCS)7INCS= -I$(INC) -I.. $(EXTRA_INCS)
8OBJS= luac.o print.o lopcodes.o8OBJS= luac.o print.o
9SRCS= luac.c print.c9SRCS= luac.c print.c
10 10
11T= $(BIN)/luac11T= $(BIN)/luac
@@ -15,10 +15,6 @@ all: $T · 3 unmodified lines
15$T: $(OBJS) $(LIB)/liblua.a ../lib/lauxlib.o15$T: $(OBJS) $(LIB)/liblua.a ../lib/lauxlib.o
16 $(CC) -o $@ $(MYLDFLAGS) $(OBJS) ../lib/lauxlib.o -L$(LIB) -llua $(EXTRA_LIBS)16 $(CC) -o $@ $(MYLDFLAGS) $(OBJS) ../lib/lauxlib.o -L$(LIB) -llua $(EXTRA_LIBS)
17 17
18# print.c needs opcode names from lopcodes.c
19lopcodes.o: ../lopcodes.c ../lopcodes.h
20 $(CC) -o $@ -c $(CFLAGS) -DLUA_OPNAMES ../lopcodes.c
21
22$(LIB)/liblua.a:18$(LIB)/liblua.a:
23 cd ..; $(MAKE)19 cd ..; $(MAKE)
24 20
src/luac/RCS+0−1
@@ -1 +0,0 @@
1../RCS
src/luac/README+1−1
@@ -1,7 +1,7 @@
1This is luac, the Lua compiler.1This is luac, the Lua compiler.
2There are man pages for it in both nroff and html in ../../doc.2There are man pages for it in both nroff and html in ../../doc.
3 3
4luac translates Lua programs into binary files that can be loaded latter.4luac translates Lua programs into binary files that can be loaded later.
5The main advantages of pre-compiling chunks are: faster loading, protecting5The main advantages of pre-compiling chunks are: faster loading, protecting
6source code from user changes, and off-line syntax error detection.6source code from user changes, and off-line syntax error detection.
7luac can also be used to learn about the Lua virtual machine.7luac can also be used to learn about the Lua virtual machine.
src/luac/luac.c+44−31
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: luac.c,v 1.47 2004/03/24 00:25:08 lhf Exp $2** $Id: luac.c,v 1.49 2004/09/01 21:22:34 lhf Exp $
3** Lua compiler (saves bytecodes to files; also list bytecodes)3** Lua compiler (saves bytecodes to files; also list bytecodes)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -9,6 +9,9 @@ · 3 unmodified lines
9#include <stdlib.h>9#include <stdlib.h>
10#include <string.h>10#include <string.h>
11 11
12#define luac_c
13#define LUA_CORE
14
12#include "lua.h"15#include "lua.h"
13#include "lauxlib.h"16#include "lauxlib.h"
14 17
@@ -43,8 +46,7 @@ static void fatal(const char* message) · 28 unmodified lines
43 46
44static void cannot(const char* what)47static void cannot(const char* what)
45{48{
46 fprintf(stderr,"%s: cannot %s output file %s: %s\n",49 fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
47 progname,what,output,strerror(errno));
48 exit(EXIT_FAILURE);50 exit(EXIT_FAILURE);
49}51}
50 52
@@ -84,13 +86,14 @@ static int doargs(int argc, char* argv[]) · 33 unmodified lines
84 break;86 break;
85 }87 }
86 else if (IS("-")) /* end of options; use stdin */88 else if (IS("-")) /* end of options; use stdin */
87 return i;89 break;
88 else if (IS("-l")) /* list */90 else if (IS("-l")) /* list */
89 listing=1;91 ++listing;
90 else if (IS("-o")) /* output file */92 else if (IS("-o")) /* output file */
91 {93 {
92 output=argv[++i];94 output=argv[++i];
93 if (output==NULL || *output==0) usage("`-o' needs argument");95 if (output==NULL || *output==0) usage("`-o' needs argument");
96 if (IS("-")) output=NULL;
94 }97 }
95 else if (IS("-p")) /* parse only */98 else if (IS("-p")) /* parse only */
96 dumping=0;99 dumping=0;
@@ -112,11 +115,7 @@ static int doargs(int argc, char* argv[]) · 15 unmodified lines
112 return i;115 return i;
113}116}
114 117
115static Proto* toproto(lua_State* L, int i)118#define toproto(L,i) (clvalue(L->top+(i))->l.p)
116{
117 const Closure* c=(const Closure*)lua_topointer(L,i);
118 return c->l.p;
119}
120 119
121static Proto* combine(lua_State* L, int n)120static Proto* combine(lua_State* L, int n)
122{121{
@@ -124,18 +123,20 @@ static Proto* combine(lua_State* L, int n) · 1 unmodified line
124 return toproto(L,-1);123 return toproto(L,-1);
125 else124 else
126 {125 {
127 int i,pc=0;126 int i,pc;
128 Proto* f=luaF_newproto(L);127 Proto* f=luaF_newproto(L);
129 setptvalue2s(L,L->top,f); incr_top(L);128 setptvalue2s(L,L->top,f); incr_top(L);
130 f->source=luaS_newliteral(L,"=(" PROGNAME ")");129 f->source=luaS_newliteral(L,"=(" PROGNAME ")");
131 f->maxstacksize=1;130 f->maxstacksize=1;
131 pc=2*n+1;
132 f->code=luaM_newvector(L,pc,Instruction);
133 f->sizecode=pc;
132 f->p=luaM_newvector(L,n,Proto*);134 f->p=luaM_newvector(L,n,Proto*);
133 f->sizep=n;135 f->sizep=n;
134 f->sizecode=2*n+1;136 pc=0;
135 f->code=luaM_newvector(L,f->sizecode,Instruction);
136 for (i=0; i<n; i++)137 for (i=0; i<n; i++)
137 {138 {
138 f->p[i]=toproto(L,i-n);139 f->p[i]=toproto(L,i-n-1);
139 f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);140 f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
140 f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);141 f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
141 }142 }
@@ -147,26 +148,23 @@ static Proto* combine(lua_State* L, int n) · 5 unmodified lines
147static int writer(lua_State* L, const void* p, size_t size, void* u)148static int writer(lua_State* L, const void* p, size_t size, void* u)
148{149{
149 UNUSED(L);150 UNUSED(L);
150 return fwrite(p,size,1,(FILE*)u)==1;151 return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
151}152}
152 153
153static int panic(lua_State *L)154void unprint(lua_State* L, const char* name);
154{
155 UNUSED(L);
156 fatal("not enough memory!");
157 return 0;
158}
159 155
160int main(int argc, char* argv[])156struct Smain {
157 int argc;
158 char **argv;
159};
160
161static int pmain(lua_State *L)
161{162{
162 lua_State* L;163 struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
164 int argc=s->argc;
165 char **argv=s->argv;
163 Proto* f;166 Proto* f;
164 int i=doargs(argc,argv);167 int i;
165 argc-=i; argv+=i;
166 if (argc<=0) usage("no input files given");
167 L=lua_open();
168 if (L==NULL) fatal("not enough memory for state");
169 lua_atpanic(L,panic);
170 if (!lua_checkstack(L,argc)) fatal("too many input files");168 if (!lua_checkstack(L,argc)) fatal("too many input files");
171 for (i=0; i<argc; i++)169 for (i=0; i<argc; i++)
172 {170 {
@@ -174,10 +172,10 @@ int main(int argc, char* argv[]) · 1 unmodified line
174 if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));172 if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
175 }173 }
176 f=combine(L,argc);174 f=combine(L,argc);
177 if (listing) luaU_print(f);175 if (listing) luaU_print(f,listing>1);
178 if (dumping)176 if (dumping)
179 {177 {
180 FILE* D=fopen(output,"wb");178 FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
181 if (D==NULL) cannot("open");179 if (D==NULL) cannot("open");
182 lua_lock(L);180 lua_lock(L);
183 luaU_dump(L,f,writer,D,stripping);181 luaU_dump(L,f,writer,D,stripping);
@@ -185,6 +183,21 @@ int main(int argc, char* argv[]) · 1 unmodified line
185 if (ferror(D)) cannot("write");183 if (ferror(D)) cannot("write");
186 if (fclose(D)) cannot("close");184 if (fclose(D)) cannot("close");
187 }185 }
186 return 0;
187}
188
189int main(int argc, char* argv[])
190{
191 lua_State* L;
192 struct Smain s;
193 int i=doargs(argc,argv);
194 argc-=i; argv+=i;
195 if (argc<=0) usage("no input files given");
196 L=lua_open();
197 if (L==NULL) fatal("not enough memory for state");
198 s.argc=argc;
199 s.argv=argv;
200 if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1));
188 lua_close(L);201 lua_close(L);
189 return EXIT_SUCCESS;202 return EXIT_SUCCESS;
190}203}
src/luac/print.c+21−31
@@ -1,18 +1,13 @@
1/*1/*
2** $Id: print.c,v 1.46 2004/03/24 00:25:08 lhf Exp $2** $Id: print.c,v 1.48 2004/09/01 21:22:34 lhf Exp $
3** print bytecodes3** print bytecodes
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
6 6
7#include <ctype.h>
7#include <stdio.h>8#include <stdio.h>
8 9
9#if 110#define LUA_CORE
10#define DEBUG_PRINT
11#endif
12
13#ifndef LUA_OPNAMES
14#define LUA_OPNAMES
15#endif
16 11
17#include "ldebug.h"12#include "ldebug.h"
18#include "lobject.h"13#include "lobject.h"
@@ -38,7 +33,7 @@ static void PrintString(const Proto* f, int n) · 19 unmodified lines
38 case '\r': printf("\\r"); break;33 case '\r': printf("\\r"); break;
39 case '\t': printf("\\t"); break;34 case '\t': printf("\\t"); break;
40 case '\v': printf("\\v"); break;35 case '\v': printf("\\v"); break;
41 default: putchar(*s); break;36 default: printf(isprint(*s) ? "%c" : "\\%03d",*s);
42 }37 }
43 }38 }
44 putchar('"');39 putchar('"');
@@ -88,13 +83,11 @@ static void PrintCode(const Proto* f) · 43 unmodified lines
88 {83 {
89 case iABC:84 case iABC:
90 printf("%d",a);85 printf("%d",a);
91 if (getBMode(o)!=OpArgN) 86 if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
92 { if (b>=MAXSTACK) printf(" #%d",b-MAXSTACK); else printf(" %d",b); }87 if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
93 if (getCMode(o)!=OpArgN)
94 { if (c>=MAXSTACK) printf(" #%d",c-MAXSTACK); else printf(" %d",c); }
95 break;88 break;
96 case iABx:89 case iABx:
97 if (getBMode(o)==OpArgK) printf("%d #%d",a,bx); else printf("%d %d",a,bx);90 if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
98 break;91 break;
99 case iAsBx:92 case iAsBx:
100 if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);93 if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
@@ -115,7 +108,7 @@ static void PrintCode(const Proto* f) · 14 unmodified lines
115 break;108 break;
116 case OP_GETTABLE:109 case OP_GETTABLE:
117 case OP_SELF:110 case OP_SELF:
118 if (c>=MAXSTACK) { printf("\t; "); PrintConstant(f,c-MAXSTACK); }111 if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
119 break;112 break;
120 case OP_SETTABLE:113 case OP_SETTABLE:
121 case OP_ADD:114 case OP_ADD:
@@ -126,12 +119,12 @@ static void PrintCode(const Proto* f) · 4 unmodified lines
126 case OP_EQ:119 case OP_EQ:
127 case OP_LT:120 case OP_LT:
128 case OP_LE:121 case OP_LE:
129 if (b>=MAXSTACK || c>=MAXSTACK)122 if (ISK(b) || ISK(c))
130 {123 {
131 printf("\t; ");124 printf("\t; ");
132 if (b>=MAXSTACK) PrintConstant(f,b-MAXSTACK); else printf("-");125 if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
133 printf(" ");126 printf(" ");
134 if (c>=MAXSTACK) PrintConstant(f,c-MAXSTACK); else printf("-");127 if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
135 }128 }
136 break;129 break;
137 case OP_JMP:130 case OP_JMP:
@@ -161,15 +154,13 @@ static const char* Source(const Proto* f) · 23 unmodified lines
161 return "(string)";154 return "(string)";
162}155}
163 156
164#define IsMain(f) (f->lineDefined==0)
165
166#define SS(x) (x==1)?"":"s"157#define SS(x) (x==1)?"":"s"
167#define S(x) x,SS(x)158#define S(x) x,SS(x)
168 159
169static void PrintHeader(const Proto* f)160static void PrintHeader(const Proto* f)
170{161{
171 printf("\n%s <%s:%d> (%d instruction%s, %d bytes at %p)\n",162 printf("\n%s <%s:%d> (%d instruction%s, %d bytes at %p)\n",
172 IsMain(f)?"main":"function",Source(f),f->lineDefined,163 (f->lineDefined==0)?"main":"function",Source(f),f->lineDefined,
173 S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));164 S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
174 printf("%d%s param%s, %d stack%s, %d upvalue%s, ",165 printf("%d%s param%s, %d stack%s, %d upvalue%s, ",
175 f->numparams,f->is_vararg?"+":"",SS(f->numparams),S(f->maxstacksize),166 f->numparams,f->is_vararg?"+":"",SS(f->numparams),S(f->maxstacksize),
@@ -178,14 +169,13 @@ static void PrintHeader(const Proto* f) · 2 unmodified lines
178 S(f->sizelocvars),S(f->sizek),S(f->sizep));169 S(f->sizelocvars),S(f->sizek),S(f->sizep));
179}170}
180 171
181#ifdef DEBUG_PRINT
182static void PrintConstants(const Proto* f)172static void PrintConstants(const Proto* f)
183{173{
184 int i,n=f->sizek;174 int i,n=f->sizek;
185 printf("constants (%d) for %p:\n",n,VOID(f));175 printf("constants (%d) for %p:\n",n,VOID(f));
186 for (i=0; i<n; i++)176 for (i=0; i<n; i++)
187 {177 {
188 printf("\t%d\t",i);178 printf("\t%d\t",i+1);
189 PrintConstant(f,i);179 PrintConstant(f,i);
190 printf("\n");180 printf("\n");
191 }181 }
@@ -212,17 +202,17 @@ static void PrintUpvalues(const Proto* f) · 20 unmodified lines
212 printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));202 printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
213 }203 }
214}204}
215#endif
216 205
217void luaU_print(const Proto* f)206void luaU_print(const Proto* f, int full)
218{207{
219 int i,n=f->sizep;208 int i,n=f->sizep;
220 PrintHeader(f);209 PrintHeader(f);
221 PrintCode(f);210 PrintCode(f);
222#ifdef DEBUG_PRINT211 if (full)
223 PrintConstants(f);212 {
224 PrintLocals(f);213 PrintConstants(f);
225 PrintUpvalues(f);214 PrintLocals(f);
226#endif215 PrintUpvalues(f);
227 for (i=0; i<n; i++) luaU_print(f->p[i]);216 }
217 for (i=0; i<n; i++) luaU_print(f->p[i],full);
228}218}
src/lundump.c+7−6
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lundump.c,v 1.51 2004/03/24 00:25:08 lhf Exp $2** $Id: lundump.c,v 1.53 2004/09/01 21:22:34 lhf Exp $
3** load pre-compiled Lua chunks3** load pre-compiled Lua chunks
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <stddef.h>8#include <stddef.h>
9 9
10#define lundump_c10#define lundump_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14
@@ -261,15 +262,15 @@ static void LoadHeader (LoadState* S) · 247 unmodified lines
261/*262/*
262** load precompiled chunk263** load precompiled chunk
263*/264*/
264Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* s)265Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
265{266{
266 LoadState S;267 LoadState S;
267 if (*s=='@' || *s=='=')268 if (*name=='@' || *name=='=')
268 S.name=s+1;269 S.name=name+1;
269 else if (*s==LUA_SIGNATURE[0])270 else if (*name==LUA_SIGNATURE[0])
270 S.name="binary string";271 S.name="binary string";
271 else272 else
272 S.name=s;273 S.name=name;
273 S.L=L;274 S.L=L;
274 S.Z=Z;275 S.Z=Z;
275 S.b=buff;276 S.b=buff;
src/lundump.h+3−3
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lundump.h,v 1.32 2003/12/09 19:22:19 lhf Exp $2** $Id: lundump.h,v 1.33 2004/06/09 21:03:53 lhf Exp $
3** load pre-compiled Lua chunks3** load pre-compiled Lua chunks
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -17,10 +17,10 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char *name); · 11 unmodified lines
17int luaU_endianness (void);17int luaU_endianness (void);
18 18
19/* dump one chunk; from ldump.c */19/* dump one chunk; from ldump.c */
20int luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data, int strip);20int luaU_dump (lua_State* L, const Proto* f, lua_Chunkwriter w, void* data, int strip);
21 21
22/* print one chunk; from print.c */22/* print one chunk; from print.c */
23void luaU_print (const Proto* Main);23void luaU_print (const Proto* f, int full);
24 24
25/* definitions for headers of binary files */25/* definitions for headers of binary files */
26#define VERSION 0x51 /* last format change was in 5.1 */26#define VERSION 0x51 /* last format change was in 5.1 */
src/lvm.c+166−138
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lvm.c,v 2.2 2004/03/16 12:31:40 roberto Exp $2** $Id: lvm.c,v 2.13 2004/08/12 14:19:51 roberto Exp $
3** Lua virtual machine3** Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,10 +8,8 @@ · 2 unmodified lines
8#include <stdlib.h>8#include <stdlib.h>
9#include <string.h>9#include <string.h>
10 10
11/* needed only when `lua_number2str' uses `sprintf' */
12#include <stdio.h>
13
14#define lvm_c11#define lvm_c
12#define LUA_CORE
15 13
16#include "lua.h"14#include "lua.h"
17 15
@@ -29,12 +27,6 @@ · 11 unmodified lines
29 27
30 28
31 29
32/* function to convert a lua_Number to a string */
33#ifndef lua_number2str
34#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
35#endif
36
37
38/* limit for table tag-method chains (to avoid loops) */30/* limit for table tag-method chains (to avoid loops) */
39#define MAXTAGLOOP 10031#define MAXTAGLOOP 100
40 32
@@ -66,8 +58,8 @@ int luaV_tostring (lua_State *L, StkId obj) { · 25 unmodified lines
66static void traceexec (lua_State *L, const Instruction *pc) {58static void traceexec (lua_State *L, const Instruction *pc) {
67 lu_byte mask = L->hookmask;59 lu_byte mask = L->hookmask;
68 CallInfo *ci = L->ci;60 CallInfo *ci = L->ci;
69 const Instruction *oldpc = ci->u.l.savedpc;61 const Instruction *oldpc = ci->savedpc;
70 ci->u.l.savedpc = pc;62 ci->savedpc = pc;
71 if (mask > LUA_MASKLINE) { /* instruction-hook set? */63 if (mask > LUA_MASKLINE) { /* instruction-hook set? */
72 if (L->hookcount == 0) {64 if (L->hookcount == 0) {
73 resethookcount(L);65 resethookcount(L);
@@ -114,7 +106,8 @@ static void callTM (lua_State *L) { · 40 unmodified lines
114}106}
115 107
116 108
117void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {109StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
110 const Instruction *pc) {
118 int loop;111 int loop;
119 for (loop = 0; loop < MAXTAGLOOP; loop++) {112 for (loop = 0; loop < MAXTAGLOOP; loop++) {
120 const TValue *tm;113 const TValue *tm;
@@ -124,24 +117,30 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 3 unmodified lines
124 if (!ttisnil(res) || /* result is no nil? */117 if (!ttisnil(res) || /* result is no nil? */
125 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */118 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
126 setobj2s(L, val, res);119 setobj2s(L, val, res);
127 return;120 return L->base;
128 }121 }
129 /* else will try the tag method */122 /* else will try the tag method */
130 }123 }
131 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))124 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) {
125 L->ci->savedpc = pc;
132 luaG_typeerror(L, t, "index");126 luaG_typeerror(L, t, "index");
127 }
133 if (ttisfunction(tm)) {128 if (ttisfunction(tm)) {
129 L->ci->savedpc = pc;
134 prepTMcall(L, tm, t, key);130 prepTMcall(L, tm, t, key);
135 callTMres(L, val);131 callTMres(L, val);
136 return;132 return L->base;
137 }133 }
138 t = tm; /* else repeat with `tm' */ 134 t = tm; /* else repeat with `tm' */
139 }135 }
136 L->ci->savedpc = pc;
140 luaG_runerror(L, "loop in gettable");137 luaG_runerror(L, "loop in gettable");
138 return NULL; /* to avoid warnings */
141}139}
142 140
143 141
144void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {142StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
143 const Instruction *pc) {
145 int loop;144 int loop;
146 for (loop = 0; loop < MAXTAGLOOP; loop++) {145 for (loop = 0; loop < MAXTAGLOOP; loop++) {
147 const TValue *tm;146 const TValue *tm;
@@ -151,22 +150,27 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 3 unmodified lines
151 if (!ttisnil(oldval) || /* result is no nil? */150 if (!ttisnil(oldval) || /* result is no nil? */
152 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */151 (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
153 setobj2t(L, oldval, val);152 setobj2t(L, oldval, val);
154 luaC_barrier(L, h, val);153 luaC_barriert(L, h, val);
155 return;154 return L->base;
156 }155 }
157 /* else will try the tag method */156 /* else will try the tag method */
158 }157 }
159 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))158 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) {
159 L->ci->savedpc = pc;
160 luaG_typeerror(L, t, "index");160 luaG_typeerror(L, t, "index");
161 }
161 if (ttisfunction(tm)) {162 if (ttisfunction(tm)) {
163 L->ci->savedpc = pc;
162 prepTMcall(L, tm, t, key);164 prepTMcall(L, tm, t, key);
163 setobj2s(L, L->top+3, val); /* 3th argument */165 setobj2s(L, L->top+3, val); /* 3th argument */
164 callTM(L);166 callTM(L);
165 return;167 return L->base;
166 }168 }
167 t = tm; /* else repeat with `tm' */ 169 t = tm; /* else repeat with `tm' */
168 }170 }
171 L->ci->savedpc = pc;
169 luaG_runerror(L, "loop in settable");172 luaG_runerror(L, "loop in settable");
173 return NULL; /* to avoid warnings */
170}174}
171 175
172 176
@@ -304,10 +308,11 @@ void luaV_concat (lua_State *L, int total, int last) { · 131 unmodified lines
304 char *buffer;308 char *buffer;
305 int i;309 int i;
306 while (n < total && tostring(L, top-n-1)) { /* collect total length */310 while (n < total && tostring(L, top-n-1)) { /* collect total length */
307 tl += tsvalue(top-n-1)->len;311 size_t l = tsvalue(top-n-1)->len;
312 if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
313 tl += l;
308 n++;314 n++;
309 }315 }
310 if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
311 buffer = luaZ_openspace(L, &G(L)->buff, tl);316 buffer = luaZ_openspace(L, &G(L)->buff, tl);
312 tl = 0;317 tl = 0;
313 for (i=n; i>0; i--) { /* concat all strings */318 for (i=n; i>0; i--) { /* concat all strings */
@@ -327,7 +332,7 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb, · 13 unmodified lines
327 const TValue *rc, TMS op, const Instruction *pc) {332 const TValue *rc, TMS op, const Instruction *pc) {
328 TValue tempb, tempc;333 TValue tempb, tempc;
329 const TValue *b, *c;334 const TValue *b, *c;
330 L->ci->u.l.savedpc = pc;335 L->ci->savedpc = pc;
331 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&336 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
332 (c = luaV_tonumber(rc, &tempc)) != NULL) {337 (c = luaV_tonumber(rc, &tempc)) != NULL) {
333 switch (op) {338 switch (op) {
@@ -364,13 +369,13 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb, · 30 unmodified lines
364#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))369#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
365#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))370#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
366#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \371#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
367 (GETARG_B(i) < MAXSTACK) ? base+GETARG_B(i) : k+GETARG_B(i)-MAXSTACK)372 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
368#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \373#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
369 (GETARG_C(i) < MAXSTACK) ? base+GETARG_C(i) : k+GETARG_C(i)-MAXSTACK)374 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
370#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))375#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
371 376
372 377
373#define dojump(pc, i) ((pc) += (i))378#define dojump(L,pc,i) {(pc) += (i); lua_threadyield(L);}
374 379
375 380
376StkId luaV_execute (lua_State *L, int nexeccalls) {381StkId luaV_execute (lua_State *L, int nexeccalls) {
@@ -382,9 +387,9 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 5 unmodified lines
382 if (L->hookmask & LUA_MASKCALL)387 if (L->hookmask & LUA_MASKCALL)
383 luaD_callhook(L, LUA_HOOKCALL, -1);388 luaD_callhook(L, LUA_HOOKCALL, -1);
384 retentry: /* entry point when returning to old functions */389 retentry: /* entry point when returning to old functions */
385 pc = L->ci->u.l.savedpc;390 pc = L->ci->savedpc;
391 cl = &clvalue(L->ci->func)->l;
386 base = L->base;392 base = L->base;
387 cl = &clvalue(base - 1)->l;
388 k = cl->p->k;393 k = cl->p->k;
389 /* main loop of interpreter */394 /* main loop of interpreter */
390 for (;;) {395 for (;;) {
@@ -394,7 +399,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines
394 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {399 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
395 traceexec(L, pc); /***/400 traceexec(L, pc); /***/
396 if (L->isSuspended) { /* did hook yield? */401 if (L->isSuspended) { /* did hook yield? */
397 L->ci->u.l.savedpc = pc - 1;402 L->ci->savedpc = pc - 1;
398 return NULL;403 return NULL;
399 }404 }
400 base = L->base;405 base = L->base;
@@ -402,85 +407,73 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line
402 /* warning!! several calls may realloc the stack and invalidate `ra' */407 /* warning!! several calls may realloc the stack and invalidate `ra' */
403 ra = RA(i);408 ra = RA(i);
404 lua_assert(base == L->ci->base && base == L->base);409 lua_assert(base == L->ci->base && base == L->base);
405 lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);410 lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
406 lua_assert(L->top == L->ci->top ||411 lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
407 GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
408 GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
409 switch (GET_OPCODE(i)) {412 switch (GET_OPCODE(i)) {
410 case OP_MOVE: {413 case OP_MOVE: {
411 setobjs2s(L, ra, RB(i));414 setobjs2s(L, ra, RB(i));
412 break;415 continue;
413 }416 }
414 case OP_LOADK: {417 case OP_LOADK: {
415 setobj2s(L, ra, KBx(i));418 setobj2s(L, ra, KBx(i));
416 break;419 continue;
417 }420 }
418 case OP_LOADBOOL: {421 case OP_LOADBOOL: {
419 setbvalue(ra, GETARG_B(i));422 setbvalue(ra, GETARG_B(i));
420 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */423 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
421 break;424 continue;
422 }425 }
423 case OP_LOADNIL: {426 case OP_LOADNIL: {
424 TValue *rb = RB(i);427 TValue *rb = RB(i);
425 do {428 do {
426 setnilvalue(rb--);429 setnilvalue(rb--);
427 } while (rb >= ra);430 } while (rb >= ra);
428 break;431 continue;
429 }432 }
430 case OP_GETUPVAL: {433 case OP_GETUPVAL: {
431 int b = GETARG_B(i);434 int b = GETARG_B(i);
432 setobj2s(L, ra, cl->upvals[b]->v);435 setobj2s(L, ra, cl->upvals[b]->v);
433 break;436 continue;
434 }437 }
435 case OP_GETGLOBAL: {438 case OP_GETGLOBAL: {
436 TValue *rb = KBx(i);439 TValue *rb = KBx(i);
437 lua_assert(ttisstring(rb) && ttistable(&cl->g));440 lua_assert(ttisstring(rb) && ttistable(&cl->g));
438 L->ci->u.l.savedpc = pc;441 base = luaV_gettable(L, &cl->g, rb, ra, pc); /***/
439 luaV_gettable(L, &cl->g, rb, ra); /***/442 continue;
440 base = L->base;
441 break;
442 }443 }
443 case OP_GETTABLE: {444 case OP_GETTABLE: {
444 L->ci->u.l.savedpc = pc;445 base = luaV_gettable(L, RB(i), RKC(i), ra, pc); /***/
445 luaV_gettable(L, RB(i), RKC(i), ra); /***/446 continue;
446 base = L->base;
447 break;
448 }447 }
449 case OP_SETGLOBAL: {448 case OP_SETGLOBAL: {
450 lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));449 lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
451 L->ci->u.l.savedpc = pc;450 base = luaV_settable(L, &cl->g, KBx(i), ra, pc); /***/
452 luaV_settable(L, &cl->g, KBx(i), ra); /***/451 continue;
453 base = L->base;
454 break;
455 }452 }
456 case OP_SETUPVAL: {453 case OP_SETUPVAL: {
457 UpVal *uv = cl->upvals[GETARG_B(i)];454 UpVal *uv = cl->upvals[GETARG_B(i)];
458 setobj(L, uv->v, ra);455 setobj(L, uv->v, ra);
459 luaC_barrier(L, uv, ra);456 luaC_barrier(L, uv, ra);
460 break;457 continue;
461 }458 }
462 case OP_SETTABLE: {459 case OP_SETTABLE: {
463 L->ci->u.l.savedpc = pc;460 base = luaV_settable(L, ra, RKB(i), RKC(i), pc); /***/
464 luaV_settable(L, ra, RKB(i), RKC(i)); /***/461 continue;
465 base = L->base;
466 break;
467 }462 }
468 case OP_NEWTABLE: {463 case OP_NEWTABLE: {
469 int b = GETARG_B(i);464 int b = GETARG_B(i);
470 b = fb2int(b);465 b = fb2int(b);
471 sethvalue(L, ra, luaH_new(L, b, GETARG_C(i)));466 sethvalue(L, ra, luaH_new(L, b, GETARG_C(i)));
472 L->ci->u.l.savedpc = pc;467 L->ci->savedpc = pc;
473 luaC_checkGC(L); /***/468 luaC_checkGC(L); /***/
474 base = L->base;469 base = L->base;
475 break;470 continue;
476 }471 }
477 case OP_SELF: {472 case OP_SELF: {
478 StkId rb = RB(i);473 StkId rb = RB(i);
479 setobjs2s(L, ra+1, rb);474 setobjs2s(L, ra+1, rb);
480 L->ci->u.l.savedpc = pc;475 base = luaV_gettable(L, rb, RKC(i), ra, pc); /***/
481 luaV_gettable(L, rb, RKC(i), ra); /***/476 continue;
482 base = L->base;
483 break;
484 }477 }
485 case OP_ADD: {478 case OP_ADD: {
486 TValue *rb = RKB(i);479 TValue *rb = RKB(i);
@@ -490,7 +483,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines
490 }483 }
491 else484 else
492 base = Arith(L, ra, rb, rc, TM_ADD, pc); /***/485 base = Arith(L, ra, rb, rc, TM_ADD, pc); /***/
493 break;486 continue;
494 }487 }
495 case OP_SUB: {488 case OP_SUB: {
496 TValue *rb = RKB(i);489 TValue *rb = RKB(i);
@@ -500,7 +493,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines
500 }493 }
501 else494 else
502 base = Arith(L, ra, rb, rc, TM_SUB, pc); /***/495 base = Arith(L, ra, rb, rc, TM_SUB, pc); /***/
503 break;496 continue;
504 }497 }
505 case OP_MUL: {498 case OP_MUL: {
506 TValue *rb = RKB(i);499 TValue *rb = RKB(i);
@@ -510,7 +503,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines
510 }503 }
511 else504 else
512 base = Arith(L, ra, rb, rc, TM_MUL, pc); /***/505 base = Arith(L, ra, rb, rc, TM_MUL, pc); /***/
513 break;506 continue;
514 }507 }
515 case OP_DIV: {508 case OP_DIV: {
516 TValue *rb = RKB(i);509 TValue *rb = RKB(i);
@@ -520,11 +513,11 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines
520 }513 }
521 else514 else
522 base = Arith(L, ra, rb, rc, TM_DIV, pc); /***/515 base = Arith(L, ra, rb, rc, TM_DIV, pc); /***/
523 break;516 continue;
524 }517 }
525 case OP_POW: {518 case OP_POW: {
526 base = Arith(L, ra, RKB(i), RKC(i), TM_POW, pc); /***/519 base = Arith(L, ra, RKB(i), RKC(i), TM_POW, pc); /***/
527 break;520 continue;
528 }521 }
529 case OP_UNM: {522 case OP_UNM: {
530 const TValue *rb = RB(i);523 const TValue *rb = RB(i);
@@ -534,113 +527,131 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines
534 }527 }
535 else {528 else {
536 setnilvalue(&temp);529 setnilvalue(&temp);
537 L->ci->u.l.savedpc = pc;530 L->ci->savedpc = pc;
538 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/531 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/
539 luaG_aritherror(L, RB(i), &temp);532 luaG_aritherror(L, RB(i), &temp);
540 base = L->base;533 base = L->base;
541 }534 }
542 break;535 continue;
543 }536 }
544 case OP_NOT: {537 case OP_NOT: {
545 int res = l_isfalse(RB(i)); /* next assignment may change this value */538 int res = l_isfalse(RB(i)); /* next assignment may change this value */
546 setbvalue(ra, res);539 setbvalue(ra, res);
547 break;540 continue;
548 }541 }
549 case OP_CONCAT: {542 case OP_CONCAT: {
550 int b = GETARG_B(i);543 int b = GETARG_B(i);
551 int c = GETARG_C(i);544 int c = GETARG_C(i);
552 L->ci->u.l.savedpc = pc;545 L->ci->savedpc = pc;
553 luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/546 luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/
554 luaC_checkGC(L); /***/547 luaC_checkGC(L); /***/
555 base = L->base;548 base = L->base;
556 setobjs2s(L, RA(i), base+b);549 setobjs2s(L, RA(i), base+b);
557 break;550 continue;
558 }551 }
559 case OP_JMP: {552 case OP_JMP: {
560 dojump(pc, GETARG_sBx(i));553 dojump(L, pc, GETARG_sBx(i));
561 break;554 continue;
562 }555 }
563 case OP_EQ: {556 case OP_EQ: {
564 L->ci->u.l.savedpc = pc;557 L->ci->savedpc = pc;
565 if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/558 if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
566 else dojump(pc, GETARG_sBx(*pc) + 1);559 else dojump(L, pc, GETARG_sBx(*pc) + 1);
567 base = L->base;560 base = L->base;
568 break;561 continue;
569 }562 }
570 case OP_LT: {563 case OP_LT: {
571 L->ci->u.l.savedpc = pc;564 L->ci->savedpc = pc;
572 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/565 if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
573 else dojump(pc, GETARG_sBx(*pc) + 1);566 else dojump(L, pc, GETARG_sBx(*pc) + 1);
574 base = L->base;567 base = L->base;
575 break;568 continue;
576 }569 }
577 case OP_LE: {570 case OP_LE: {
578 L->ci->u.l.savedpc = pc;571 L->ci->savedpc = pc;
579 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/572 if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; /***/
580 else dojump(pc, GETARG_sBx(*pc) + 1);573 else dojump(L, pc, GETARG_sBx(*pc) + 1);
581 base = L->base;574 base = L->base;
582 break;575 continue;
583 }576 }
584 case OP_TEST: {577 case OP_TEST: {
585 TValue *rb = RB(i);578 TValue *rb = RB(i);
586 if (l_isfalse(rb) == GETARG_C(i)) pc++;579 if (l_isfalse(rb) == GETARG_C(i)) pc++;
587 else {580 else {
588 setobjs2s(L, ra, rb);581 setobjs2s(L, ra, rb);
589 dojump(pc, GETARG_sBx(*pc) + 1);582 dojump(L, pc, GETARG_sBx(*pc) + 1);
590 }583 }
591 break;584 continue;
592 }585 }
593 case OP_CALL:586 case OP_CALL: { /***/
594 case OP_TAILCALL: { /***/587 int pcr;
595 StkId firstResult;
596 int b = GETARG_B(i);588 int b = GETARG_B(i);
589 int nresults = GETARG_C(i) - 1;
597 if (b != 0) L->top = ra+b; /* else previous instruction set top */590 if (b != 0) L->top = ra+b; /* else previous instruction set top */
598 L->ci->u.l.savedpc = pc;591 L->ci->savedpc = pc;
599 firstResult = luaD_precall(L, ra);592 pcr = luaD_precall(L, ra, nresults);
600 if (firstResult) {593 if (pcr == PCRLUA) {
601 int nresults = GETARG_C(i) - 1;594 nexeccalls++;
602 if (firstResult > L->top) { /* yield? */595 goto callentry; /* restart luaV_execute over new Lua function */
603 (L->ci - 1)->u.l.savedpc = pc;596 }
604 return NULL;597 else if (pcr == PCRC) {
605 }
606 /* it was a C function (`precall' called it); adjust results */598 /* it was a C function (`precall' called it); adjust results */
607 luaD_poscall(L, nresults, firstResult);
608 if (nresults >= 0) L->top = L->ci->top;599 if (nresults >= 0) L->top = L->ci->top;
600 base = L->base;
601 continue;
609 }602 }
610 else { /* it is a Lua function */603 else {
611 if (GET_OPCODE(i) == OP_CALL) /* regular call? */604 lua_assert(pcr == PCRYIELD);
612 nexeccalls++;605 return NULL;
613 else { /* tail call: put new frame in place of previous one */606 }
614 int aux;607 }
615 base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */608 case OP_TAILCALL: { /***/
616 ra = RA(i);609 int pcr;
617 if (L->openupval) luaF_close(L, base);610 int b = GETARG_B(i);
618 for (aux = 0; ra+aux < L->top; aux++) /* move frame down */611 if (b != 0) L->top = ra+b; /* else previous instruction set top */
619 setobjs2s(L, base+aux-1, ra+aux);612 L->ci->savedpc = pc;
620 (L->ci - 1)->top = L->top = base+aux; /* correct top */613 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
621 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;614 pcr = luaD_precall(L, ra, LUA_MULTRET);
622 (L->ci - 1)->u.l.tailcalls++; /* one more call lost */615 if (pcr == PCRLUA) {
623 L->ci--; /* remove new frame */616 /* tail call: put new frame in place of previous one */
624 L->base = L->ci->base;617 CallInfo *ci = L->ci - 1; /* previous frame */
625 }618 int aux;
619 StkId func = ci->func;
620 StkId pfunc = (ci+1)->func; /* previous function index */
621 base = ci->base = ci->func + ((ci+1)->base - pfunc);
622 L->base = base;
623 if (L->openupval) luaF_close(L, base);
624 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
625 setobjs2s(L, func+aux, pfunc+aux);
626 ci->top = L->top = func+aux; /* correct top */
627 lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
628 ci->savedpc = L->ci->savedpc;
629 ci->tailcalls++; /* one more call lost */
630 L->ci--; /* remove new frame */
626 goto callentry;631 goto callentry;
627 }632 }
628 base = L->base;633 else if (pcr == PCRC) {
629 break;634 /* it was a C function (`precall' called it) */
635 base = L->base;
636 continue;
637 }
638 else {
639 lua_assert(pcr == PCRYIELD);
640 return NULL;
641 }
630 }642 }
631 case OP_RETURN: {643 case OP_RETURN: {
632 CallInfo *ci = L->ci - 1; /* previous function frame */644 CallInfo *ci = L->ci - 1; /* previous function frame */
633 int b = GETARG_B(i);645 int b = GETARG_B(i);
634 if (b != 0) L->top = ra+b-1;646 if (b != 0) L->top = ra+b-1;
635 if (L->openupval) luaF_close(L, base);647 if (L->openupval) luaF_close(L, base);
636 L->ci->u.l.savedpc = pc;648 L->ci->savedpc = pc;
637 if (--nexeccalls == 0) /* was previous function running `here'? */649 if (--nexeccalls == 0) /* was previous function running `here'? */
638 return ra; /* no: return */650 return ra; /* no: return */
639 else { /* yes: continue its execution */651 else { /* yes: continue its execution */
640 int nresults;652 int nresults = (ci+1)->nresults;
641 lua_assert(isLua(ci));653 lua_assert(isLua(ci));
642 lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);654 lua_assert(GET_OPCODE(*(ci->savedpc - 1)) == OP_CALL);
643 nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
644 luaD_poscall(L, nresults, ra);655 luaD_poscall(L, nresults, ra);
645 if (nresults >= 0) L->top = L->ci->top;656 if (nresults >= 0) L->top = L->ci->top;
646 goto retentry;657 goto retentry;
@@ -651,17 +662,17 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 4 unmodified lines
651 lua_Number idx = nvalue(ra) + step; /* increment index */662 lua_Number idx = nvalue(ra) + step; /* increment index */
652 lua_Number limit = nvalue(ra+1);663 lua_Number limit = nvalue(ra+1);
653 if (step > 0 ? idx <= limit : idx >= limit) {664 if (step > 0 ? idx <= limit : idx >= limit) {
654 dojump(pc, GETARG_sBx(i)); /* jump back */665 dojump(L, pc, GETARG_sBx(i)); /* jump back */
655 setnvalue(ra, idx); /* update internal index... */666 setnvalue(ra, idx); /* update internal index... */
656 setnvalue(ra+3, idx); /* ...and external index */667 setnvalue(ra+3, idx); /* ...and external index */
657 }668 }
658 break;669 continue;
659 }670 }
660 case OP_FORPREP: { /***/671 case OP_FORPREP: { /***/
661 const TValue *init = ra;672 const TValue *init = ra;
662 const TValue *plimit = ra+1;673 const TValue *plimit = ra+1;
663 const TValue *pstep = ra+2;674 const TValue *pstep = ra+2;
664 L->ci->u.l.savedpc = pc;675 L->ci->savedpc = pc;
665 if (!tonumber(init, ra))676 if (!tonumber(init, ra))
666 luaG_runerror(L, "`for' initial value must be a number");677 luaG_runerror(L, "`for' initial value must be a number");
667 else if (!tonumber(plimit, ra+1))678 else if (!tonumber(plimit, ra+1))
@@ -669,8 +680,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line
669 else if (!tonumber(pstep, ra+2))680 else if (!tonumber(pstep, ra+2))
670 luaG_runerror(L, "`for' step must be a number");681 luaG_runerror(L, "`for' step must be a number");
671 setnvalue(ra, nvalue(ra) - nvalue(pstep));682 setnvalue(ra, nvalue(ra) - nvalue(pstep));
672 dojump(pc, GETARG_sBx(i));683 dojump(L, pc, GETARG_sBx(i));
673 break;684 continue;
674 }685 }
675 case OP_TFORLOOP: {686 case OP_TFORLOOP: {
676 StkId cb = ra + 3; /* call base */687 StkId cb = ra + 3; /* call base */
@@ -678,7 +689,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line
678 setobjs2s(L, cb+1, ra+1);689 setobjs2s(L, cb+1, ra+1);
679 setobjs2s(L, cb, ra);690 setobjs2s(L, cb, ra);
680 L->top = cb+3; /* func. + 2 args (state and index) */691 L->top = cb+3; /* func. + 2 args (state and index) */
681 L->ci->u.l.savedpc = pc;692 L->ci->savedpc = pc;
682 luaD_call(L, cb, GETARG_C(i)); /***/693 luaD_call(L, cb, GETARG_C(i)); /***/
683 L->top = L->ci->top;694 L->top = L->ci->top;
684 base = L->base;695 base = L->base;
@@ -687,26 +698,25 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 2 unmodified lines
687 pc++; /* skip jump (break loop) */698 pc++; /* skip jump (break loop) */
688 else {699 else {
689 setobjs2s(L, cb-1, cb); /* save control variable */700 setobjs2s(L, cb-1, cb); /* save control variable */
690 dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */701 dojump(L, pc, GETARG_sBx(*pc) + 1); /* jump back */
691 }702 }
692 break;703 continue;
693 }704 }
694 case OP_TFORPREP: { /* for compatibility only */705 case OP_TFORPREP: { /* for compatibility only */
695 if (ttistable(ra)) {706 if (ttistable(ra)) {
696 setobjs2s(L, ra+1, ra);707 setobjs2s(L, ra+1, ra);
697 setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));708 setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
698 }709 }
699 dojump(pc, GETARG_sBx(i));710 dojump(L, pc, GETARG_sBx(i));
700 break;711 continue;
701 }712 }
702 case OP_SETLIST:713 case OP_SETLIST:
703 case OP_SETLISTO: {714 case OP_SETLISTO: {
704 int bc;715 int bc = GETARG_Bx(i);
705 int n;716 int n, last;
706 Table *h;717 Table *h;
707 runtime_check(L, ttistable(ra));718 runtime_check(L, ttistable(ra));
708 h = hvalue(ra);719 h = hvalue(ra);
709 bc = GETARG_Bx(i);
710 if (GET_OPCODE(i) == OP_SETLIST)720 if (GET_OPCODE(i) == OP_SETLIST)
711 n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;721 n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
712 else {722 else {
@@ -714,16 +724,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line
714 L->top = L->ci->top;724 L->top = L->ci->top;
715 }725 }
716 bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */726 bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */
727 last = bc + n + LUA_FIRSTINDEX - 1;
728 if (last > h->sizearray) /* needs more space? */
729 luaH_resize(L, h, last, h->lsizenode); /* pre-alloc it at once */
717 for (; n > 0; n--) {730 for (; n > 0; n--) {
718 TValue *val = ra+n;731 TValue *val = ra+n;
719 setobj2t(L, luaH_setnum(L, h, bc+n), val);732 setobj2t(L, luaH_setnum(L, h, last--), val);
720 luaC_barrier(L, h, val);733 luaC_barriert(L, h, val);
721 }734 }
722 break;735 continue;
723 }736 }
724 case OP_CLOSE: {737 case OP_CLOSE: {
725 luaF_close(L, ra);738 luaF_close(L, ra);
726 break;739 continue;
727 }740 }
728 case OP_CLOSURE: {741 case OP_CLOSURE: {
729 Proto *p;742 Proto *p;
@@ -742,10 +755,25 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 12 unmodified lines
742 }755 }
743 }756 }
744 setclvalue(L, ra, ncl);757 setclvalue(L, ra, ncl);
745 L->ci->u.l.savedpc = pc;758 L->ci->savedpc = pc;
746 luaC_checkGC(L); /***/759 luaC_checkGC(L); /***/
747 base = L->base;760 base = L->base;
748 break;761 continue;
762 }
763 case OP_VARARG: {
764 int b = GETARG_B(i) - 1;
765 int j;
766 CallInfo *ci = L->ci;
767 int n = ci->base - ci->func - cl->p->numparams - 1;
768 if (b == LUA_MULTRET) {
769 b = n;
770 L->top = ra + n;
771 }
772 for (j=0; j<b && j<n; j++)
773 setobjs2s(L, ra+j, ci->base - n + j);
774 for (; j<b; j++)
775 setnilvalue(ra+j);
776 continue;
749 }777 }
750 }778 }
751 }779 }
src/lvm.h+5−3
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lvm.h,v 2.1 2003/12/10 12:13:36 roberto Exp $2** $Id: lvm.h,v 2.2 2004/05/14 19:25:09 roberto Exp $
3** Lua virtual machine3** Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -26,8 +26,10 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); · 20 unmodified lines
26int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);26int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
27const TValue *luaV_tonumber (const TValue *obj, TValue *n);27const TValue *luaV_tonumber (const TValue *obj, TValue *n);
28int luaV_tostring (lua_State *L, StkId obj);28int luaV_tostring (lua_State *L, StkId obj);
29void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val);29StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
30void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val);30 const Instruction *pc);
31StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
32 const Instruction *pc);
31StkId luaV_execute (lua_State *L, int nexeccalls);33StkId luaV_execute (lua_State *L, int nexeccalls);
32void luaV_concat (lua_State *L, int total, int last);34void luaV_concat (lua_State *L, int total, int last);
33 35
src/lzio.c+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lzio.c,v 1.28 2003/11/18 10:44:53 roberto Exp $2** $Id: lzio.c,v 1.29 2004/04/30 20:13:38 roberto Exp $
3** a generic input stream interface3** a generic input stream interface
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -8,6 +8,7 @@ · 2 unmodified lines
8#include <string.h>8#include <string.h>
9 9
10#define lzio_c10#define lzio_c
11#define LUA_CORE
11 12
12#include "lua.h"13#include "lua.h"
13 14