Unified · Split
| @@ -1,4 +1,4 @@ | |||
| 1 | This is Lua 5.0. | 1 | This is Lua 5.1 (work). |
| 2 | 2 | ||
| 3 | * Changes from version 4.0 to 5.0 | 3 | * Changes from version 4.0 to 5.0 |
| 4 | ------------------------------- | 4 | ------------------------------- |
| @@ -1,4 +1,4 @@ | |||
| 1 | This is Lua 5.0. | 1 | This is Lua 5.1 (work). |
| 2 | 2 | ||
| 3 | * Installation | 3 | * 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 install | 13 | 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 systems | 60 | * Installation on Windows and other systems |
| 60 | ----------------------------------------- | 61 | ----------------------------------------- |
| 61 | The instructions for building Lua on other systems machine depend on the | 62 | 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 folder | 63 | 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.c | 67 | 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.c | 68 | lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c |
| 68 | ltable.c ltm.c lundump.c lvm.c lzio.c | 69 | 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.c | 71 | standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c |
| 71 | lstrlib.c loadlib.c | 72 | ltablib.c lstrlib.c loadlib.c |
| 72 | 73 | ||
| 73 | interpreter: core lib, standard lib, lua.c | 74 | interpreter: core lib, standard lib, lua.c |
| 74 | 75 | ||
| 75 | compiler: core lib, lauxlib.c luac.c print.c | 76 | 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 create | 78 | 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. |
| @@ -0,0 +1,114 @@ | |||
| 1 | MANIFEST contents of Lua 5.1 (work1) distribution on Wed Sep 1 22:19:31 BRT 2004 | ||
| 2 | lua-5.1-work1 | ||
| 3 | lua-5.1-work1/COPYRIGHT | ||
| 4 | lua-5.1-work1/HISTORY | ||
| 5 | lua-5.1-work1/INSTALL | ||
| 6 | lua-5.1-work1/MANIFEST | ||
| 7 | lua-5.1-work1/Makefile | ||
| 8 | lua-5.1-work1/README | ||
| 9 | lua-5.1-work1/bin | ||
| 10 | lua-5.1-work1/build | ||
| 11 | lua-5.1-work1/config | ||
| 12 | lua-5.1-work1/etc | ||
| 13 | lua-5.1-work1/etc/Makefile | ||
| 14 | lua-5.1-work1/etc/README | ||
| 15 | lua-5.1-work1/etc/all.c | ||
| 16 | lua-5.1-work1/etc/lua.ico | ||
| 17 | lua-5.1-work1/etc/min.c | ||
| 18 | lua-5.1-work1/etc/noparser.c | ||
| 19 | lua-5.1-work1/etc/saconfig.c | ||
| 20 | lua-5.1-work1/include | ||
| 21 | lua-5.1-work1/include/Makefile | ||
| 22 | lua-5.1-work1/include/lauxlib.h | ||
| 23 | lua-5.1-work1/include/lua.h | ||
| 24 | lua-5.1-work1/include/luaconf.h | ||
| 25 | lua-5.1-work1/include/lualib.h | ||
| 26 | lua-5.1-work1/lib | ||
| 27 | lua-5.1-work1/src | ||
| 28 | lua-5.1-work1/src/Makefile | ||
| 29 | lua-5.1-work1/src/README | ||
| 30 | lua-5.1-work1/src/lapi.c | ||
| 31 | lua-5.1-work1/src/lapi.h | ||
| 32 | lua-5.1-work1/src/lcode.c | ||
| 33 | lua-5.1-work1/src/lcode.h | ||
| 34 | lua-5.1-work1/src/ldebug.c | ||
| 35 | lua-5.1-work1/src/ldebug.h | ||
| 36 | lua-5.1-work1/src/ldo.c | ||
| 37 | lua-5.1-work1/src/ldo.h | ||
| 38 | lua-5.1-work1/src/ldump.c | ||
| 39 | lua-5.1-work1/src/lfunc.c | ||
| 40 | lua-5.1-work1/src/lfunc.h | ||
| 41 | lua-5.1-work1/src/lgc.c | ||
| 42 | lua-5.1-work1/src/lgc.h | ||
| 43 | lua-5.1-work1/src/lib | ||
| 44 | lua-5.1-work1/src/lib/Makefile | ||
| 45 | lua-5.1-work1/src/lib/README | ||
| 46 | lua-5.1-work1/src/lib/lauxlib.c | ||
| 47 | lua-5.1-work1/src/lib/lbaselib.c | ||
| 48 | lua-5.1-work1/src/lib/ldblib.c | ||
| 49 | lua-5.1-work1/src/lib/linit.c | ||
| 50 | lua-5.1-work1/src/lib/liolib.c | ||
| 51 | lua-5.1-work1/src/lib/lmathlib.c | ||
| 52 | lua-5.1-work1/src/lib/loadlib.c | ||
| 53 | lua-5.1-work1/src/lib/loslib.c | ||
| 54 | lua-5.1-work1/src/lib/lstrlib.c | ||
| 55 | lua-5.1-work1/src/lib/ltablib.c | ||
| 56 | lua-5.1-work1/src/llex.c | ||
| 57 | lua-5.1-work1/src/llex.h | ||
| 58 | lua-5.1-work1/src/llimits.h | ||
| 59 | lua-5.1-work1/src/lmem.c | ||
| 60 | lua-5.1-work1/src/lmem.h | ||
| 61 | lua-5.1-work1/src/lobject.c | ||
| 62 | lua-5.1-work1/src/lobject.h | ||
| 63 | lua-5.1-work1/src/lopcodes.c | ||
| 64 | lua-5.1-work1/src/lopcodes.h | ||
| 65 | lua-5.1-work1/src/lparser.c | ||
| 66 | lua-5.1-work1/src/lparser.h | ||
| 67 | lua-5.1-work1/src/lstate.c | ||
| 68 | lua-5.1-work1/src/lstate.h | ||
| 69 | lua-5.1-work1/src/lstring.c | ||
| 70 | lua-5.1-work1/src/lstring.h | ||
| 71 | lua-5.1-work1/src/ltable.c | ||
| 72 | lua-5.1-work1/src/ltable.h | ||
| 73 | lua-5.1-work1/src/ltm.c | ||
| 74 | lua-5.1-work1/src/ltm.h | ||
| 75 | lua-5.1-work1/src/lua | ||
| 76 | lua-5.1-work1/src/lua/Makefile | ||
| 77 | lua-5.1-work1/src/lua/README | ||
| 78 | lua-5.1-work1/src/lua/lua.c | ||
| 79 | lua-5.1-work1/src/luac | ||
| 80 | lua-5.1-work1/src/luac/Makefile | ||
| 81 | lua-5.1-work1/src/luac/README | ||
| 82 | lua-5.1-work1/src/luac/luac.c | ||
| 83 | lua-5.1-work1/src/luac/print.c | ||
| 84 | lua-5.1-work1/src/lundump.c | ||
| 85 | lua-5.1-work1/src/lundump.h | ||
| 86 | lua-5.1-work1/src/lvm.c | ||
| 87 | lua-5.1-work1/src/lvm.h | ||
| 88 | lua-5.1-work1/src/lzio.c | ||
| 89 | lua-5.1-work1/src/lzio.h | ||
| 90 | lua-5.1-work1/test | ||
| 91 | lua-5.1-work1/test/README | ||
| 92 | lua-5.1-work1/test/bisect.lua | ||
| 93 | lua-5.1-work1/test/cf.lua | ||
| 94 | lua-5.1-work1/test/echo.lua | ||
| 95 | lua-5.1-work1/test/env.lua | ||
| 96 | lua-5.1-work1/test/factorial.lua | ||
| 97 | lua-5.1-work1/test/fib.lua | ||
| 98 | lua-5.1-work1/test/fibfor.lua | ||
| 99 | lua-5.1-work1/test/globals.lua | ||
| 100 | lua-5.1-work1/test/hello.lua | ||
| 101 | lua-5.1-work1/test/life.lua | ||
| 102 | lua-5.1-work1/test/lua | ||
| 103 | lua-5.1-work1/test/luac | ||
| 104 | lua-5.1-work1/test/luac.lua | ||
| 105 | lua-5.1-work1/test/printf.lua | ||
| 106 | lua-5.1-work1/test/readonly.lua | ||
| 107 | lua-5.1-work1/test/sieve.lua | ||
| 108 | lua-5.1-work1/test/sort.lua | ||
| 109 | lua-5.1-work1/test/table.lua | ||
| 110 | lua-5.1-work1/test/trace-calls.lua | ||
| 111 | lua-5.1-work1/test/trace-globals.lua | ||
| 112 | lua-5.1-work1/test/undefined.lua | ||
| 113 | lua-5.1-work1/test/xd.lua | ||
| 114 | END OF MANIFEST | ||
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | This is Lua 5.0. | 1 | This is Lua 5.1 (work). |
| 2 | See HISTORY for a summary of changes since the last released version. | 2 | See HISTORY for a summary of changes since the last released version. |
| 3 | 3 | ||
| 4 | * What is Lua? | 4 | * What is Lua? |
| @@ -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 -ldl | 8 | # 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 | ||
| 26 | echo -n 'luac... ' | 29 | echo -n 'luac... ' |
| 27 | cd ../luac | 30 | cd ../luac |
| 28 | cc -O2 -o ../../bin/luac -I../../include -I.. *.c -DLUA_OPNAMES ../lopcodes.c ../../lib/*.a | 31 | cc -O2 -o ../../bin/luac -I../../include -I.. *.c ../../lib/*.a |
| 29 | 32 | ||
| 30 | echo 'done' | 33 | echo 'done' |
| 31 | 34 | ||
| @@ -1,14 +1,10 @@ | |||
| 1 | # configuration file for making Lua 5.0 | 1 | # configuration file for making Lua 5.1 (work) |
| 2 | # see INSTALL for installation instructions | 2 | # 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 | ||
| 6 | LOADLIB= | 6 | LOADLIB= |
| 7 | DLLIB= | 7 | DLLIB= |
| 8 | NUMBER= | ||
| 9 | POPEN= | ||
| 10 | TMPNAM= | ||
| 11 | DEGREES= | ||
| 12 | USERCONF= | 8 | USERCONF= |
| 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 libraries | 39 | # --------------------------------------------------------------- Lua libraries |
| 44 | 40 | ||
| 45 | # The Lua IO library (src/lib/liolib.c) has support for pipes using popen and | 41 | # 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 core | 43 | # ------------------------------------------------------------------ Lua core |
| 73 | 44 | ||
| 74 | # Lua uses double for numbers. To change this, uncomment and edit the following | 45 | # 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 interpreter | 47 | # ------------------------------------------------------------- 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 | ||
| 168 | V= 5.0 | 125 | V= 5.1 |
| 169 | 126 | ||
| 170 | BIN= $(LUA)/bin | 127 | BIN= $(LUA)/bin |
| 171 | INC= $(LUA)/include | 128 | INC= $(LUA)/include |
| 172 | LIB= $(LUA)/lib | 129 | LIB= $(LUA)/lib |
| 173 | 130 | ||
| 174 | INCS= -I$(INC) $(EXTRA_INCS) | 131 | INCS= -I$(INC) $(EXTRA_INCS) |
| 175 | DEFS= $(NUMBER) $(EXTRA_DEFS) | 132 | DEFS= $(EXTRA_DEFS) |
| 176 | 133 | ||
| 177 | CFLAGS= $(MYCFLAGS) $(WARN) $(INCS) $(DEFS) | 134 | CFLAGS= $(MYCFLAGS) $(WARN) $(INCS) $(DEFS) |
| 178 | 135 | ||
| @@ -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: | ||
| 7 | make echo | ||
| 8 | |||
| 9 | # If you want config as a Lua program, run "make lecho". | ||
| @@ -4,32 +4,29 @@ LUA= .. · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | include $(LUA)/config | 5 | include $(LUA)/config |
| 6 | 6 | ||
| 7 | LIBLUA=$(LIB)/liblua.a | 7 | ALL= min noparser luab 1 |
| 8 | ALL= bin2c min noparser luab | ||
| 9 | 8 | ||
| 10 | all: | 9 | all: |
| 11 | @echo 'choose a target:' $(ALL) | 10 | @echo 'choose a target:' $(ALL) |
| 12 | 11 | ||
| 13 | bin2c: bin2c.c | ||
| 14 | $(CC) $(CFLAGS) -o $@ $@.c | ||
| 15 | |||
| 16 | min: min.c $(LIBLUA) | 12 | min: min.c $(LIBLUA) |
| 17 | $(CC) $(CFLAGS) -o $@ $@.c -L$(LIB) -llua | 13 | $(CC) $(CFLAGS) -o $@ $@.c -L$(LIB) -llua -llualib |
| 18 | 14 | ||
| 19 | noparser: noparser.c | 15 | noparser: noparser.c |
| 20 | $(CC) $(CFLAGS) -I$(LUA)/src -o $@.o -c $@.c | 16 | $(CC) $(CFLAGS) -I$(LUA)/src -o $@.o -c $@.c |
| 21 | 17 | ||
| 22 | luab: noparser $(LIBLUA) | 18 | luab: 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.lua | 20 | $(BIN)/luac $(LUA)/test/hello.lua |
| 25 | $@ luac.out | 21 | $@ luac.out |
| 26 | -$@ -e'a=1' | 22 | -$@ -e'a=1' |
| 27 | 23 | ||
| 24 | 1: | ||
| 25 | $(CC) $(CFLAGS) -I../src -I../src/lib -I../src/lua all.c $(EXTRA_LIBS) $(DLLIB) | ||
| 26 | ./a.out $(LUA)/test/hello.lua | ||
| 27 | |||
| 28 | flat: | 28 | flat: |
| 29 | cd ..; mkdir flat; mv include/*.h src/*.[ch] src/*/*.[ch] flat | 29 | cd ..; mkdir flat; mv include/*.h src/*.[ch] src/*/*.[ch] flat |
| 30 | 30 | ||
| 31 | $(LIBLUA): | ||
| 32 | cd ../src; $(MAKE) | ||
| 33 | |||
| 34 | clean: | 31 | clean: |
| 35 | rm -f $(ALL) a.out core *.o luac.out | 32 | rm -f $(ALL) a.out core *.o luac.out |
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -1,6 +1,10 @@ | |||
| 1 | This directory contains some useful files and code. | 1 | This directory contains some useful files and code. |
| 2 | Unlike the code in ../src, everything here is in the public domain. | 2 | Unlike the code in ../src, everything here is in the public domain. |
| 3 | 3 | ||
| 4 | all.c | ||
| 5 | Full Lua interpreter in a single file. | ||
| 6 | Do "make 1". | ||
| 7 | |||
| 4 | lua.ico | 8 | lua.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>. |
| @@ -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" | ||
| @@ -1,37 +1,47 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * min.c -- a minimal Lua interpreter | 2 | * min.c -- a minimal Lua interpreter |
| 3 | * only dynamic loading is enabled -- all libraries must be dynamically loaded | 3 | * loads stdin only with minimal error handling. |
| 4 | * no interaction, only batch execution | 4 | * 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 | ||
| 12 | static int run(lua_State *L) | 11 | static 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) | 31 | static 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 | ||
| 26 | int main(int argc, char *argv[]) | 40 | int 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 | } |
| @@ -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 NODUMP | 34 | #ifdef NODUMP |
| 32 | #include "lundump.h" | 35 | #include "lundump.h" |
| 33 | 36 | ||
| @@ -4,7 +4,7 @@ LUA= .. · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | include $(LUA)/config | 5 | include $(LUA)/config |
| 6 | 6 | ||
| 7 | SRCS= lua.h lualib.h lauxlib.h | 7 | SRCS= lua.h lualib.h lauxlib.h luaconf.h |
| 8 | 8 | ||
| 9 | all: | 9 | all: |
| 10 | 10 | ||
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -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 libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,10 +15,8 @@ · 9 unmodified lines | |||
| 15 | #include "lua.h" | 15 | #include "lua.h" |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | #ifndef LUALIB_API | 18 | /* extra error code for `luaL_load' */ |
| 19 | #define LUALIB_API LUA_API | 19 | #define LUA_ERRFILE (LUA_ERRERR+1) |
| 20 | #endif | ||
| 21 | |||
| 22 | 20 | ||
| 23 | 21 | ||
| 24 | typedef struct luaL_reg { | 22 | typedef struct luaL_reg { |
| @@ -56,6 +54,9 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...); · 31 unmodified lines | |||
| 56 | 54 | ||
| 57 | LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); | 55 | LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); |
| 58 | 56 | ||
| 57 | LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name, | ||
| 58 | const char *path); | ||
| 59 | |||
| 59 | LUALIB_API int luaL_ref (lua_State *L, int t); | 60 | LUALIB_API int luaL_ref (lua_State *L, int t); |
| 60 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref); | 61 | LUALIB_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 | ||
| 101 | typedef struct luaL_Buffer { | 99 | typedef 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 functions | 126 | #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 | ||
| 130 | LUALIB_API int lua_dofile (lua_State *L, const char *filename); | 134 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) |
| 131 | LUALIB_API int lua_dostring (lua_State *L, const char *str); | ||
| 132 | LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz, | ||
| 133 | const char *n); | ||
| 134 | 135 | ||
| 135 | 136 | ||
| 136 | #endif | 137 | #endif |
| @@ -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 Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
| 5 | ** http://www.lua.org mailto:info@lua.org | 5 | ** 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 1 | 41 | #define LUA_ERRRUN 1 |
| 39 | #define LUA_ERRFILE 2 | 42 | #define LUA_ERRSYNTAX 2 |
| 40 | #define LUA_ERRSYNTAX 3 | 43 | #define LUA_ERRMEM 3 |
| 41 | #define LUA_ERRMEM 4 | 44 | #define LUA_ERRERR 4 |
| 42 | #define LUA_ERRERR 5 | ||
| 43 | 45 | ||
| 44 | 46 | ||
| 45 | typedef struct lua_State lua_State; | 47 | typedef 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 | ||
| 95 | typedef double lua_Number; | ||
| 96 | #else | ||
| 97 | typedef LUA_NUMBER lua_Number; | 96 | typedef LUA_NUMBER lua_Number; |
| 98 | #endif | ||
| 99 | 97 | ||
| 100 | 98 | ||
| 101 | /* type for integer functions */ | 99 | /* type for integer functions */ |
| 102 | #ifndef LUA_INTEGER | ||
| 103 | typedef long lua_Integer; | ||
| 104 | #else | ||
| 105 | typedef LUA_INTEGER lua_Integer; | 100 | typedef 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 manipulation | 105 | ** state manipulation |
| @@ -155,7 +144,7 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int idx); · 38 unmodified lines | |||
| 155 | LUA_API lua_Integer lua_tointeger (lua_State *L, int idx); | 144 | LUA_API lua_Integer lua_tointeger (lua_State *L, int idx); |
| 156 | LUA_API int lua_toboolean (lua_State *L, int idx); | 145 | LUA_API int lua_toboolean (lua_State *L, int idx); |
| 157 | LUA_API const char *lua_tostring (lua_State *L, int idx); | 146 | LUA_API const char *lua_tostring (lua_State *L, int idx); |
| 158 | LUA_API size_t lua_strlen (lua_State *L, int idx); | 147 | LUA_API size_t lua_objsize (lua_State *L, int idx); |
| 159 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx); | 148 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx); |
| 160 | LUA_API void *lua_touserdata (lua_State *L, int idx); | 149 | LUA_API void *lua_touserdata (lua_State *L, int idx); |
| 161 | LUA_API lua_State *lua_tothread (lua_State *L, int idx); | 150 | LUA_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 1 | 217 | #define LUA_GCRESTART 1 |
| 229 | #define LUA_GCCOLLECT 2 | 218 | #define LUA_GCCOLLECT 2 |
| 230 | #define LUA_GCCOUNT 3 | 219 | #define LUA_GCCOUNT 3 |
| 220 | #define LUA_GCSTEP 4 | ||
| 231 | 221 | ||
| 232 | LUA_API int lua_gc (lua_State *L, int what, int data); | 222 | LUA_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 API | 290 | ** Debug API |
| @@ -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 | ||
| @@ -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 libraries | 3 | ** Lua standard libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_API | 14 | /* Key to file-handle type */ |
| 15 | #define LUALIB_API LUA_API | 15 | #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 | |||
| 23 | LUALIB_API int luaopen_table (lua_State *L); | 22 | LUALIB_API int luaopen_table (lua_State *L); |
| 24 | 23 | ||
| 25 | #define LUA_IOLIBNAME "io" | 24 | #define LUA_IOLIBNAME "io" |
| 26 | #define LUA_OSLIBNAME "os" | ||
| 27 | LUALIB_API int luaopen_io (lua_State *L); | 25 | LUALIB_API int luaopen_io (lua_State *L); |
| 28 | 26 | ||
| 27 | #define LUA_OSLIBNAME "os" | ||
| 28 | LUALIB_API int luaopen_os (lua_State *L); | ||
| 29 | |||
| 29 | #define LUA_STRLIBNAME "string" | 30 | #define LUA_STRLIBNAME "string" |
| 30 | LUALIB_API int luaopen_string (lua_State *L); | 31 | LUALIB_API int luaopen_string (lua_State *L); |
| 31 | 32 | ||
| @@ -39,18 +40,8 @@ LUALIB_API int luaopen_debug (lua_State *L); · 7 unmodified lines | |||
| 39 | LUALIB_API int luaopen_loadlib (lua_State *L); | 40 | LUALIB_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_assert | 44 | LUALIB_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 | #endif | 47 | #endif |
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | This is the Lua core. | 1 | This is the Lua core. |
| 2 | 2 | ||
| 3 | The standard Lua library are in lib/. | 3 | The standard Lua library are in lib/. |
| 4 | A sample interpreter is in lua/. | 4 | The standalone interpreter is in lua/. |
| 5 | A standalone compiler is in luac/. | 5 | The standalone compiler is in luac/. |
| @@ -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 API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 12 | #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 | ||
| 37 | const char lua_ident[] = | 33 | const 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 | |||
| 56 | static TValue *luaA_index (lua_State *L, int idx) { | 48 | static 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 | |||
| 87 | LUA_API int lua_checkstack (lua_State *L, int size) { | 79 | LUA_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 | ||
| 334 | LUA_API size_t lua_strlen (lua_State *L, int idx) { | 326 | LUA_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 | |||
| 701 | LUA_API void lua_call (lua_State *L, int nargs, int nresults) { | 705 | LUA_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 | ||
| 814 | LUA_API int lua_gc (lua_State *L, int what, int data) { | 823 | LUA_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 | } |
| @@ -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 Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #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 | ||
| 196 | static void freereg (FuncState *fs, int reg) { | 197 | static 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 | ||
| 254 | void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { | 255 | void 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 | |||
| 267 | void 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; |
| @@ -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 Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | |||
| 44 | int luaK_code (FuncState *fs, Instruction i, int line); | 46 | int luaK_code (FuncState *fs, Instruction i, int line); |
| 45 | int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | 47 | int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
| 46 | int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); | 48 | int 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 | |||
| 60 | void luaK_goiftrue (FuncState *fs, expdesc *e); | 62 | void luaK_goiftrue (FuncState *fs, expdesc *e); |
| 61 | void luaK_goiffalse (FuncState *fs, expdesc *e); | 63 | void luaK_goiffalse (FuncState *fs, expdesc *e); |
| 62 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); | 64 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); |
| 63 | void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); | 65 | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); |
| 66 | void luaK_setoneret (FuncState *fs, expdesc *e); | ||
| 64 | int luaK_jump (FuncState *fs); | 67 | int luaK_jump (FuncState *fs); |
| 65 | void luaK_patchlist (FuncState *fs, int list, int target); | 68 | void luaK_patchlist (FuncState *fs, int list, int target); |
| 66 | void luaK_patchtohere (FuncState *fs, int list); | 69 | void luaK_patchtohere (FuncState *fs, int list); |
| @@ -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 Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -11,6 +11,7 @@ · 5 unmodified lines | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | #define ldebug_c | 13 | #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 | ||
| 35 | static int currentpc (CallInfo *ci) { | 36 | static 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 | else | 227 | 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 | ||
| 257 | static 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 | |
| 260 | int 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 | ||
| 425 | static const char *kname (Proto *p, int c) { | 434 | static 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 | else | 437 | 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 | ||
| 480 | static const char *getfuncname (CallInfo *ci, const char **name) { | 488 | static 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 | else | 497 | else |
| 489 | return NULL; /* no useful name can be found */ | 498 | return NULL; /* no useful name can be found */ |
| @@ -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 module | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | |||
| 25 | void luaG_runerror (lua_State *L, const char *fmt, ...); | 25 | void luaG_runerror (lua_State *L, const char *fmt, ...); |
| 26 | void luaG_errormsg (lua_State *L); | 26 | void luaG_errormsg (lua_State *L); |
| 27 | int luaG_checkcode (const Proto *pt); | 27 | int luaG_checkcode (const Proto *pt); |
| 28 | 28 | int luaG_checkopenop (Instruction i); | |
| 29 | 29 | ||
| 30 | #endif | 30 | #endif |
| @@ -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 Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <setjmp.h> | ||
| 9 | #include <stdlib.h> | 8 | #include <stdlib.h> |
| 10 | #include <string.h> | 9 | #include <string.h> |
| 11 | 10 | ||
| 12 | #define ldo_c | 11 | #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 */ |
| 57 | struct lua_longjmp { | 43 | struct 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 | ||
| 198 | static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { | 185 | static 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 | ||
| 236 | StkId luaD_precall (lua_State *L, StkId func) { | 234 | int 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 | */ |
| 313 | void luaD_call (lua_State *L, StkId func, int nResults) { | 327 | void 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 */ |
| @@ -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 Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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' */ |
| 42 | typedef void (*Pfunc) (lua_State *L, void *ud); | 48 | typedef void (*Pfunc) (lua_State *L, void *ud); |
| 43 | 49 | ||
| 44 | void luaD_resetprotection (lua_State *L); | 50 | void luaD_resetprotection (lua_State *L); |
| 45 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); | 51 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); |
| 46 | void luaD_callhook (lua_State *L, int event, int line); | 52 | void luaD_callhook (lua_State *L, int event, int line); |
| 47 | StkId luaD_precall (lua_State *L, StkId func); | 53 | int luaD_precall (lua_State *L, StkId func, int nresults); |
| 48 | void luaD_call (lua_State *L, StkId func, int nResults); | 54 | void luaD_call (lua_State *L, StkId func, int nResults); |
| 49 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 55 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 50 | ptrdiff_t oldtop, ptrdiff_t ef); | 56 | ptrdiff_t oldtop, ptrdiff_t ef); |
| @@ -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 bytecodes | 3 | ** save pre-compiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <stddef.h> | 7 | #include <stddef.h> |
| 8 | 8 | ||
| 9 | #define ldump_c | 9 | #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 | ||
| 21 | typedef struct { | 22 | typedef 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 | ||
| 28 | static void DumpBlock(const void* b, size_t size, DumpState* D) | 30 | static 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 | ||
| 35 | static void DumpByte(int y, DumpState* D) | 40 | static 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 | ||
| 56 | static void DumpString(TString* s, DumpState* D) | 61 | static 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 chunk | 161 | ** dump Lua function as precompiled chunk |
| 157 | */ | 162 | */ |
| 158 | int luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data, int strip) | 163 | int 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 | } |
| @@ -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 closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | |||
| 8 | #include <stddef.h> | 8 | #include <stddef.h> |
| 9 | 9 | ||
| 10 | #define lfunc_c | 10 | #define lfunc_c |
| 11 | #define LUA_CORE | ||
| 11 | 12 | ||
| 12 | #include "lua.h" | 13 | #include "lua.h" |
| 13 | 14 | ||
| @@ -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 Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 9 | #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 | */ |
| 272 | static l_mem propagatemarks (global_State *g, l_mem lim) { | 274 | static 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 | |||
| 324 | static 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 | ||
| 396 | static 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 | ||
| 400 | static GCObject **sweeplist (lua_State *L, GCObject **p, int keepfixed, | 404 | static 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 | ||
| 431 | static 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 | ||
| 440 | static l_mem sweepstrings (lua_State *L, int keepfixed, l_mem lim) { | 432 | static 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 | ||
| 497 | void luaC_sweepall (lua_State *L) { | 487 | void 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 | ||
| 541 | static void atomic (lua_State *L) { | 526 | static 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 | ||
| 566 | static l_mem singlestep (lua_State *L, l_mem lim) { | 559 | static 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 | ||
| 612 | void luaC_step (lua_State *L) { | 612 | void 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 | ||
| 625 | void luaC_fullgc (lua_State *L) { | 635 | void 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 | |||
| 639 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 665 | void 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 | ||
| 676 | void 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 | |||
| 650 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { | 686 | void 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 | } |
| @@ -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 Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -14,10 +14,11 @@ · 8 unmodified lines | |||
| 14 | /* | 14 | /* |
| 15 | ** Possible states of the Garbage Collector | 15 | ** Possible states of the Garbage Collector |
| 16 | */ | 16 | */ |
| 17 | #define GCSpropagate 0 | 17 | #define GCSpause 0 |
| 18 | #define GCSsweepstring 1 | 18 | #define GCSpropagate 1 |
| 19 | #define GCSsweep 2 | 19 | #define GCSsweepstring 2 |
| 20 | #define GCSfinalize 3 | 20 | #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 gray | 43 | ** bit 0 - object is white (type 0) |
| 43 | ** bit 1 - object is black | 44 | ** 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 keys | 46 | ** bit 3 - for userdata: has been finalized |
| 46 | ** bit 3 - for tables: has weak values | 47 | ** 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 0 | 52 | #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 | ||
| 84 | size_t luaC_separateudata (lua_State *L, int all); | 89 | size_t luaC_separateudata (lua_State *L, int all); |
| 85 | void luaC_callGCTM (lua_State *L); | 90 | void luaC_callGCTM (lua_State *L); |
| 86 | void luaC_sweepall (lua_State *L); | 91 | void luaC_freeall (lua_State *L); |
| 87 | void luaC_step (lua_State *L); | 92 | void luaC_step (lua_State *L); |
| 88 | void luaC_fullgc (lua_State *L); | 93 | void luaC_fullgc (lua_State *L); |
| 89 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | 94 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt); |
| 90 | void luaC_linkupval (lua_State *L, UpVal *uv); | 95 | void luaC_linkupval (lua_State *L, UpVal *uv); |
| 91 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); | 96 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); |
| 97 | void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v); | ||
| 92 | 98 | ||
| 93 | 99 | ||
| 94 | #endif | 100 | #endif |
| @@ -6,8 +6,8 @@ include $(LUA)/config · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | EXTRA_DEFS= $(POPEN) $(TMPNAM) $(DEGREES) $(LOADLIB) | 7 | EXTRA_DEFS= $(POPEN) $(TMPNAM) $(DEGREES) $(LOADLIB) |
| 8 | 8 | ||
| 9 | OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o ltablib.o lstrlib.o loadlib.o | 9 | OBJS= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o loadlib.o linit.o |
| 10 | SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c ltablib.c lstrlib.c loadlib.c | 10 | SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c ltablib.c lstrlib.c loadlib.c linit.c |
| 11 | 11 | ||
| 12 | T= $(LIB)/liblualib.a | 12 | T= $(LIB)/liblualib.a |
| 13 | 13 | ||
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -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 libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -18,6 +18,7 @@ · 12 unmodified lines | |||
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #define lauxlib_c | 20 | #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 | ||
| 63 | LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { | 64 | LUALIB_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 | ||
| 291 | void luaL_setn (lua_State *L, int t, int n) { | 294 | LUALIB_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 | ||
| 301 | int luaL_getn (lua_State *L, int t) { | 304 | /* find an `n' such that t[n] ~= nil and t[n+1] == nil */ |
| 305 | static 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 | |||
| 329 | LUALIB_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 | ||
| 344 | static 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 | |||
| 355 | static 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 | |||
| 372 | LUALIB_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 | ||
| 483 | static int errfile (lua_State *L, int fnameindex) { | 554 | static 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 | ||
| 571 | LUALIB_API lua_State *luaL_newstate (void) { | 644 | static 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 | |||
| 583 | static 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 | ||
| 598 | static int aux_do (lua_State *L, int status) { | 650 | LUALIB_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 | |||
| 607 | LUALIB_API int lua_dofile (lua_State *L, const char *filename) { | ||
| 608 | return aux_do(L, luaL_loadfile(L, filename)); | ||
| 609 | } | ||
| 610 | |||
| 611 | |||
| 612 | LUALIB_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 | |||
| 618 | LUALIB_API int lua_dostring (lua_State *L, const char *str) { | ||
| 619 | return lua_dobuffer(L, str, strlen(str), str); | ||
| 620 | } | 654 | } |
| 621 | 655 | ||
| 622 | /* }====================================================== */ | ||
| @@ -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 library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 14 | #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 | ||
| 131 | static 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 | |||
| 139 | static int luaB_getfenv (lua_State *L) { | 132 | static 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 | |||
| 147 | static int luaB_setfenv (lua_State *L) { | 139 | static 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 | ||
| 193 | static int luaB_collectgarbage (lua_State *L) { | 183 | static 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 | ||
| 217 | static int luaB_type (lua_State *L) { | 196 | static 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 | ||
| 236 | static int luaB_pairs (lua_State *L) { | 215 | static 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 | ||
| 224 | static 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 | |||
| 245 | static int luaB_ipairs (lua_State *L) { | 234 | static 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 | ||
| 282 | static int luaB_loadfile (lua_State *L) { | 262 | static 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 | ||
| 347 | static int luaB_unpack (lua_State *L) { | 334 | static 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 | ||
| 350 | static 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 | |||
| 358 | static int luaB_pcall (lua_State *L) { | 365 | static 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 | ||
| 380 | static int luaB_tostring (lua_State *L) { | 387 | static 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 | |||
| 476 | static const char *getpath (lua_State *L) { | 455 | static 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 | |||
| 488 | static 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 | |||
| 499 | static 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 | ||
| 516 | static int luaB_require (lua_State *L) { | 468 | static 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 | ||
| 629 | static 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 | ||
| 708 | static void base_open (lua_State *L) { | 637 | static 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 | ||
| 725 | LUALIB_API int luaopen_base (lua_State *L) { | 671 | LUALIB_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 | ||
| @@ -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 API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 12 | #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 | else | 314 | 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 | } |
| @@ -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 | |||
| 17 | static 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 | |||
| 30 | LUALIB_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 | |||
| @@ -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) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #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_c | 13 | #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 1 | 23 | #define IO_INPUT 1 |
| 65 | #define IO_OUTPUT 2 | 24 | #define IO_OUTPUT 2 |
| 66 | 25 | ||
| 67 | 26 | ||
| 27 | static const char *const fnames[] = {"input", "output"}; | ||
| 28 | |||
| 29 | |||
| 68 | static int pushresult (lua_State *L, int i, const char *filename) { | 30 | static 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 | ||
| 85 | static FILE **topfile (lua_State *L, int findex) { | 47 | static 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 | |||
| 53 | static 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 | ||
| 92 | static int io_type (lua_State *L) { | 60 | static 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 | ||
| 103 | static FILE *tofile (lua_State *L, int findex) { | 71 | static 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 | |||
| 117 | static FILE **newfile (lua_State *L) { | 85 | static 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 | ||
| 126 | static int aux_close (lua_State *L) { | 94 | static 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 | ||
| 146 | static int io_gc (lua_State *L) { | 114 | static 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 | ||
| 154 | static int io_tostring (lua_State *L) { | 122 | static 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 | else | 126 | 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 | ||
| 175 | static 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 | |||
| 189 | static int io_tmpfile (lua_State *L) { | 141 | static 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 | ||
| 196 | static FILE *getiofile (lua_State *L, int f) { | 148 | static 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 | ||
| 238 | static void aux_lines (lua_State *L, int idx, int close) { | 194 | static 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 | ||
| 246 | static int f_lines (lua_State *L) { | 202 | static 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 | ||
| 386 | static int f_read (lua_State *L) { | 346 | static 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 | ||
| 391 | static int io_readline (lua_State *L) { | 351 | static 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 | ||
| 433 | static int f_write (lua_State *L) { | 397 | static 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 | ||
| 438 | static int f_seek (lua_State *L) { | 402 | static 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 | |||
| 455 | static int f_setvbuf (lua_State *L) { | 419 | static 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 | ||
| 471 | static int f_flush (lua_State *L) { | 435 | static 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 | ||
| 506 | static void createmeta (lua_State *L) { | 469 | static 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 | |||
| 528 | static int io_execute (lua_State *L) { | ||
| 529 | lua_pushinteger(L, system(luaL_checkstring(L, 1))); | ||
| 530 | return 1; | ||
| 531 | } | ||
| 532 | |||
| 533 | |||
| 534 | static 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 | |||
| 540 | static 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 | |||
| 547 | static 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 | ||
| 561 | static int io_getenv (lua_State *L) { | 477 | static 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; | |
| 567 | static 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 | |||
| 581 | static 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 | |||
| 587 | static 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 | |||
| 593 | static 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 | |||
| 602 | static 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 | |||
| 617 | static 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 | |||
| 653 | static 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 | |||
| 678 | static 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 | |||
| 687 | static 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 | |||
| 701 | static int io_exit (lua_State *L) { | ||
| 702 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); | ||
| 703 | return 0; /* to avoid warnings */ | ||
| 704 | } | 484 | } |
| 705 | 485 | ||
| 706 | static 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 | ||
| 725 | LUALIB_API int luaopen_io (lua_State *L) { | 488 | LUALIB_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 | ||
| @@ -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 library | 3 | ** Standard mathematical library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 11 | #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 | |||
| 38 | static int math_abs (lua_State *L) { | 26 | static 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 | ||
| 43 | static int math_sin (lua_State *L) { | 31 | static 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 | ||
| 48 | static int math_cos (lua_State *L) { | 36 | static 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 | ||
| 53 | static int math_tan (lua_State *L) { | 41 | static 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 | ||
| 58 | static int math_asin (lua_State *L) { | 46 | static 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 | ||
| 63 | static int math_acos (lua_State *L) { | 51 | static 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 | ||
| 68 | static int math_atan (lua_State *L) { | 56 | static 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 | ||
| 73 | static int math_atan2 (lua_State *L) { | 61 | static 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 | ||
| @@ -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 Lua | 3 | ** Dynamic library loader for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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" |
| @@ -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 | |||
| 23 | static 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 | |||
| 40 | static int io_execute (lua_State *L) { | ||
| 41 | lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); | ||
| 42 | return 1; | ||
| 43 | } | ||
| 44 | |||
| 45 | |||
| 46 | static 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 | |||
| 52 | static 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 | |||
| 59 | static 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 | |||
| 73 | static 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 | |||
| 79 | static 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 | |||
| 93 | static 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 | |||
| 99 | static 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 | |||
| 105 | static 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 | |||
| 114 | static 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 | |||
| 129 | static 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 | |||
| 165 | static 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 | |||
| 190 | static 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 | |||
| 199 | static 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 | |||
| 213 | static int io_exit (lua_State *L) { | ||
| 214 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); | ||
| 215 | return 0; /* to avoid warnings */ | ||
| 216 | } | ||
| 217 | |||
| 218 | static 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 | |||
| 237 | LUALIB_API int luaopen_os (lua_State *L) { | ||
| 238 | luaL_openlib(L, LUA_OSLIBNAME, syslib, 0); | ||
| 239 | return 1; | ||
| 240 | } | ||
| 241 | |||
| @@ -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-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -12,6 +12,7 @@ · 6 unmodified lines | |||
| 12 | #include <string.h> | 12 | #include <string.h> |
| 13 | 13 | ||
| 14 | #define lstrlib_c | 14 | #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 | ||
| 28 | typedef lua_Integer sint32; /* a signed version for size_t */ | 27 | typedef lua_Integer sint32; /* a signed version for size_t */ |
| @@ -108,11 +107,17 @@ static int str_rep (lua_State *L) { · 79 unmodified lines | |||
| 108 | static int str_byte (lua_State *L) { | 107 | static 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 | |||
| 134 | static int writer (lua_State *L, const void* b, size_t size, void* B) { | 139 | static 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 | ||
| 141 | static int str_dump (lua_State *L) { | 146 | static 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) |
| @@ -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 Manipulation | 3 | ** Library for Table Manipulation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #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 | |||
| 62 | static int luaB_setn (lua_State *L) { | 63 | static 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 | ||
| 69 | static int luaB_tinsert (lua_State *L) { | 71 | static 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 | ||
| 91 | static int luaB_tremove (lua_State *L) { | 93 | static 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 | ||
| @@ -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 Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 11 | #define llex_c |
| 12 | #define LUA_CORE | ||
| 12 | 13 | ||
| 13 | #include "lua.h" | 14 | #include "lua.h" |
| 14 | 15 | ||
| @@ -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' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,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 | ||
| 49 | typedef LUA_UINT32 lu_int32; | 19 | typedef 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 | |||
| 60 | typedef LUA_INT32 l_int32; | 21 | typedef 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 | ||
| 99 | typedef union { double u; void *s; long l; } L_Umaxalign; | ||
| 100 | #else | ||
| 101 | typedef LUSER_ALIGNMENT_T L_Umaxalign; | 59 | typedef 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 | ||
| 107 | typedef double l_uacNumber; | ||
| 108 | #else | ||
| 109 | typedef LUA_UACNUMBER l_uacNumber; | 63 | typedef 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_exp | 66 | #ifndef check_exp |
| @@ -138,43 +86,11 @@ typedef LUA_UACNUMBER l_uacNumber; · 19 unmodified lines | |||
| 138 | typedef lu_int32 Instruction; | 86 | typedef 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 250 | 91 | #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 MINSTRTABSIZE | 96 | #ifndef MINSTRTABSIZE |
| @@ -188,13 +104,4 @@ typedef lu_int32 Instruction; · 7 unmodified lines | |||
| 188 | #endif | 104 | #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 | #endif | 107 | #endif |
| @@ -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 Manager | 3 | ** Interface to Memory Manager |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #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 | ||
| @@ -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 objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 12 | #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 | ||
| 30 | const TValue luaO_nilobject = {LUA_TNIL, {NULL}}; | 26 | const 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 */ |
| 102 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 98 | const 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 \""); |
| @@ -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 objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | |||
| 252 | typedef struct LocVar { | 256 | typedef 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 */ |
| @@ -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.h | 3 | ** See Copyright Notice in lua.h |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | 6 | ||
| 7 | #define lopcodes_c | 7 | #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 | |||
| 19 | const char *const luaP_opnames[NUM_OPCODES] = { | 18 | const 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 | ||
| @@ -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 machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 6 | 42 | #define SIZE_OP 6 |
| 43 | 43 | ||
| 44 | #define POS_C SIZE_OP | 44 | #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_C | 48 | #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-1 | 56 | #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 | #else | 59 | #else |
| @@ -76,10 +77,11 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ · 17 unmodified lines | |||
| 76 | ** the following macros help to manipulate instructions | 77 | ** 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) - register | 140 | ** 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 | |||
| 183 | OP_SETLISTO,/* A Bx */ | 202 | OP_SETLISTO,/* A Bx */ |
| 184 | 203 | ||
| 185 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ | 204 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ |
| 186 | OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ | 205 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ |
| 206 | |||
| 207 | OP_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, so | 218 | 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 jump | 228 | (*) All `skips' (pc++) assume that next instruction is a jump |
| 205 | ===========================================================================*/ | 229 | ===========================================================================*/ |
| 206 | 230 | ||
| 207 | 231 | ||
| @@ -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 Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #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 | |||
| 271 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | 274 | static 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 | ||
| 481 | static void lastlistfield (FuncState *fs, struct ConsControl *cc) { | 485 | static 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 by | 986 | ** 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 | } |
| @@ -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 Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | ||
| 36 | typedef struct expdesc { | 37 | typedef struct expdesc { |
| @@ -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 State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #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 | */ |
| 76 | static void f_luaopen (lua_State *L, void *ud) { | 78 | static 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 | |||
| 119 | static void close_state (lua_State *L) { | 124 | static 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 | ||
| @@ -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 State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | ||
| 42 | struct lua_longjmp; /* defined in ldo.c */ | 18 | struct lua_longjmp; /* defined in ldo.c */ |
| 43 | 19 | ||
| @@ -70,25 +46,20 @@ typedef struct stringtable { · 26 unmodified lines | |||
| 70 | ** informations about a call | 46 | ** informations about a call |
| 71 | */ | 47 | */ |
| 72 | typedef struct CallInfo { | 48 | typedef 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; |
| @@ -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.h | 4 | ** 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_c | 10 | #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 | ||
| 21 | void 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 | |||
| 27 | void luaS_resize (lua_State *L, int newsize) { | 22 | void 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; |
| @@ -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.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,7 +26,6 @@ · 20 unmodified lines | |||
| 26 | 26 | ||
| 27 | void luaS_resize (lua_State *L, int newsize); | 27 | void luaS_resize (lua_State *L, int newsize); |
| 28 | Udata *luaS_newudata (lua_State *L, size_t s); | 28 | Udata *luaS_newudata (lua_State *L, size_t s); |
| 29 | void luaS_freeall (lua_State *L); | ||
| 30 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 29 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
| 31 | 30 | ||
| 32 | 31 | ||
| @@ -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.h | 4 | ** 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_c | 23 | #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^MAXBITS | 38 | ** max size of array part is 2^MAXBITS |
| 38 | */ | 39 | */ |
| 39 | #if BITS_INT > 26 | 40 | #if LUA_BITSINT > 26 |
| 40 | #define MAXBITS 24 | 41 | #define MAXBITS 24 |
| 41 | #else | 42 | #else |
| 42 | #define MAXBITS (BITS_INT-2) | 43 | #define MAXBITS (LUA_BITSINT-2) |
| 43 | #endif | 44 | #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 | ||
| 273 | static void resize (lua_State *L, Table *t, int nasize, int nhsize) { | 269 | void 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 | |||
| 315 | static void rehash (lua_State *L, Table *t) { | 311 | static 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 | */ | ||
| 357 | void 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 | */ | ||
| 423 | static 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 integers | 397 | ** search function for integers |
| 437 | */ | 398 | */ |
| @@ -470,6 +431,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { · 32 unmodified lines | |||
| 470 | */ | 431 | */ |
| 471 | const TValue *luaH_get (Table *t, const TValue *key) { | 432 | const 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 | ||
| @@ -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.h | 4 | ** 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 | |||
| 22 | const TValue *luaH_get (Table *t, const TValue *key); | 22 | const TValue *luaH_get (Table *t, const TValue *key); |
| 23 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key); | 23 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key); |
| 24 | Table *luaH_new (lua_State *L, int narray, int lnhash); | 24 | Table *luaH_new (lua_State *L, int narray, int lnhash); |
| 25 | void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); | ||
| 25 | void luaH_free (lua_State *L, Table *t); | 26 | void luaH_free (lua_State *L, Table *t); |
| 26 | int luaH_next (lua_State *L, Table *t, StkId key); | 27 | int luaH_next (lua_State *L, Table *t, StkId key); |
| 27 | 28 | ||
| @@ -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 | |||
| 42 | static lua_State *lua_state = NULL; | ||
| 43 | |||
| 44 | int islocked = 0; | ||
| 45 | |||
| 46 | |||
| 47 | #define func_at(L,k) (L->ci->base+(k) - 1) | ||
| 48 | |||
| 49 | |||
| 50 | static 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 | |||
| 83 | unsigned long memdebug_numblocks = 0; | ||
| 84 | unsigned long memdebug_total = 0; | ||
| 85 | unsigned long memdebug_maxmem = 0; | ||
| 86 | unsigned long memdebug_memlimit = ULONG_MAX; | ||
| 87 | |||
| 88 | |||
| 89 | static void *checkblock (void *block, size_t size) { | ||
| 90 | void *b = blockhead(block); | ||
| 91 | int i; | ||
| 92 | for (i=0;i<MARKSIZE;i++) | ||
| 93 | lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */ | ||
| 94 | return b; | ||
| 95 | } | ||
| 96 | |||
| 97 | |||
| 98 | static void freeblock (void *block, size_t size) { | ||
| 99 | if (block) { | ||
| 100 | lua_assert(checkblocksize(block, size)); | ||
| 101 | block = checkblock(block, size); | ||
| 102 | fillmem(block, size+HEADER+MARKSIZE); /* erase block */ | ||
| 103 | free(block); /* free original block */ | ||
| 104 | memdebug_numblocks--; | ||
| 105 | memdebug_total -= size; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | void *debug_realloc (void *block, size_t oldsize, size_t size) { | ||
| 111 | lua_assert(oldsize == 0 || checkblocksize(block, oldsize)); | ||
| 112 | /* ISO does not specify what realloc(NULL, 0) does */ | ||
| 113 | lua_assert(block != NULL || size > 0); | ||
| 114 | if (size == 0) { | ||
| 115 | freeblock(block, oldsize); | ||
| 116 | return NULL; | ||
| 117 | } | ||
| 118 | else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit) | ||
| 119 | return NULL; /* to test memory allocation errors */ | ||
| 120 | else { | ||
| 121 | void *newblock; | ||
| 122 | int i; | ||
| 123 | size_t realsize = HEADER+size+MARKSIZE; | ||
| 124 | size_t commonsize = (oldsize < size) ? oldsize : size; | ||
| 125 | if (realsize < size) return NULL; /* overflow! */ | ||
| 126 | newblock = malloc(realsize); /* alloc a new block */ | ||
| 127 | if (newblock == NULL) return NULL; | ||
| 128 | if (block) { | ||
| 129 | memcpy(cast(char *, newblock)+HEADER, block, commonsize); | ||
| 130 | freeblock(block, oldsize); /* erase (and check) old copy */ | ||
| 131 | } | ||
| 132 | /* initialize new part of the block with something `weird' */ | ||
| 133 | fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); | ||
| 134 | memdebug_total += size; | ||
| 135 | if (memdebug_total > memdebug_maxmem) | ||
| 136 | memdebug_maxmem = memdebug_total; | ||
| 137 | memdebug_numblocks++; | ||
| 138 | setsize(newblock, size); | ||
| 139 | for (i=0;i<MARKSIZE;i++) | ||
| 140 | *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i); | ||
| 141 | return cast(char *, newblock)+HEADER; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | |||
| 146 | /* }====================================================================== */ | ||
| 147 | |||
| 148 | |||
| 149 | |||
| 150 | /* | ||
| 151 | ** {====================================================== | ||
| 152 | ** Disassembler | ||
| 153 | ** ======================================================= | ||
| 154 | */ | ||
| 155 | |||
| 156 | |||
| 157 | static 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 | ||
| 180 | void luaI_printcode (Proto *pt, int size) { | ||
| 181 | int pc; | ||
| 182 | for (pc=0; pc<size; pc++) { | ||
| 183 | char buff[100]; | ||
| 184 | printf("%s\n", buildop(pt, pc, buff)); | ||
| 185 | } | ||
| 186 | printf("-------\n"); | ||
| 187 | } | ||
| 188 | #endif | ||
| 189 | |||
| 190 | |||
| 191 | static 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 | |||
| 210 | static 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 | |||
| 226 | static 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 | |||
| 244 | static 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 | |||
| 256 | static 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 | |||
| 270 | static 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 | |||
| 286 | static int stacklevel (lua_State *L) { | ||
| 287 | unsigned long a = 0; | ||
| 288 | lua_pushintegral(L, (int)(L->top - L->stack)); | ||
| 289 | lua_pushintegral(L, (int)(L->stack_last - L->stack)); | ||
| 290 | lua_pushintegral(L, (int)(L->ci - L->base_ci)); | ||
| 291 | lua_pushintegral(L, (int)(L->end_ci - L->base_ci)); | ||
| 292 | lua_pushintegral(L, (unsigned long)&a); | ||
| 293 | return 5; | ||
| 294 | } | ||
| 295 | |||
| 296 | |||
| 297 | static 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 | |||
| 330 | static 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 | |||
| 352 | static 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 | |||
| 362 | static 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 | |||
| 369 | static 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 | |||
| 376 | static int metatable (lua_State *L) { | ||
| 377 | luaL_checkany(L, 1); | ||
| 378 | if (lua_isnone(L, 2)) { | ||
| 379 | if (lua_getmetatable(L, 1) == 0) | ||
| 380 | lua_pushnil(L); | ||
| 381 | } | ||
| 382 | else { | ||
| 383 | lua_settop(L, 2); | ||
| 384 | luaL_checktype(L, 2, LUA_TTABLE); | ||
| 385 | lua_setmetatable(L, 1); | ||
| 386 | } | ||
| 387 | return 1; | ||
| 388 | } | ||
| 389 | |||
| 390 | |||
| 391 | static int upvalue (lua_State *L) { | ||
| 392 | int n = luaL_checkint(L, 2); | ||
| 393 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
| 394 | if (lua_isnone(L, 3)) { | ||
| 395 | const char *name = lua_getupvalue(L, 1, n); | ||
| 396 | if (name == NULL) return 0; | ||
| 397 | lua_pushstring(L, name); | ||
| 398 | return 2; | ||
| 399 | } | ||
| 400 | else { | ||
| 401 | const char *name = lua_setupvalue(L, 1, n); | ||
| 402 | lua_pushstring(L, name); | ||
| 403 | return 1; | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | |||
| 408 | static 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 | |||
| 416 | static int pushuserdata (lua_State *L) { | ||
| 417 | lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); | ||
| 418 | return 1; | ||
| 419 | } | ||
| 420 | |||
| 421 | |||
| 422 | static int udataval (lua_State *L) { | ||
| 423 | lua_pushintegral(L, cast(int, lua_touserdata(L, 1))); | ||
| 424 | return 1; | ||
| 425 | } | ||
| 426 | |||
| 427 | |||
| 428 | static int doonnewstack (lua_State *L) { | ||
| 429 | lua_State *L1 = lua_newthread(L); | ||
| 430 | size_t l; | ||
| 431 | const char *s = luaL_checklstring(L, 1, &l); | ||
| 432 | int status = luaL_loadbuffer(L1, s, l, s); | ||
| 433 | if (status == 0) | ||
| 434 | status = lua_pcall(L1, 0, 0, 0); | ||
| 435 | lua_pushintegral(L, status); | ||
| 436 | return 1; | ||
| 437 | } | ||
| 438 | |||
| 439 | |||
| 440 | static int s2d (lua_State *L) { | ||
| 441 | lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1))); | ||
| 442 | return 1; | ||
| 443 | } | ||
| 444 | |||
| 445 | static int d2s (lua_State *L) { | ||
| 446 | double d = luaL_checknumber(L, 1); | ||
| 447 | lua_pushlstring(L, cast(char *, &d), sizeof(d)); | ||
| 448 | return 1; | ||
| 449 | } | ||
| 450 | |||
| 451 | |||
| 452 | static 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 | |||
| 464 | static 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 | |||
| 481 | static 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 | |||
| 488 | static 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 | |||
| 513 | static int log2_aux (lua_State *L) { | ||
| 514 | lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1))); | ||
| 515 | return 1; | ||
| 516 | } | ||
| 517 | |||
| 518 | static int int2fb_aux (lua_State *L) { | ||
| 519 | int b = luaO_int2fb(luaL_checkint(L, 1)); | ||
| 520 | lua_pushintegral(L, b); | ||
| 521 | lua_pushintegral(L, fb2int(b)); | ||
| 522 | return 2; | ||
| 523 | } | ||
| 524 | |||
| 525 | |||
| 526 | static int test_do (lua_State *L) { | ||
| 527 | const char *p = luaL_checkstring(L, 1); | ||
| 528 | if (*p == '@') | ||
| 529 | lua_dofile(L, p+1); | ||
| 530 | else | ||
| 531 | lua_dostring(L, p); | ||
| 532 | return lua_gettop(L); | ||
| 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 | |||
| 544 | static const char *const delimits = " \t\n,;"; | ||
| 545 | |||
| 546 | static void skip (const char **pc) { | ||
| 547 | while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; | ||
| 548 | } | ||
| 549 | |||
| 550 | static 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 | |||
| 568 | static 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 | |||
| 584 | static 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 | |||
| 744 | static void yieldf (lua_State *L, lua_Debug *ar) { | ||
| 745 | lua_yield(L, 0); | ||
| 746 | } | ||
| 747 | |||
| 748 | static int setyhook (lua_State *L) { | ||
| 749 | if (lua_isnoneornil(L, 1)) | ||
| 750 | lua_sethook(L, NULL, 0, 0); /* turn off hooks */ | ||
| 751 | else { | ||
| 752 | const char *smask = luaL_checkstring(L, 1); | ||
| 753 | int count = luaL_optint(L, 2, 0); | ||
| 754 | int mask = 0; | ||
| 755 | if (strchr(smask, 'l')) mask |= LUA_MASKLINE; | ||
| 756 | if (count > 0) mask |= LUA_MASKCOUNT; | ||
| 757 | lua_sethook(L, yieldf, mask, count); | ||
| 758 | } | ||
| 759 | return 0; | ||
| 760 | } | ||
| 761 | |||
| 762 | |||
| 763 | static int coresume (lua_State *L) { | ||
| 764 | int status; | ||
| 765 | lua_State *co = lua_tothread(L, 1); | ||
| 766 | luaL_argcheck(L, co, 1, "coroutine expected"); | ||
| 767 | status = lua_resume(co, 0); | ||
| 768 | if (status != 0) { | ||
| 769 | lua_pushboolean(L, 0); | ||
| 770 | lua_insert(L, -2); | ||
| 771 | return 2; /* return false + error message */ | ||
| 772 | } | ||
| 773 | else { | ||
| 774 | lua_pushboolean(L, 1); | ||
| 775 | return 1; | ||
| 776 | } | ||
| 777 | } | ||
| 778 | |||
| 779 | /* }====================================================== */ | ||
| 780 | |||
| 781 | |||
| 782 | |||
| 783 | static 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 | |||
| 818 | static void fim (void) { | ||
| 819 | if (!islocked) | ||
| 820 | lua_close(lua_state); | ||
| 821 | lua_assert(memdebug_numblocks == 0); | ||
| 822 | lua_assert(memdebug_total == 0); | ||
| 823 | } | ||
| 824 | |||
| 825 | |||
| 826 | static int l_panic (lua_State *L) { | ||
| 827 | UNUSED(L); | ||
| 828 | fprintf(stderr, "unable to recover; exiting\n"); | ||
| 829 | return 0; | ||
| 830 | } | ||
| 831 | |||
| 832 | |||
| 833 | int luaB_opentests (lua_State *L) { | ||
| 834 | lua_atpanic(L, l_panic); | ||
| 835 | lua_userstateopen(L); /* init lock */ | ||
| 836 | lua_state = L; /* keep first state to be opened */ | ||
| 837 | luaL_openlib(L, "T", tests_funcs, 0); | ||
| 838 | atexit(fim); | ||
| 839 | return 0; | ||
| 840 | } | ||
| 841 | |||
| 842 | |||
| 843 | #undef main | ||
| 844 | int main (int argc, char *argv[]) { | ||
| 845 | char *limit = getenv("MEMLIMIT"); | ||
| 846 | if (limit) | ||
| 847 | memdebug_memlimit = strtoul(limit, NULL, 10); | ||
| 848 | l_main(argc, argv); | ||
| 849 | return 0; | ||
| 850 | } | ||
| 851 | |||
| 852 | #endif | ||
| @@ -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 methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #define ltm_c |
| 11 | #define LUA_CORE | ||
| 11 | 12 | ||
| 12 | #include "lua.h" | 13 | #include "lua.h" |
| 13 | 14 | ||
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | This is lua, a sample Lua interpreter. | 1 | This is lua, the stand-alone Lua interpreter. |
| 2 | It can be used as a batch interpreter and also interactively. | 2 | It can be used as a batch interpreter and also interactively. |
| 3 | There are man pages for it in both nroff and html in ../../doc. | 3 | There 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 information | 10 | -v show version information |
| 11 | -- stop handling options | 11 | -- stop handling options |
| 12 | 12 | ||
| 13 | This interpreter is suitable for using Lua as a standalone language; it loads | 13 | This interpreter is suitable for using Lua as a stand-alone language; it loads |
| 14 | all standard libraries. For a minimal interpreter, see ../../etc/min.c. | 14 | all standard libraries. For a minimal interpreter, see ../../etc/min.c. |
| 15 | 15 | ||
| 16 | If your application simply exports new functions to Lua (which is common), | 16 | If your application simply exports new functions to Lua (which is common), |
| @@ -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 interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,73 +26,25 @@ · 20 unmodified lines | |||
| 26 | #endif | 26 | #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 | ||
| 64 | static lua_State *L = NULL; | 31 | static lua_State *globalL = NULL; |
| 65 | 32 | ||
| 66 | static const char *progname = PROGNAME; | 33 | static const char *progname = PROGNAME; |
| 67 | 34 | ||
| 68 | 35 | ||
| 69 | 36 | ||
| 70 | static const luaL_reg lualibs[] = { | 37 | static 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 | |||
| 85 | static 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 | ||
| 92 | static void laction (int i) { | 44 | static 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 | ||
| 119 | static int report (int status) { | 71 | static 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 | ||
| 130 | static int lcall (int narg, int clear) { | 82 | static 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 | ||
| 149 | static void getargs (char *argv[], int n) { | 101 | static 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 | ||
| 160 | static int docall (int status) { | 117 | static 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 | |||
| 166 | static int file_input (const char *name) { | ||
| 167 | return docall(luaL_loadfile(L, name)); | ||
| 168 | } | 120 | } |
| 169 | 121 | ||
| 170 | 122 | ||
| 171 | static int dostring (const char *s, const char *name) { | 123 | static 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 | ||
| 176 | static int load_file (const char *name) { | 129 | static 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 the | 143 | ** 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 | #endif | 152 | #endif |
| 210 | 153 | ||
| 211 | 154 | ||
| 212 | static int readline (lua_State *l, const char *prompt) { | 155 | static 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 | #endif | 169 | #endif |
| 227 | 170 | ||
| 228 | 171 | ||
| 229 | static const char *get_prompt (int firstline) { | 172 | static 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 | ||
| 240 | static int incomplete (int status) { | 183 | static 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 | ||
| 251 | static int load_string (void) { | 194 | static 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 | ||
| 273 | static void manual_input (void) { | 216 | static 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 | ||
| 294 | static int handle_argv (char *argv[], int *interactive) { | 238 | static 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 | |||
| 248 | static 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 | else | 253 | 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 | ||
| 375 | static void openstdlibs (lua_State *l) { | 339 | static 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 | |||
| 384 | static 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 | else | 344 | 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 | ||
| 401 | static int pmain (lua_State *l) { | 356 | static 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 | |||
| 418 | int main (int argc, char *argv[]) { | 373 | int 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 | ||
| @@ -5,7 +5,7 @@ LUA= ../.. · 4 unmodified lines | |||
| 5 | include $(LUA)/config | 5 | include $(LUA)/config |
| 6 | 6 | ||
| 7 | INCS= -I$(INC) -I.. $(EXTRA_INCS) | 7 | INCS= -I$(INC) -I.. $(EXTRA_INCS) |
| 8 | OBJS= luac.o print.o lopcodes.o | 8 | OBJS= luac.o print.o |
| 9 | SRCS= luac.c print.c | 9 | SRCS= luac.c print.c |
| 10 | 10 | ||
| 11 | T= $(BIN)/luac | 11 | T= $(BIN)/luac |
| @@ -15,10 +15,6 @@ all: $T · 3 unmodified lines | |||
| 15 | $T: $(OBJS) $(LIB)/liblua.a ../lib/lauxlib.o | 15 | $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 | ||
| 19 | lopcodes.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 | ||
| @@ -1 +0,0 @@ | |||
| 1 | ../RCS | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | This is luac, the Lua compiler. | 1 | This is luac, the Lua compiler. |
| 2 | There are man pages for it in both nroff and html in ../../doc. | 2 | There are man pages for it in both nroff and html in ../../doc. |
| 3 | 3 | ||
| 4 | luac translates Lua programs into binary files that can be loaded latter. | 4 | luac translates Lua programs into binary files that can be loaded later. |
| 5 | The main advantages of pre-compiling chunks are: faster loading, protecting | 5 | The main advantages of pre-compiling chunks are: faster loading, protecting |
| 6 | source code from user changes, and off-line syntax error detection. | 6 | source code from user changes, and off-line syntax error detection. |
| 7 | luac can also be used to learn about the Lua virtual machine. | 7 | luac can also be used to learn about the Lua virtual machine. |
| @@ -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.h | 4 | ** 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 | ||
| 44 | static void cannot(const char* what) | 47 | static 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 | ||
| 115 | static 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 | ||
| 121 | static Proto* combine(lua_State* L, int n) | 120 | static 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 | else | 124 | 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 | |||
| 147 | static int writer(lua_State* L, const void* p, size_t size, void* u) | 148 | static 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 | ||
| 153 | static int panic(lua_State *L) | 154 | void unprint(lua_State* L, const char* name); |
| 154 | { | ||
| 155 | UNUSED(L); | ||
| 156 | fatal("not enough memory!"); | ||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | 155 | ||
| 160 | int main(int argc, char* argv[]) | 156 | struct Smain { |
| 157 | int argc; | ||
| 158 | char **argv; | ||
| 159 | }; | ||
| 160 | |||
| 161 | static 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 | |||
| 189 | int 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 | } |
| @@ -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 bytecodes | 3 | ** print bytecodes |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 1 | 10 | #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 | ||
| 169 | static void PrintHeader(const Proto* f) | 160 | static 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 | ||
| 182 | static void PrintConstants(const Proto* f) | 172 | static 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 | ||
| 217 | void luaU_print(const Proto* f) | 206 | void 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_PRINT | 211 | if (full) |
| 223 | PrintConstants(f); | 212 | { |
| 224 | PrintLocals(f); | 213 | PrintConstants(f); |
| 225 | PrintUpvalues(f); | 214 | PrintLocals(f); |
| 226 | #endif | 215 | 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 | } |
| @@ -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 chunks | 3 | ** load pre-compiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #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 chunk | 263 | ** load precompiled chunk |
| 263 | */ | 264 | */ |
| 264 | Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* s) | 265 | Proto* 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 | else | 272 | 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; |
| @@ -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 chunks | 3 | ** load pre-compiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | |||
| 17 | int luaU_endianness (void); | 17 | int luaU_endianness (void); |
| 18 | 18 | ||
| 19 | /* dump one chunk; from ldump.c */ | 19 | /* dump one chunk; from ldump.c */ |
| 20 | int luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data, int strip); | 20 | int 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 */ |
| 23 | void luaU_print (const Proto* Main); | 23 | void 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 */ |
| @@ -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 machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 11 | #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 100 | 31 | #define MAXTAGLOOP 100 |
| 40 | 32 | ||
| @@ -66,8 +58,8 @@ int luaV_tostring (lua_State *L, StkId obj) { · 25 unmodified lines | |||
| 66 | static void traceexec (lua_State *L, const Instruction *pc) { | 58 | static 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 | ||
| 117 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | 109 | StkId 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 | ||
| 144 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | 142 | StkId 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 | ||
| 376 | StkId luaV_execute (lua_State *L, int nexeccalls) { | 381 | StkId 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 | else | 484 | 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 | else | 494 | 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 | else | 504 | 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 | else | 514 | 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 | } |
| @@ -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 machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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 | |||
| 26 | int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); | 26 | int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); |
| 27 | const TValue *luaV_tonumber (const TValue *obj, TValue *n); | 27 | const TValue *luaV_tonumber (const TValue *obj, TValue *n); |
| 28 | int luaV_tostring (lua_State *L, StkId obj); | 28 | int luaV_tostring (lua_State *L, StkId obj); |
| 29 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); | 29 | StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val, |
| 30 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val); | 30 | const Instruction *pc); |
| 31 | StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val, | ||
| 32 | const Instruction *pc); | ||
| 31 | StkId luaV_execute (lua_State *L, int nexeccalls); | 33 | StkId luaV_execute (lua_State *L, int nexeccalls); |
| 32 | void luaV_concat (lua_State *L, int total, int last); | 34 | void luaV_concat (lua_State *L, int total, int last); |
| 33 | 35 | ||
| @@ -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 interface | 3 | ** a generic input stream interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** 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_c | 10 | #define lzio_c |
| 11 | #define LUA_CORE | ||
| 11 | 12 | ||
| 12 | #include "lua.h" | 13 | #include "lua.h" |
| 13 | 14 | ||