Unified · Split
| @@ -1,4 +1,4 @@ | ||
| 1 | −This is Lua 5.0. | |
| 1 | +This is Lua 5.1 (work). | |
| 2 | 2 | |
| 3 | 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 | 3 | * Installation |
| 4 | 4 | ------------ |
| @@ -7,8 +7,9 @@ This is Lua 5.0. · 2 unmodified lines | ||
| 7 | 7 | 1. Read "config" and edit it to suit your platform and needs. |
| 8 | 8 | We strongly recommend that you enable support for dynamic loading, |
| 9 | 9 | if your platform allows it. |
| 10 | − 2. Do "make". | |
| 11 | − 3. If you want to install Lua in an "official" place in your system, | |
| 10 | + 2. Do the same for include/luaconf.h. | |
| 11 | + 3. Do "make". | |
| 12 | + 4. If you want to install Lua in an "official" place in your system, | |
| 12 | 13 | then do "make install". The official place and the way to install |
| 13 | 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 | 54 | /usr/local/lib may not be a place that is checked for shared libraries. |
| 54 | 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 | 58 | you may need to fix a few details in the top-level Makefile. |
| 58 | 59 | |
| 59 | 60 | * Installation on Windows and other systems |
| 60 | 61 | ----------------------------------------- |
| 61 | − The instructions for building Lua on other systems machine depend on the | |
| 62 | − particular compiler you are using. The simplest way is to create a folder | |
| 63 | − with all .c and .h files, and then create projects for the core library, | |
| 64 | − the standard library, the interpreter, and the compiler, as follows: | |
| 62 | + The instructions for building Lua on other systems depend on the particular | |
| 63 | + compiler you are using. The simplest way is to create a folder with all .c | |
| 64 | + and .h files, and then create projects for the core library, the standard | |
| 65 | + library, the interpreter, and the compiler, as follows: | |
| 65 | 66 | |
| 66 | 67 | core lib: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c |
| 67 | 68 | lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c |
| 68 | 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 | − lstrlib.c loadlib.c | |
| 71 | + standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c | |
| 72 | + ltablib.c lstrlib.c loadlib.c | |
| 72 | 73 | |
| 73 | 74 | interpreter: core lib, standard lib, lua.c |
| 74 | 75 | |
| 75 | 76 | compiler: core lib, lauxlib.c luac.c print.c |
| 76 | − and also lopcodes.c (with LUA_OPNAMES defined) from core. | |
| 77 | 77 | |
| 78 | 78 | Of course, to use Lua as a library, you'll have to know how to create |
| 79 | 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 | 2 | See HISTORY for a summary of changes since the last released version. |
| 3 | 3 | |
| 4 | 4 | * What is Lua? |
| @@ -1,9 +1,12 @@ | ||
| 1 | −# If you don't want to use make, run this script. | |
| 2 | −# But make sure you read config to see what can be customized. | |
| 1 | +#!/bin/sh | |
| 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 | 7 | # Easiest way to build bin/lua: |
| 6 | 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 | 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 | 29 | echo -n 'luac... ' |
| 27 | 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 | 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 | 2 | # see INSTALL for installation instructions |
| 3 | 3 | |
| 4 | 4 | # These are default values. Skip this section and see the explanations below. |
| 5 | 5 | |
| 6 | 6 | LOADLIB= |
| 7 | 7 | DLLIB= |
| 8 | −NUMBER= | |
| 9 | −POPEN= | |
| 10 | −TMPNAM= | |
| 11 | −DEGREES= | |
| 12 | 8 | USERCONF= |
| 13 | 9 | |
| 14 | 10 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= |
| @@ -42,50 +38,11 @@ USERCONF= · 27 unmodified lines | ||
| 42 | 38 | |
| 43 | 39 | # --------------------------------------------------------------- Lua libraries |
| 44 | 40 | |
| 45 | −# The Lua IO library (src/lib/liolib.c) has support for pipes using popen and | |
| 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 | |
| 41 | +# See include/luaconf.h. | |
| 71 | 42 | |
| 72 | 43 | # ------------------------------------------------------------------ Lua core |
| 73 | 44 | |
| 74 | −# Lua uses double for numbers. To change this, uncomment and edit the following | |
| 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 | |
| 45 | +# See include/luaconf.h. | |
| 89 | 46 | |
| 90 | 47 | # ------------------------------------------------------------- Lua interpreter |
| 91 | 48 | |
| @@ -165,14 +122,14 @@ INSTALL_DATA= cp · 73 unmodified lines | ||
| 165 | 122 | |
| 166 | 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 | 127 | BIN= $(LUA)/bin |
| 171 | 128 | INC= $(LUA)/include |
| 172 | 129 | LIB= $(LUA)/lib |
| 173 | 130 | |
| 174 | 131 | INCS= -I$(INC) $(EXTRA_INCS) |
| 175 | −DEFS= $(NUMBER) $(EXTRA_DEFS) | |
| 132 | +DEFS= $(EXTRA_DEFS) | |
| 176 | 133 | |
| 177 | 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 | 5 | include $(LUA)/config |
| 6 | 6 | |
| 7 | −LIBLUA=$(LIB)/liblua.a | |
| 8 | −ALL= bin2c min noparser luab | |
| 7 | +ALL= min noparser luab 1 | |
| 9 | 8 | |
| 10 | 9 | all: |
| 11 | 10 | @echo 'choose a target:' $(ALL) |
| 12 | 11 | |
| 13 | −bin2c: bin2c.c | |
| 14 | − $(CC) $(CFLAGS) -o $@ $@.c | |
| 15 | − | |
| 16 | 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 | 15 | noparser: noparser.c |
| 20 | 16 | $(CC) $(CFLAGS) -I$(LUA)/src -o $@.o -c $@.c |
| 21 | 17 | |
| 22 | −luab: noparser $(LIBLUA) | |
| 23 | − $(CC) -o $@ noparser.o $(LUA)/src/lua/lua.o -L$(LIB) -llua -llualib $(EXTRA_LIBS) | |
| 18 | +luab: noparser | |
| 19 | + $(CC) -o $@ noparser.o $(LUA)/src/lua/lua.o -L$(LIB) -llua -llualib $(EXTRA_LIBS) $(DLLIB) | |
| 24 | 20 | $(BIN)/luac $(LUA)/test/hello.lua |
| 25 | 21 | $@ luac.out |
| 26 | 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 | 28 | flat: |
| 29 | 29 | cd ..; mkdir flat; mv include/*.h src/*.[ch] src/*/*.[ch] flat |
| 30 | 30 | |
| 31 | −$(LIBLUA): | |
| 32 | − cd ../src; $(MAKE) | |
| 33 | − | |
| 34 | 31 | clean: |
| 35 | 32 | rm -f $(ALL) a.out core *.o luac.out |
| @@ -1 +0,0 @@ | ||
| 1 | −../RCS | |
| @@ -1,6 +1,10 @@ | ||
| 1 | 1 | This directory contains some useful files and code. |
| 2 | 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 | 8 | lua.ico |
| 5 | 9 | A Lua icon for Windows (and web sites, as favicon.ico). |
| 6 | 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 | 2 | * min.c -- a minimal Lua interpreter |
| 3 | −* only dynamic loading is enabled -- all libraries must be dynamically loaded | |
| 4 | −* no interaction, only batch execution | |
| 3 | +* loads stdin only with minimal error handling. | |
| 4 | +* no interaction, and no standard library, only a "print" function. | |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <stdio.h> |
| 8 | 8 | #include "lua.h" |
| 9 | −#include "lualib.h" | |
| 10 | 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); | |
| 15 | − lua_register(L,"error",lua_error); | |
| 16 | − luaopen_loadlib(L); | |
| 17 | − while (*++argv) | |
| 13 | + int n=lua_gettop(L); | |
| 14 | + int i; | |
| 15 | + for (i=1; i<=n; i++) | |
| 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 | 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 | 42 | lua_State *L=lua_open(); |
| 29 | − if (L==NULL) | |
| 30 | − { | |
| 31 | − report("not enough memory for state"); | |
| 32 | − return 1; | |
| 33 | − } | |
| 34 | − if (lua_cpcall(L,run,argv)) report(lua_tostring(L,-1)); | |
| 35 | − lua_close(L); | |
| 43 | + lua_register(L,"print",print); | |
| 44 | + if (lua_load(L,getF,stdin,"=stdin") || lua_pcall(L,0,0,0)) | |
| 45 | + fprintf(stderr,"%s\n",lua_tostring(L,-1)); | |
| 36 | 46 | return 0; |
| 37 | 47 | } |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | * load the parsing modules. To try it, do "make luab". |
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | +#define LUA_CORE | |
| 13 | + | |
| 12 | 14 | #include "llex.h" |
| 13 | 15 | #include "lparser.h" |
| 14 | 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 | 31 | * If you also want to avoid the dump module, ldump.o, enable the code below. |
| 30 | 32 | */ |
| 33 | +#define NODUMP | |
| 31 | 34 | #ifdef NODUMP |
| 32 | 35 | #include "lundump.h" |
| 33 | 36 | |
| @@ -4,7 +4,7 @@ LUA= .. · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 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 | 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 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -15,10 +15,8 @@ · 9 unmodified lines | ||
| 15 | 15 | #include "lua.h" |
| 16 | 16 | |
| 17 | 17 | |
| 18 | −#ifndef LUALIB_API | |
| 19 | −#define LUALIB_API LUA_API | |
| 20 | −#endif | |
| 21 | − | |
| 18 | +/* extra error code for `luaL_load' */ | |
| 19 | +#define LUA_ERRFILE (LUA_ERRERR+1) | |
| 22 | 20 | |
| 23 | 21 | |
| 24 | 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 | 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 | 60 | LUALIB_API int luaL_ref (lua_State *L, int t); |
| 60 | 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 | 86 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, n)) |
| 86 | 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 | 99 | typedef struct luaL_Buffer { |
| 102 | 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 | −/* | |
| 127 | −** Compatibility macros and functions | |
| 128 | −*/ | |
| 125 | +/* pre-defined references */ | |
| 126 | +#define LUA_NOREF (-2) | |
| 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); | |
| 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 | +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) | |
| 134 | 135 | |
| 135 | 136 | |
| 136 | 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 | 3 | ** Lua - An Extensible Extension Language |
| 4 | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
| 5 | 5 | ** http://www.lua.org mailto:info@lua.org |
| @@ -14,7 +14,10 @@ · 8 unmodified lines | ||
| 14 | 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 | 21 | #define LUA_COPYRIGHT "Copyright (C) 1994-2004 Tecgraf, PUC-Rio" |
| 19 | 22 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" |
| 20 | 23 | |
| @@ -34,12 +37,11 @@ · 13 unmodified lines | ||
| 34 | 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 | 41 | #define LUA_ERRRUN 1 |
| 39 | −#define LUA_ERRFILE 2 | |
| 40 | −#define LUA_ERRSYNTAX 3 | |
| 41 | −#define LUA_ERRMEM 4 | |
| 42 | −#define LUA_ERRERR 5 | |
| 42 | +#define LUA_ERRSYNTAX 2 | |
| 43 | +#define LUA_ERRMEM 3 | |
| 44 | +#define LUA_ERRERR 4 | |
| 43 | 45 | |
| 44 | 46 | |
| 45 | 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 | 95 | /* type of numbers in Lua */ |
| 94 | −#ifndef LUA_NUMBER | |
| 95 | −typedef double lua_Number; | |
| 96 | −#else | |
| 97 | 96 | typedef LUA_NUMBER lua_Number; |
| 98 | −#endif | |
| 99 | 97 | |
| 100 | 98 | |
| 101 | 99 | /* type for integer functions */ |
| 102 | −#ifndef LUA_INTEGER | |
| 103 | −typedef long lua_Integer; | |
| 104 | −#else | |
| 105 | 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 | 105 | ** state manipulation |
| @@ -155,7 +144,7 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int idx); · 38 unmodified lines | ||
| 155 | 144 | LUA_API lua_Integer lua_tointeger (lua_State *L, int idx); |
| 156 | 145 | LUA_API int lua_toboolean (lua_State *L, int idx); |
| 157 | 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 | 148 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx); |
| 160 | 149 | LUA_API void *lua_touserdata (lua_State *L, int idx); |
| 161 | 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 | 217 | #define LUA_GCRESTART 1 |
| 229 | 218 | #define LUA_GCCOLLECT 2 |
| 230 | 219 | #define LUA_GCCOUNT 3 |
| 220 | +#define LUA_GCSTEP 4 | |
| 231 | 221 | |
| 232 | 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 | 247 | #define lua_pop(L,n) lua_settop(L, -(n)-1) |
| 263 | 248 | |
| 264 | 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 | 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 | 257 | #define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) |
| 271 | 258 | #define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) |
| 272 | 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 | 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 | 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 | 3 | ** Lua standard libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -11,9 +11,8 @@ · 5 unmodified lines | ||
| 11 | 11 | #include "lua.h" |
| 12 | 12 | |
| 13 | 13 | |
| 14 | −#ifndef LUALIB_API | |
| 15 | −#define LUALIB_API LUA_API | |
| 16 | −#endif | |
| 14 | +/* Key to file-handle type */ | |
| 15 | +#define LUA_FILEHANDLE "FILE*" | |
| 17 | 16 | |
| 18 | 17 | |
| 19 | 18 | #define LUA_COLIBNAME "coroutine" |
| @@ -23,9 +22,11 @@ LUALIB_API int luaopen_base (lua_State *L); · 3 unmodified lines | ||
| 23 | 22 | LUALIB_API int luaopen_table (lua_State *L); |
| 24 | 23 | |
| 25 | 24 | #define LUA_IOLIBNAME "io" |
| 26 | −#define LUA_OSLIBNAME "os" | |
| 27 | 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 | 30 | #define LUA_STRLIBNAME "string" |
| 30 | 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 | 40 | LUALIB_API int luaopen_loadlib (lua_State *L); |
| 40 | 41 | |
| 41 | 42 | |
| 42 | −/* to help testing the libraries */ | |
| 43 | −#ifndef lua_assert | |
| 44 | −#define lua_assert(c) /* empty */ | |
| 45 | −#endif | |
| 46 | − | |
| 43 | +/* open all previous libraries */ | |
| 44 | +LUALIB_API int luaopen_stdlibs (lua_State *L); | |
| 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 | 47 | #endif |
| @@ -1 +0,0 @@ | ||
| 1 | −../RCS | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | This is the Lua core. |
| 2 | 2 | |
| 3 | 3 | The standard Lua library are in lib/. |
| 4 | −A sample interpreter is in lua/. | |
| 5 | −A standalone compiler is in luac/. | |
| 4 | +The standalone interpreter is in lua/. | |
| 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 | 3 | ** Lua API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -10,6 +10,7 @@ · 4 unmodified lines | ||
| 10 | 10 | #include <string.h> |
| 11 | 11 | |
| 12 | 12 | #define lapi_c |
| 13 | +#define LUA_CORE | |
| 13 | 14 | |
| 14 | 15 | #include "lua.h" |
| 15 | 16 | |
| @@ -28,11 +29,6 @@ · 12 unmodified lines | ||
| 28 | 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 | 33 | const char lua_ident[] = |
| 38 | 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 | 40 | #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) |
| 49 | 41 | |
| 50 | 42 | #define api_checkvalidindex(L, i) api_check(L, (i) != &luaO_nilobject) |
| @@ -56,7 +48,7 @@ const char lua_ident[] = · 5 unmodified lines | ||
| 56 | 48 | static TValue *luaA_index (lua_State *L, int idx) { |
| 57 | 49 | if (idx > 0) { |
| 58 | 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 | 52 | if (o >= L->top) return cast(TValue *, &luaO_nilobject); |
| 61 | 53 | else return o; |
| 62 | 54 | } |
| @@ -87,7 +79,7 @@ void luaA_pushobject (lua_State *L, const TValue *o) { · 24 unmodified lines | ||
| 87 | 79 | LUA_API int lua_checkstack (lua_State *L, int size) { |
| 88 | 80 | int res; |
| 89 | 81 | lua_lock(L); |
| 90 | − if ((L->top - L->base + size) > LUA_MAXCSTACK) | |
| 82 | + if ((L->top - L->base + size) > MAXCSTACK) | |
| 91 | 83 | res = 0; /* stack overflow */ |
| 92 | 84 | else { |
| 93 | 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 | 327 | StkId o = luaA_index(L, idx); |
| 336 | 328 | if (ttisstring(o)) |
| 337 | 329 | return tsvalue(o)->len; |
| 330 | + else if (ttisuserdata(o)) | |
| 331 | + return uvalue(o)->len; | |
| 338 | 332 | else { |
| 339 | 333 | size_t l; |
| 340 | 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 | 490 | lua_lock(L); |
| 497 | 491 | t = luaA_index(L, idx); |
| 498 | 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 | 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 | 502 | t = luaA_index(L, idx); |
| 509 | 503 | api_checkvalidindex(L, t); |
| 510 | 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 | 506 | api_incr_top(L); |
| 513 | 507 | lua_unlock(L); |
| 514 | 508 | } |
| @@ -592,7 +586,7 @@ LUA_API void lua_settable (lua_State *L, int idx) { · 77 unmodified lines | ||
| 592 | 586 | api_checknelems(L, 2); |
| 593 | 587 | t = luaA_index(L, idx); |
| 594 | 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 | 590 | L->top -= 2; /* pop index and value */ |
| 597 | 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 | 600 | t = luaA_index(L, idx); |
| 607 | 601 | api_checkvalidindex(L, t); |
| 608 | 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 | 604 | L->top--; /* pop value */ |
| 611 | 605 | lua_unlock(L); |
| 612 | 606 | } |
| @@ -619,7 +613,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) { · 6 unmodified lines | ||
| 619 | 613 | t = luaA_index(L, idx); |
| 620 | 614 | api_check(L, ttistable(t)); |
| 621 | 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 | 617 | L->top -= 2; |
| 624 | 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 | 626 | o = luaA_index(L, idx); |
| 633 | 627 | api_check(L, ttistable(o)); |
| 634 | 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 | 630 | L->top--; |
| 637 | 631 | lua_unlock(L); |
| 638 | 632 | } |
| @@ -683,12 +677,13 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { · 44 unmodified lines | ||
| 683 | 677 | api_checknelems(L, 1); |
| 684 | 678 | o = luaA_index(L, idx); |
| 685 | 679 | api_checkvalidindex(L, o); |
| 686 | − L->top--; | |
| 687 | − api_check(L, ttistable(L->top)); | |
| 680 | + api_check(L, ttistable(L->top - 1)); | |
| 688 | 681 | if (isLfunction(o)) { |
| 689 | 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 | 687 | lua_unlock(L); |
| 693 | 688 | return res; |
| 694 | 689 | } |
| @@ -698,12 +693,23 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { · 3 unmodified lines | ||
| 698 | 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 | 705 | LUA_API void lua_call (lua_State *L, int nargs, int nresults) { |
| 702 | 706 | StkId func; |
| 703 | 707 | lua_lock(L); |
| 704 | 708 | api_checknelems(L, nargs+1); |
| 709 | + checkresults(L, nargs, nresults); | |
| 705 | 710 | func = L->top - (nargs+1); |
| 706 | 711 | luaD_call(L, func, nresults); |
| 712 | + adjustresults(L, nresults); | |
| 707 | 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 | 736 | int status; |
| 731 | 737 | ptrdiff_t func; |
| 732 | 738 | lua_lock(L); |
| 739 | + api_checknelems(L, nargs+1); | |
| 740 | + checkresults(L, nargs, nresults); | |
| 733 | 741 | if (errfunc == 0) |
| 734 | 742 | func = 0; |
| 735 | 743 | else { |
| @@ -740,6 +748,7 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { · 4 unmodified lines | ||
| 740 | 748 | c.func = L->top - (nargs+1); /* function to be called */ |
| 741 | 749 | c.nresults = nresults; |
| 742 | 750 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); |
| 751 | + adjustresults(L, nresults); | |
| 743 | 752 | lua_unlock(L); |
| 744 | 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 | 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 | 828 | switch (what) { |
| 817 | 829 | case LUA_GCSTOP: { |
| 818 | 830 | g->GCthreshold = MAXLMEM; |
| 819 | − return 0; | |
| 831 | + break; | |
| 820 | 832 | } |
| 821 | 833 | case LUA_GCRESTART: { |
| 822 | − g->GCthreshold = g->nblocks; | |
| 823 | − return 0; | |
| 834 | + g->GCthreshold = g->totalbytes; | |
| 835 | + break; | |
| 824 | 836 | } |
| 825 | 837 | case LUA_GCCOLLECT: { |
| 826 | − lua_lock(L); | |
| 827 | 838 | luaC_fullgc(L); |
| 828 | − lua_unlock(L); | |
| 829 | − return 0; | |
| 839 | + break; | |
| 830 | 840 | } |
| 831 | 841 | case LUA_GCCOUNT: { |
| 832 | 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 | 938 | if (!ttisfunction(fi)) return NULL; |
| 917 | 939 | f = clvalue(fi); |
| 918 | 940 | if (f->c.isC) { |
| 919 | − if (n > f->c.nupvalues) return NULL; | |
| 941 | + if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | |
| 920 | 942 | *val = &f->c.upvalue[n-1]; |
| 921 | 943 | return ""; |
| 922 | 944 | } |
| 923 | 945 | else { |
| 924 | 946 | Proto *p = f->l.p; |
| 925 | − if (n > p->sizeupvalues) return NULL; | |
| 947 | + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | |
| 926 | 948 | *val = f->l.upvals[n-1]->v; |
| 927 | 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 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stdlib.h> |
| 9 | 9 | |
| 10 | 10 | #define lcode_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 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 | 197 | static void freereg (FuncState *fs, int reg) { |
| 197 | − if (reg >= fs->nactvar && reg < MAXSTACK) { | |
| 198 | + if (!ISK(reg) && reg >= fs->nactvar) { | |
| 198 | 199 | fs->freereg--; |
| 199 | 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 | 223 | MAXARG_Bx, "constant table overflow"); |
| 223 | 224 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); |
| 224 | 225 | setobj(L, &f->k[fs->nk], v); |
| 225 | − luaC_barrier(L, f, v); | |
| 226 | + luaC_barriert(L, f, v); | |
| 226 | 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 | 256 | if (e->k == VCALL) { /* expression is an open function call? */ |
| 256 | 257 | SETARG_C(getcode(fs, e), nresults+1); |
| 257 | − if (nresults == 1) { /* `regular' expression? */ | |
| 258 | − e->k = VNONRELOC; | |
| 259 | − e->info = GETARG_A(getcode(fs, e)); | |
| 260 | − } | |
| 258 | + } | |
| 259 | + else if (e->k == VVARARG) { | |
| 260 | + SETARG_B(getcode(fs, e), nresults+1); | |
| 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 | 299 | e->k = VRELOCABLE; |
| 286 | 300 | break; |
| 287 | 301 | } |
| 302 | + case VVARARG: | |
| 288 | 303 | case VCALL: { |
| 289 | − luaK_setcallreturns(fs, e, 1); | |
| 304 | + luaK_setoneret(fs, e); | |
| 290 | 305 | break; |
| 291 | 306 | } |
| 292 | 307 | default: break; /* there is one value available (somewhere) */ |
| @@ -403,16 +418,16 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { · 110 unmodified lines | ||
| 403 | 418 | luaK_exp2val(fs, e); |
| 404 | 419 | switch (e->k) { |
| 405 | 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 | 422 | e->info = nil_constant(fs); |
| 408 | 423 | e->k = VK; |
| 409 | − return e->info + MAXSTACK; | |
| 424 | + return RKASK(e->info); | |
| 410 | 425 | } |
| 411 | 426 | else break; |
| 412 | 427 | } |
| 413 | 428 | case VK: { |
| 414 | − if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ | |
| 415 | − return e->info + MAXSTACK; | |
| 429 | + if (e->info <= MAXINDEXRK) /* constant fit in argC? */ | |
| 430 | + return RKASK(e->info); | |
| 416 | 431 | else break; |
| 417 | 432 | } |
| 418 | 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 | 3 | ** Code generator for Lua |
| 4 | 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 | 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 | 46 | int luaK_code (FuncState *fs, Instruction i, int line); |
| 45 | 47 | int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
| 46 | 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 | 62 | void luaK_goiftrue (FuncState *fs, expdesc *e); |
| 61 | 63 | void luaK_goiffalse (FuncState *fs, expdesc *e); |
| 62 | 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 | 67 | int luaK_jump (FuncState *fs); |
| 65 | 68 | void luaK_patchlist (FuncState *fs, int list, int target); |
| 66 | 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 | 3 | ** Debug Interface |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -11,6 +11,7 @@ · 5 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | |
| 13 | 13 | #define ldebug_c |
| 14 | +#define LUA_CORE | |
| 14 | 15 | |
| 15 | 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 | 36 | static int currentpc (CallInfo *ci) { |
| 36 | 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 | 86 | for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { |
| 86 | 87 | level--; |
| 87 | 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 | 91 | if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */ |
| 91 | 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 | 222 | else if (ar->i_ci != 0) { /* no tail call? */ |
| 222 | 223 | CallInfo *ci = L->base_ci + ar->i_ci; |
| 223 | − lua_assert(ttisfunction(ci->base - 1)); | |
| 224 | − status = auxgetinfo(L, what, ar, ci->base - 1, ci); | |
| 224 | + lua_assert(ttisfunction(ci->func)); | |
| 225 | + status = auxgetinfo(L, what, ar, ci->func, ci); | |
| 225 | 226 | } |
| 226 | 227 | else |
| 227 | 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 | − Instruction i = pt->code[pc+1]; | |
| 258 | +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) | |
| 259 | + | |
| 260 | +int luaG_checkopenop (Instruction i) { | |
| 259 | 261 | switch (GET_OPCODE(i)) { |
| 260 | 262 | case OP_CALL: |
| 261 | 263 | case OP_TAILCALL: |
| @@ -274,8 +276,8 @@ static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { · 12 unmodified lines | ||
| 274 | 276 | case OpArgN: check(r == 0); break; |
| 275 | 277 | case OpArgU: break; |
| 276 | 278 | case OpArgR: checkreg(pt, r); break; |
| 277 | − case OpArgK: | |
| 278 | − check(r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); | |
| 279 | + case OpArgK: | |
| 280 | + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); | |
| 279 | 281 | break; |
| 280 | 282 | } |
| 281 | 283 | return 1; |
| @@ -355,7 +357,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { · 73 unmodified lines | ||
| 355 | 357 | } |
| 356 | 358 | case OP_TFORLOOP: { |
| 357 | 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 | 361 | break; |
| 360 | 362 | } |
| 361 | 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 | 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 | 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 | 434 | static const char *kname (Proto *p, int c) { |
| 426 | − c = c - MAXSTACK; | |
| 427 | − if (c >= 0 && ttisstring(&p->k[c])) | |
| 428 | − return svalue(&p->k[c]); | |
| 435 | + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | |
| 436 | + return svalue(&p->k[INDEXK(c)]); | |
| 429 | 437 | else |
| 430 | 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 | 488 | static const char *getfuncname (CallInfo *ci, const char **name) { |
| 481 | 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 | 491 | return NULL; /* calling function is not Lua (or is unknown) */ |
| 484 | 492 | ci--; /* calling function */ |
| 485 | 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 | 496 | return getobjname(ci, GETARG_A(i), name); |
| 488 | 497 | else |
| 489 | 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 | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | 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 | 25 | void luaG_runerror (lua_State *L, const char *fmt, ...); |
| 26 | 26 | void luaG_errormsg (lua_State *L); |
| 27 | 27 | int luaG_checkcode (const Proto *pt); |
| 28 | − | |
| 28 | +int luaG_checkopenop (Instruction i); | |
| 29 | 29 | |
| 30 | 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 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | −#include <setjmp.h> | |
| 9 | 8 | #include <stdlib.h> |
| 10 | 9 | #include <string.h> |
| 11 | 10 | |
| 12 | 11 | #define ldo_c |
| 12 | +#define LUA_CORE | |
| 13 | 13 | |
| 14 | 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 | 42 | /* chain list of long jump buffers */ |
| 57 | 43 | struct lua_longjmp { |
| 58 | 44 | struct lua_longjmp *previous; |
| 59 | − jmp_buf b; | |
| 45 | + l_jmpbuf b; | |
| 60 | 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 | 113 | for (ci = L->base_ci; ci <= L->ci; ci++) { |
| 128 | 114 | ci->top = (ci->top - oldstack) + L->stack; |
| 129 | 115 | ci->base = (ci->base - oldstack) + L->stack; |
| 116 | + ci->func = (ci->func - oldstack) + L->stack; | |
| 130 | 117 | } |
| 131 | 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 | 187 | int i; |
| 200 | − Table *htab; | |
| 201 | − int actual = L->top - base; /* actual number of arguments */ | |
| 188 | + Table *htab = NULL; | |
| 189 | + StkId base, fixed; | |
| 202 | 190 | if (actual < nfixargs) { |
| 203 | − luaD_checkstack(L, nfixargs - actual); | |
| 204 | 191 | for (; actual < nfixargs; ++actual) |
| 205 | 192 | setnilvalue(L->top++); |
| 206 | 193 | } |
| 207 | − actual -= nfixargs; /* number of extra arguments */ | |
| 208 | − htab = luaH_new(L, actual, 1); /* create `arg' table */ | |
| 209 | − for (i=0; i<actual; i++) /* put extra arguments into `arg' table */ | |
| 210 | − setobj2n(L, luaH_setnum(L, htab, i+1), L->top - actual + i); | |
| 211 | − /* store counter in field `n' */ | |
| 212 | − setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), | |
| 213 | − cast(lua_Number, actual)); | |
| 214 | − L->top -= actual; /* remove extra elements from the stack */ | |
| 215 | − sethvalue(L, L->top, htab); | |
| 216 | − lua_assert(iswhite(obj2gco(htab))); | |
| 217 | − incr_top(L); | |
| 194 | + if (style != NEWSTYLEVARARG) { /* compatibility with old-style vararg */ | |
| 195 | + int nvar = actual - nfixargs; /* number of extra arguments */ | |
| 196 | + htab = luaH_new(L, nvar, 1); /* create `arg' table */ | |
| 197 | + for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ | |
| 198 | + setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - nvar + i); | |
| 199 | + /* store counter in field `n' */ | |
| 200 | + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), | |
| 201 | + cast(lua_Number, nvar)); | |
| 202 | + } | |
| 203 | + /* move fixed parameters to final position */ | |
| 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 | 235 | LClosure *cl; |
| 238 | − ptrdiff_t funcr = savestack(L, func); | |
| 236 | + ptrdiff_t funcr; | |
| 239 | 237 | if (!ttisfunction(func)) /* `func' is not a function? */ |
| 240 | 238 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
| 239 | + funcr = savestack(L, func); | |
| 241 | 240 | if (L->ci + 1 == L->end_ci) luaD_growCI(L); |
| 242 | 241 | else condhardstacktests(luaD_reallocCI(L, L->size_ci)); |
| 243 | 242 | cl = &clvalue(func)->l; |
| 244 | 243 | if (!cl->isC) { /* Lua function? prepare its call */ |
| 245 | 244 | CallInfo *ci; |
| 246 | − StkId st; | |
| 245 | + StkId st, base; | |
| 247 | 246 | Proto *p = cl->p; |
| 248 | − if (p->is_vararg) /* varargs? */ | |
| 249 | − adjust_varargs(L, p->numparams, func+1); | |
| 250 | 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 | 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 | 258 | ci->top = L->base + p->maxstacksize; |
| 254 | − ci->u.l.savedpc = p->code; /* starting point */ | |
| 255 | − ci->u.l.tailcalls = 0; | |
| 259 | + ci->savedpc = p->code; /* starting point */ | |
| 260 | + ci->tailcalls = 0; | |
| 261 | + ci->nresults = nresults; | |
| 256 | 262 | for (st = L->top; st < ci->top; st++) |
| 257 | 263 | setnilvalue(st); |
| 258 | 264 | L->top = ci->top; |
| 259 | − return NULL; | |
| 265 | + return PCRLUA; | |
| 260 | 266 | } |
| 261 | 267 | else { /* if is a C function, call it */ |
| 262 | 268 | CallInfo *ci; |
| 263 | 269 | int n; |
| 264 | 270 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 265 | 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 | 274 | ci->top = L->top + LUA_MINSTACK; |
| 268 | 275 | if (L->hookmask & LUA_MASKCALL) |
| 269 | 276 | luaD_callhook(L, LUA_HOOKCALL, -1); |
| 270 | 277 | lua_unlock(L); |
| 271 | 278 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ |
| 272 | 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 | 293 | ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ |
| 280 | 294 | luaD_callhook(L, LUA_HOOKRET, -1); |
| 281 | 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 | 297 | luaD_callhook(L, LUA_HOOKTAILRET, -1); |
| 284 | 298 | } |
| 285 | 299 | return restorestack(L, fr); |
| @@ -290,7 +304,7 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { · 4 unmodified lines | ||
| 290 | 304 | StkId res; |
| 291 | 305 | if (L->hookmask & LUA_MASKRET) |
| 292 | 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 | 308 | L->ci--; |
| 295 | 309 | L->base = L->ci->base; /* restore base */ |
| 296 | 310 | /* move results to correct place */ |
| @@ -311,17 +325,16 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { · 14 unmodified lines | ||
| 311 | 325 | ** function position. |
| 312 | 326 | */ |
| 313 | 327 | void luaD_call (lua_State *L, StkId func, int nResults) { |
| 314 | − StkId firstResult; | |
| 315 | 328 | if (++L->nCcalls >= LUA_MAXCCALLS) { |
| 316 | 329 | if (L->nCcalls == LUA_MAXCCALLS) |
| 317 | 330 | luaG_runerror(L, "C stack overflow"); |
| 318 | 331 | else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) |
| 319 | 332 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ |
| 320 | 333 | } |
| 321 | − firstResult = luaD_precall(L, func); | |
| 322 | − if (firstResult == NULL) /* is a Lua function? */ | |
| 323 | − firstResult = luaV_execute(L, 1); /* call it */ | |
| 324 | − luaD_poscall(L, nResults, firstResult); | |
| 334 | + if (luaD_precall(L, func, nResults) == PCRLUA) { /* is a Lua function? */ | |
| 335 | + StkId firstResult = luaV_execute(L, 1); /* call it */ | |
| 336 | + luaD_poscall(L, nResults, firstResult); | |
| 337 | + } | |
| 325 | 338 | L->nCcalls--; |
| 326 | 339 | luaC_checkGC(L); |
| 327 | 340 | } |
| @@ -333,15 +346,14 @@ static void resume (lua_State *L, void *ud) { · 5 unmodified lines | ||
| 333 | 346 | CallInfo *ci = L->ci; |
| 334 | 347 | if (!L->isSuspended) { |
| 335 | 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 | 351 | else { /* resuming from previous yield */ |
| 339 | 352 | if (!f_isLua(ci)) { /* `common' yield? */ |
| 340 | 353 | /* finish interrupted execution of `OP_CALL' */ |
| 341 | − int nresults; | |
| 342 | − lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || | |
| 343 | − GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); | |
| 344 | − nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; | |
| 354 | + int nresults = ci->nresults; | |
| 355 | + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || | |
| 356 | + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); | |
| 345 | 357 | luaD_poscall(L, nresults, L->top - nargs); /* complete it */ |
| 346 | 358 | if (nresults >= 0) L->top = L->ci->top; |
| 347 | 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 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -38,13 +38,19 @@ · 32 unmodified lines | ||
| 38 | 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 | 47 | /* type of protected functions, to be ran by `runprotected' */ |
| 42 | 48 | typedef void (*Pfunc) (lua_State *L, void *ud); |
| 43 | 49 | |
| 44 | 50 | void luaD_resetprotection (lua_State *L); |
| 45 | 51 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); |
| 46 | 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 | 54 | void luaD_call (lua_State *L, StkId func, int nResults); |
| 49 | 55 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 50 | 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 $ | |
| 3 | −** save bytecodes | |
| 2 | +** $Id: ldump.c,v 1.8 2004/09/01 21:22:34 lhf Exp $ | |
| 3 | +** save pre-compiled Lua chunks | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <stddef.h> |
| 8 | 8 | |
| 9 | 9 | #define ldump_c |
| 10 | +#define LUA_CORE | |
| 10 | 11 | |
| 11 | 12 | #include "lua.h" |
| 12 | 13 | |
| @@ -20,16 +21,20 @@ · 7 unmodified lines | ||
| 20 | 21 | |
| 21 | 22 | typedef struct { |
| 22 | 23 | lua_State* L; |
| 23 | − lua_Chunkwriter write; | |
| 24 | + lua_Chunkwriter writer; | |
| 24 | 25 | void* data; |
| 25 | 26 | int strip; |
| 27 | + int status; | |
| 26 | 28 | } DumpState; |
| 27 | 29 | |
| 28 | 30 | static void DumpBlock(const void* b, size_t size, DumpState* D) |
| 29 | 31 | { |
| 30 | − lua_unlock(D->L); | |
| 31 | − (*D->write)(D->L,b,size,D->data); | |
| 32 | − lua_lock(D->L); | |
| 32 | + if (D->status==0) | |
| 33 | + { | |
| 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 | 40 | static void DumpByte(int y, DumpState* D) |
| @@ -53,7 +58,7 @@ static void DumpNumber(lua_Number x, DumpState* D) · 17 unmodified lines | ||
| 53 | 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 | 63 | if (s==NULL || getstr(s)==NULL) |
| 59 | 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 | 165 | DumpState D; |
| 161 | 166 | D.L=L; |
| 162 | − D.write=w; | |
| 167 | + D.writer=w; | |
| 163 | 168 | D.data=data; |
| 164 | 169 | D.strip=strip; |
| 170 | + D.status=0; | |
| 165 | 171 | DumpHeader(&D); |
| 166 | − DumpFunction(Main,NULL,&D); | |
| 167 | − return 1; | |
| 172 | + DumpFunction(f,NULL,&D); | |
| 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 | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stddef.h> |
| 9 | 9 | |
| 10 | 10 | #define lfunc_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 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 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -7,6 +7,7 @@ · 1 unmodified line | ||
| 7 | 7 | #include <string.h> |
| 8 | 8 | |
| 9 | 9 | #define lgc_c |
| 10 | +#define LUA_CORE | |
| 10 | 11 | |
| 11 | 12 | #include "lua.h" |
| 12 | 13 | |
| @@ -22,10 +23,11 @@ · 9 unmodified lines | ||
| 22 | 23 | #include "ltm.h" |
| 23 | 24 | |
| 24 | 25 | |
| 25 | −#define GCSTEPSIZE (40*sizeof(TValue)) | |
| 26 | −#define GCFREECOST (sizeof(TValue)/2) | |
| 27 | −#define GCSWEEPCOST sizeof(TValue) | |
| 28 | −#define GCFINALIZECOST (10*sizeof(TValue)) | |
| 26 | +#define GCSTEPSIZE 1000 | |
| 27 | +#define STEPMUL 2 | |
| 28 | +#define GCSWEEPMAX 10 | |
| 29 | +#define GCSWEEPCOST 30 | |
| 30 | +#define GCFINALIZECOST 100 | |
| 29 | 31 | |
| 30 | 32 | |
| 31 | 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, | |
| 270 | −** turning them to black. Returns extra `quantity' traversed. | |
| 271 | +** traverse one gray object, turning it to black. | |
| 272 | +** Returns `quantity' traversed. | |
| 271 | 273 | */ |
| 272 | −static l_mem propagatemarks (global_State *g, l_mem lim) { | |
| 273 | − GCObject *o; | |
| 274 | − while ((o = g->gray) != NULL) { | |
| 275 | − lua_assert(isgray(o)); | |
| 276 | − gray2black(o); | |
| 277 | − switch (o->gch.tt) { | |
| 278 | − case LUA_TTABLE: { | |
| 279 | − Table *h = gco2h(o); | |
| 280 | − g->gray = h->gclist; | |
| 281 | − if (traversetable(g, h)) /* table is weak? */ | |
| 282 | − black2gray(o); /* keep it gray */ | |
| 283 | − lim -= sizeof(Table) + sizeof(TValue) * h->sizearray + | |
| 284 | − sizeof(Node) * sizenode(h); | |
| 285 | − break; | |
| 286 | − } | |
| 287 | − case LUA_TFUNCTION: { | |
| 288 | − Closure *cl = gco2cl(o); | |
| 289 | − g->gray = cl->c.gclist; | |
| 290 | − traverseclosure(g, cl); | |
| 291 | − lim -= (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : | |
| 292 | − sizeLclosure(cl->l.nupvalues); | |
| 293 | − break; | |
| 294 | − } | |
| 295 | − case LUA_TTHREAD: { | |
| 296 | − lua_State *th = gco2th(o); | |
| 297 | − g->gray = th->gclist; | |
| 298 | − th->gclist = g->grayagain; | |
| 299 | − g->grayagain = o; | |
| 300 | − black2gray(o); | |
| 301 | − traversestack(g, th); | |
| 302 | − lim -= sizeof(lua_State) + sizeof(TValue) * th->stacksize + | |
| 303 | − sizeof(CallInfo) * th->size_ci; | |
| 304 | − break; | |
| 305 | − } | |
| 306 | − case LUA_TPROTO: { | |
| 307 | − Proto *p = gco2p(o); | |
| 308 | − g->gray = p->gclist; | |
| 309 | − traverseproto(g, p); | |
| 310 | − lim -= sizeof(Proto) + sizeof(Instruction) * p->sizecode + | |
| 311 | − sizeof(Proto *) * p->sizep + | |
| 312 | − sizeof(TValue) * p->sizek + | |
| 313 | − sizeof(int) * p->sizelineinfo + | |
| 314 | − sizeof(LocVar) * p->sizelocvars + | |
| 315 | − sizeof(TString *) * p->sizeupvalues; | |
| 316 | − break; | |
| 317 | − } | |
| 318 | − default: lua_assert(0); | |
| 274 | +static l_mem propagatemark (global_State *g) { | |
| 275 | + GCObject *o = g->gray; | |
| 276 | + lua_assert(isgray(o)); | |
| 277 | + gray2black(o); | |
| 278 | + switch (o->gch.tt) { | |
| 279 | + case LUA_TTABLE: { | |
| 280 | + Table *h = gco2h(o); | |
| 281 | + g->gray = h->gclist; | |
| 282 | + if (traversetable(g, h)) /* table is weak? */ | |
| 283 | + black2gray(o); /* keep it gray */ | |
| 284 | + return sizeof(Table) + sizeof(TValue) * h->sizearray + | |
| 285 | + sizeof(Node) * sizenode(h); | |
| 286 | + break; | |
| 287 | + } | |
| 288 | + case LUA_TFUNCTION: { | |
| 289 | + Closure *cl = gco2cl(o); | |
| 290 | + g->gray = cl->c.gclist; | |
| 291 | + traverseclosure(g, cl); | |
| 292 | + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : | |
| 293 | + sizeLclosure(cl->l.nupvalues); | |
| 294 | + break; | |
| 295 | + } | |
| 296 | + case LUA_TTHREAD: { | |
| 297 | + lua_State *th = gco2th(o); | |
| 298 | + g->gray = th->gclist; | |
| 299 | + th->gclist = g->grayagain; | |
| 300 | + g->grayagain = o; | |
| 301 | + black2gray(o); | |
| 302 | + traversestack(g, th); | |
| 303 | + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | |
| 304 | + sizeof(CallInfo) * th->size_ci; | |
| 305 | + break; | |
| 306 | + } | |
| 307 | + case LUA_TPROTO: { | |
| 308 | + Proto *p = gco2p(o); | |
| 309 | + g->gray = p->gclist; | |
| 310 | + traverseproto(g, p); | |
| 311 | + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + | |
| 312 | + sizeof(Proto *) * p->sizep + | |
| 313 | + sizeof(TValue) * p->sizek + | |
| 314 | + sizeof(int) * p->sizelineinfo + | |
| 315 | + sizeof(LocVar) * p->sizelocvars + | |
| 316 | + sizeof(TString *) * p->sizeupvalues; | |
| 317 | + break; | |
| 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 | 384 | break; |
| 382 | 385 | } |
| 383 | 386 | case LUA_TSTRING: { |
| 387 | + G(L)->strt.nuse--; | |
| 384 | 388 | luaM_free(L, o, sizestring(gco2ts(o)->len)); |
| 385 | 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, | |
| 397 | − lu_int32 *count); | |
| 400 | + | |
| 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, | |
| 401 | − l_mem *plim, lu_int32 *count) { | |
| 404 | +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) { | |
| 402 | 405 | GCObject *curr; |
| 403 | 406 | global_State *g = G(L); |
| 404 | − l_mem lim = *plim; | |
| 405 | − int deadmask = otherwhite(g); | |
| 406 | − if (keepfixed) deadmask |= FIXEDMASK; | |
| 407 | − while ((curr = *p) != NULL) { | |
| 408 | − if (((curr->gch.marked ^ FIXEDMASK) & deadmask) != deadmask) { | |
| 409 | − makewhite(g, curr); | |
| 407 | + int whitebit = otherwhite(g); | |
| 408 | + int deadmask = whitebit | FIXEDMASK; | |
| 409 | + int generational = g->gcgenerational; | |
| 410 | + while ((curr = *p) != NULL && count-- > 0) { | |
| 411 | + if ((curr->gch.marked ^ whitebit) & deadmask) { | |
| 412 | + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); | |
| 413 | + if (!generational || isdead(g, curr)) | |
| 414 | + makewhite(g, curr); | |
| 410 | 415 | if (curr->gch.tt == LUA_TTHREAD) |
| 411 | − lim -= sweepwholelist(L, &gco2th(curr)->openupval, keepfixed, count); | |
| 416 | + sweepwholelist(L, &gco2th(curr)->openupval); | |
| 412 | 417 | p = &curr->gch.next; |
| 413 | − lim -= GCSWEEPCOST; | |
| 414 | 418 | } |
| 415 | 419 | else { |
| 416 | − lua_assert(iswhite(curr)); | |
| 420 | + lua_assert(isdead(g, curr)); | |
| 417 | 421 | *p = curr->gch.next; |
| 418 | 422 | if (curr == g->rootgc) /* is the first element of the list? */ |
| 419 | 423 | g->rootgc = curr->gch.next; /* adjust first */ |
| 420 | 424 | freeobj(L, curr); |
| 421 | − lim -= GCFREECOST; | |
| 422 | − if (count) (*count)--; | |
| 423 | 425 | } |
| 424 | − if (lim <= 0) break; | |
| 425 | 426 | } |
| 426 | − *plim = lim; | |
| 427 | 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) { | |
| 441 | − int i; | |
| 442 | − global_State *g = G(L); | |
| 443 | − for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */ | |
| 444 | − lim -= sweepwholelist(L, &G(L)->strt.hash[i], keepfixed, &g->strt.nuse); | |
| 445 | − if (lim <= 0) break; | |
| 432 | +static void freelist (lua_State *L, GCObject **p) { | |
| 433 | + while (*p) { | |
| 434 | + GCObject *curr = *p; | |
| 435 | + *p = (*p)->gch.next; | |
| 436 | + if (curr != obj2gco(L)) | |
| 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 | 488 | global_State *g = G(L); |
| 499 | − l_mem dummy = MAXLMEM; | |
| 500 | − /* finish (occasional) current sweep */ | |
| 501 | − sweepstrings(L, 0, MAXLMEM); | |
| 502 | − sweeplist(L, &g->rootgc, 0, &dummy, NULL); | |
| 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); | |
| 489 | + int i; | |
| 490 | + freelist(L, &g->rootgc); | |
| 491 | + for (i = 0; i < g->strt.size; i++) /* free all string lists */ | |
| 492 | + freelist(L, &G(L)->strt.hash[i]); | |
| 510 | 493 | } |
| 511 | 494 | |
| 512 | 495 | |
| @@ -530,8 +513,10 @@ static void remarkupvals (global_State *g) { · 17 unmodified lines | ||
| 530 | 513 | if (iswhite(o)) { |
| 531 | 514 | GCObject *curr; |
| 532 | 515 | for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) { |
| 533 | − if (isgray(curr)) | |
| 534 | − markvalue(g, gco2uv(curr)->v); | |
| 516 | + if (isgray(curr)) { | |
| 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 | 526 | static void atomic (lua_State *L) { |
| 542 | 527 | global_State *g = G(L); |
| 528 | + int aux; | |
| 543 | 529 | lua_assert(g->gray == NULL); |
| 544 | 530 | /* remark occasional upvalues of (maybe) dead threads */ |
| 545 | 531 | remarkupvals(g); |
| @@ -548,90 +534,130 @@ static void atomic (lua_State *L) { · 2 unmodified lines | ||
| 548 | 534 | g->weak = NULL; |
| 549 | 535 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
| 550 | 536 | markobject(g, L); /* mark running thread */ |
| 551 | − propagatemarks(g, MAXLMEM); | |
| 537 | + propagateall(g); | |
| 552 | 538 | /* remark gray again */ |
| 553 | 539 | g->gray = g->grayagain; |
| 554 | 540 | g->grayagain = NULL; |
| 555 | − propagatemarks(g, MAXLMEM); | |
| 541 | + propagateall(g); | |
| 556 | 542 | luaC_separateudata(L, 0); /* separate userdata to be preserved */ |
| 557 | 543 | marktmu(g); /* mark `preserved' userdata */ |
| 558 | − propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ | |
| 544 | + propagateall(g); /* remark, to propagate `preserveness' */ | |
| 559 | 545 | cleartable(g->weak); /* remove collected objects from weak tables */ |
| 560 | 546 | /* flip current white */ |
| 561 | 547 | g->currentwhite = otherwhite(g); |
| 548 | + g->sweepstrgc = 0; | |
| 549 | + g->sweepgc = &g->rootgc; | |
| 562 | 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 | 560 | global_State *g = G(L); |
| 561 | + /*lua_checkmemory(L);*/ | |
| 568 | 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 | 571 | case GCSpropagate: { |
| 570 | 572 | if (g->gray) |
| 571 | − lim = propagatemarks(g, lim); | |
| 573 | + return propagatemark(g); | |
| 572 | 574 | else { /* no more `gray' objects */ |
| 573 | 575 | atomic(L); /* finish mark phase */ |
| 574 | − lim = 0; | |
| 576 | + return 0; | |
| 575 | 577 | } |
| 576 | − break; | |
| 577 | 578 | } |
| 578 | 579 | case GCSsweepstring: { |
| 579 | − lim = sweepstrings(L, 1, lim); | |
| 580 | − if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */ | |
| 581 | − g->sweepstrgc = 0; | |
| 580 | + lu_mem old = g->totalbytes; | |
| 581 | + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | |
| 582 | + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ | |
| 582 | 583 | g->gcstate = GCSsweep; /* end sweep-string phase */ |
| 583 | − } | |
| 584 | − break; | |
| 584 | + g->estimate -= old - g->totalbytes; | |
| 585 | + return GCSWEEPCOST; | |
| 585 | 586 | } |
| 586 | 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 | 590 | if (*g->sweepgc == NULL) { /* nothing more to sweep? */ |
| 589 | 591 | checkSizes(L); |
| 590 | − g->sweepgc = &g->rootgc; | |
| 591 | 592 | g->gcstate = GCSfinalize; /* end sweep phase */ |
| 592 | 593 | } |
| 593 | − break; | |
| 594 | + g->estimate -= old - g->totalbytes; | |
| 595 | + return GCSWEEPMAX*GCSWEEPCOST; | |
| 594 | 596 | } |
| 595 | 597 | case GCSfinalize: { |
| 596 | 598 | if (g->tmudata) { |
| 597 | 599 | GCTM(L); |
| 598 | − lim -= GCFINALIZECOST; | |
| 600 | + return GCFINALIZECOST; | |
| 599 | 601 | } |
| 600 | − else { /* no more `udata' to finalize */ | |
| 601 | − markroot(L); /* may restart collection */ | |
| 602 | − lim = 0; | |
| 602 | + else { | |
| 603 | + g->gcstate = GCSpause; /* end collection */ | |
| 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 | 612 | void luaC_step (lua_State *L) { |
| 613 | 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 | 616 | do { |
| 616 | − lim = singlestep(L, lim); | |
| 617 | − if (g->gcstate == GCSfinalize && g->tmudata == NULL) | |
| 618 | − break; /* do not start new collection */ | |
| 617 | + /*printf("%c", "_pswf"[g->gcstate]);*/ | |
| 618 | + lim -= singlestep(L); | |
| 619 | + if (g->gcstate == GCSpause) | |
| 620 | + break; | |
| 619 | 621 | } while (lim > 0); |
| 620 | − g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2; | |
| 621 | − lua_assert((long)g->nblocks + (long)GCSTEPSIZE >= lim/2); | |
| 622 | +/*printf("\n");*/ | |
| 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 | 635 | void luaC_fullgc (lua_State *L) { |
| 626 | 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 | 649 | while (g->gcstate != GCSfinalize) { |
| 628 | − singlestep(L, MAXLMEM); | |
| 650 | + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); | |
| 651 | + singlestep(L); | |
| 629 | 652 | } |
| 630 | 653 | markroot(L); |
| 654 | + lua_assert(!g->gcgenerational); | |
| 631 | 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 | 661 | luaC_callGCTM(L); /* call finalizers */ |
| 636 | 662 | } |
| 637 | 663 | |
| @@ -639,7 +665,7 @@ void luaC_fullgc (lua_State *L) { · 1 unmodified line | ||
| 639 | 665 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { |
| 640 | 666 | global_State *g = G(L); |
| 641 | 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 | 669 | if (g->gcstate != GCSpropagate) /* sweeping phases? */ |
| 644 | 670 | black2gray(o); /* just mark as gray to avoid other barriers */ |
| 645 | 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 | 686 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { |
| 651 | 687 | global_State *g = G(L); |
| 652 | 688 | o->gch.next = g->rootgc; |
| @@ -662,13 +698,13 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { · 9 unmodified lines | ||
| 662 | 698 | o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ |
| 663 | 699 | g->rootgc = o; |
| 664 | 700 | if (isgray(o)) { |
| 665 | − if (g->gcstate == GCSpropagate) { | |
| 701 | + if (g->gcstate == GCSpropagate || g->gcgenerational) { | |
| 666 | 702 | gray2black(o); /* closed upvalues need barrier */ |
| 667 | 703 | luaC_barrier(L, uv, uv->v); |
| 668 | 704 | } |
| 669 | 705 | else { /* sweep phase: sweep it (turning it into white) */ |
| 670 | 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 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -14,10 +14,11 @@ · 8 unmodified lines | ||
| 14 | 14 | /* |
| 15 | 15 | ** Possible states of the Garbage Collector |
| 16 | 16 | */ |
| 17 | −#define GCSpropagate 0 | |
| 18 | −#define GCSsweepstring 1 | |
| 19 | −#define GCSsweep 2 | |
| 20 | −#define GCSfinalize 3 | |
| 17 | +#define GCSpause 0 | |
| 18 | +#define GCSpropagate 1 | |
| 19 | +#define GCSsweepstring 2 | |
| 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 | 42 | ** Layout for bit use in `marked' field: |
| 42 | −** bit 0 - object is gray | |
| 43 | −** bit 1 - object is black | |
| 44 | −** bit 2 - For userdata: is finalized; | |
| 45 | − for tables: has weak keys | |
| 46 | −** bit 3 - for tables: has weak values | |
| 47 | −** bit 4 - object is fixed (should not be collected) | |
| 43 | +** bit 0 - object is white (type 0) | |
| 44 | +** bit 1 - object is white (type 1) | |
| 45 | +** bit 2 - object is black | |
| 46 | +** bit 3 - for userdata: has been finalized | |
| 47 | +** bit 3 - for tables: has weak keys | |
| 48 | +** bit 4 - for tables: has weak values | |
| 49 | +** bit 5 - object is fixed (should not be collected) | |
| 48 | 50 | */ |
| 49 | 51 | |
| 50 | 52 | #define WHITE0BIT 0 |
| @@ -70,25 +72,29 @@ · 19 unmodified lines | ||
| 70 | 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 | 76 | luaC_step(L); } |
| 75 | 77 | |
| 76 | 78 | |
| 77 | 79 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ |
| 78 | 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 | 85 | #define luaC_objbarrier(L,p,o) \ |
| 81 | 86 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ |
| 82 | 87 | luaC_barrierf(L,obj2gco(p),obj2gco(o)); } |
| 83 | 88 | |
| 84 | 89 | size_t luaC_separateudata (lua_State *L, int all); |
| 85 | 90 | void luaC_callGCTM (lua_State *L); |
| 86 | −void luaC_sweepall (lua_State *L); | |
| 91 | +void luaC_freeall (lua_State *L); | |
| 87 | 92 | void luaC_step (lua_State *L); |
| 88 | 93 | void luaC_fullgc (lua_State *L); |
| 89 | 94 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt); |
| 90 | 95 | void luaC_linkupval (lua_State *L, UpVal *uv); |
| 91 | 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 | 100 | #endif |
| @@ -6,8 +6,8 @@ include $(LUA)/config · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 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 | |
| 10 | −SRCS= lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c ltablib.c lstrlib.c loadlib.c | |
| 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 loslib.c ltablib.c lstrlib.c loadlib.c linit.c | |
| 11 | 11 | |
| 12 | 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 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -18,6 +18,7 @@ · 12 unmodified lines | ||
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | 20 | #define lauxlib_c |
| 21 | +#define LUA_LIB | |
| 21 | 22 | |
| 22 | 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 | 64 | LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { |
| 64 | 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 | 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 | 243 | if (lua_isnil(L, -1)) { /* no? */ |
| 243 | 244 | lua_pop(L, 1); |
| 244 | 245 | lua_newtable(L); /* create it */ |
| 246 | + if (lua_getmetatable(L, LUA_GLOBALSINDEX)) | |
| 247 | + lua_setmetatable(L, -2); /* share metatable with global table */ | |
| 245 | 248 | lua_pushvalue(L, -1); |
| 246 | 249 | /* register it with given name */ |
| 247 | 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 | 295 | t = abs_index(L, t); |
| 293 | 296 | getsizes(L); |
| 294 | 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 | 330 | int n; |
| 303 | 331 | t = abs_index(L, t); |
| 304 | 332 | getsizes(L); /* try sizes[t] */ |
| @@ -307,18 +335,61 @@ int luaL_getn (lua_State *L, int t) { · 2 unmodified lines | ||
| 307 | 335 | if ((n = checkint(L, 2)) >= 0) return n; |
| 308 | 336 | lua_getfield(L, t, "n"); /* else try t.n */ |
| 309 | 337 | if ((n = checkint(L, 1)) >= 0) return n; |
| 310 | − for (n = 1; ; n++) { /* else must count elements */ | |
| 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; | |
| 338 | + return countn(L, t); | |
| 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 | 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 | 558 | lua_remove(L, fnameindex); |
| 487 | 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 | 573 | else { |
| 502 | 574 | lua_pushfstring(L, "@%s", filename); |
| 503 | 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 | 578 | c = getc(lf.f); |
| 507 | 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 | 584 | if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */ |
| 513 | 585 | fclose(lf.f); |
| 514 | 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 | 588 | /* skip eventual `#!...' */ |
| 517 | 589 | while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; |
| 518 | 590 | lf.extraline = 0; |
| @@ -523,7 +595,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { · 4 unmodified lines | ||
| 523 | 595 | if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ |
| 524 | 596 | if (readstatus) { |
| 525 | 597 | lua_settop(L, fnameindex); /* ignore results from `lua_load' */ |
| 526 | − return errfile(L, fnameindex); | |
| 598 | + return errfile(L, "read", fnameindex); | |
| 527 | 599 | } |
| 528 | 600 | lua_remove(L, fnameindex); |
| 529 | 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 | 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) { | |
| 572 | − return lua_newstate(l_alloc, NULL); | |
| 573 | −} | |
| 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 | − } | |
| 644 | +static int panic (lua_State *L) { | |
| 645 | + fprintf(stderr, "PANIC: unprotected error during Lua-API call\n"); | |
| 646 | + return 0; | |
| 595 | 647 | } |
| 596 | 648 | |
| 597 | 649 | |
| 598 | −static int aux_do (lua_State *L, int status) { | |
| 599 | − if (status == 0) { /* parse OK? */ | |
| 600 | − status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */ | |
| 601 | − } | |
| 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); | |
| 650 | +LUALIB_API lua_State *luaL_newstate (void) { | |
| 651 | + lua_State *L = lua_newstate(l_alloc, NULL); | |
| 652 | + lua_atpanic(L, &panic); | |
| 653 | + return L; | |
| 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 | 3 | ** Basic library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -12,6 +12,7 @@ · 6 unmodified lines | ||
| 12 | 12 | #include <string.h> |
| 13 | 13 | |
| 14 | 14 | #define lbaselib_c |
| 15 | +#define LUA_LIB | |
| 15 | 16 | |
| 16 | 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 | 132 | static int luaB_getfenv (lua_State *L) { |
| 140 | 133 | getfunc(L); |
| 141 | − if (!aux_getfenv(L)) /* __fenv not defined? */ | |
| 142 | − lua_pop(L, 1); /* remove it, to return real environment */ | |
| 134 | + lua_getfenv(L, -1); | |
| 143 | 135 | return 1; |
| 144 | 136 | } |
| 145 | 137 | |
| @@ -147,16 +139,14 @@ static int luaB_getfenv (lua_State *L) { · 1 unmodified line | ||
| 147 | 139 | static int luaB_setfenv (lua_State *L) { |
| 148 | 140 | luaL_checktype(L, 2, LUA_TTABLE); |
| 149 | 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 | 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 | 144 | lua_replace(L, LUA_GLOBALSINDEX); |
| 145 | + return 0; | |
| 146 | + } | |
| 157 | 147 | else if (lua_setfenv(L, -2) == 0) |
| 158 | 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 | 183 | static int luaB_collectgarbage (lua_State *L) { |
| 194 | 184 | static const char *const opts[] = {"stop", "restart", "collect", "count", |
| 195 | − NULL}; | |
| 185 | + "step", NULL}; | |
| 196 | 186 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, |
| 197 | − LUA_GCCOLLECT, LUA_GCCOUNT}; | |
| 198 | − int o; | |
| 199 | − int ex; | |
| 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); | |
| 187 | + LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP}; | |
| 188 | + int o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); | |
| 189 | + int ex = luaL_optint(L, 2, 0); | |
| 211 | 190 | luaL_argcheck(L, o >= 0, 1, "invalid option"); |
| 212 | 191 | lua_pushinteger(L, lua_gc(L, optsnum[o], ex)); |
| 213 | 192 | return 1; |
| @@ -216,7 +195,7 @@ static int luaB_collectgarbage (lua_State *L) { · 2 unmodified lines | ||
| 216 | 195 | |
| 217 | 196 | static int luaB_type (lua_State *L) { |
| 218 | 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 | 199 | return 1; |
| 221 | 200 | } |
| 222 | 201 | |
| @@ -235,28 +214,29 @@ static int luaB_next (lua_State *L) { · 12 unmodified lines | ||
| 235 | 214 | |
| 236 | 215 | static int luaB_pairs (lua_State *L) { |
| 237 | 216 | luaL_checktype(L, 1, LUA_TTABLE); |
| 238 | − lua_getglobal(L, "next"); /* return generator, */ | |
| 217 | + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ | |
| 239 | 218 | lua_pushvalue(L, 1); /* state, */ |
| 240 | 219 | lua_pushnil(L); /* and initial value */ |
| 241 | 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 | 234 | static int luaB_ipairs (lua_State *L) { |
| 246 | − int i = (int)lua_tointeger(L, 2); | |
| 247 | 235 | luaL_checktype(L, 1, LUA_TTABLE); |
| 248 | − if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */ | |
| 249 | − lua_getglobal(L, "ipairs"); /* return generator, */ | |
| 250 | − lua_pushvalue(L, 1); /* state, */ | |
| 251 | − lua_pushinteger(L, 0); /* and initial value */ | |
| 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 | − } | |
| 236 | + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ | |
| 237 | + lua_pushvalue(L, 1); /* state, */ | |
| 238 | + lua_pushinteger(L, LUA_FIRSTINDEX - 1); /* and initial value */ | |
| 239 | + return 3; | |
| 260 | 240 | } |
| 261 | 241 | |
| 262 | 242 | |
| @@ -281,7 +261,15 @@ static int luaB_loadstring (lua_State *L) { · 18 unmodified lines | ||
| 281 | 261 | |
| 282 | 262 | static int luaB_loadfile (lua_State *L) { |
| 283 | 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 | 327 | luaL_checkany(L, 1); |
| 340 | 328 | if (!lua_toboolean(L, 1)) |
| 341 | 329 | return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); |
| 342 | − lua_settop(L, 1); | |
| 343 | − return 1; | |
| 330 | + return lua_gettop(L); | |
| 344 | 331 | } |
| 345 | 332 | |
| 346 | 333 | |
| 347 | 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 | 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 | 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 | 345 | lua_rawgeti(L, 1, i); |
| 354 | 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 | 365 | static int luaB_pcall (lua_State *L) { |
| 359 | 366 | int status; |
| 360 | 367 | luaL_checkany(L, 1); |
| @@ -378,45 +385,36 @@ static int luaB_xpcall (lua_State *L) { · 17 unmodified lines | ||
| 378 | 385 | |
| 379 | 386 | |
| 380 | 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 | 388 | luaL_checkany(L, 1); |
| 385 | 389 | if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ |
| 386 | 390 | return 1; /* use its value */ |
| 387 | 391 | switch (lua_type(L, 1)) { |
| 388 | 392 | case LUA_TNUMBER: |
| 389 | 393 | lua_pushstring(L, lua_tostring(L, 1)); |
| 390 | − return 1; | |
| 394 | + break; | |
| 391 | 395 | case LUA_TSTRING: |
| 392 | 396 | lua_pushvalue(L, 1); |
| 393 | − return 1; | |
| 397 | + break; | |
| 394 | 398 | case LUA_TBOOLEAN: |
| 395 | 399 | lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); |
| 396 | − return 1; | |
| 400 | + break; | |
| 397 | 401 | case LUA_TNIL: |
| 398 | 402 | lua_pushliteral(L, "nil"); |
| 399 | − return 1; | |
| 403 | + break; | |
| 400 | 404 | case LUA_TTABLE: |
| 401 | − p = lua_topointer(L, 1); | |
| 402 | − tn = "table"; | |
| 405 | + lua_pushfstring(L, "table: %p", lua_topointer(L, 1)); | |
| 403 | 406 | break; |
| 404 | 407 | case LUA_TFUNCTION: |
| 405 | − p = lua_topointer(L, 1); | |
| 406 | − tn = "function"; | |
| 408 | + lua_pushfstring(L, "function: %p", lua_topointer(L, 1)); | |
| 407 | 409 | break; |
| 408 | 410 | case LUA_TUSERDATA: |
| 409 | 411 | case LUA_TLIGHTUSERDATA: |
| 410 | − p = lua_touserdata(L, 1); | |
| 411 | − tn = "userdata"; | |
| 412 | + lua_pushfstring(L, "userdata: %p", lua_topointer(L, 1)); | |
| 412 | 413 | break; |
| 413 | 414 | case LUA_TTHREAD: |
| 414 | − p = lua_tothread(L, 1); | |
| 415 | − tn = "thread"; | |
| 415 | + lua_pushfstring(L, "thread: %p", lua_topointer(L, 1)); | |
| 416 | 416 | break; |
| 417 | 417 | } |
| 418 | − sprintf(buff, "%p", p); | |
| 419 | − lua_pushfstring(L, "%s: %s", tn, buff); | |
| 420 | 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 | 455 | static const char *getpath (lua_State *L) { |
| 477 | − const char *path; | |
| 478 | − lua_getglobal(L, LUA_PATH); /* try global variable */ | |
| 479 | − path = lua_tostring(L, -1); | |
| 480 | − lua_pop(L, 1); | |
| 481 | − if (path) return 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; | |
| 456 | + /* try first `LUA_PATH' for compatibility */ | |
| 457 | + lua_getfield(L, LUA_GLOBALSINDEX, "LUA_PATH"); | |
| 458 | + if (!lua_isstring(L, -1)) { | |
| 459 | + lua_pop(L, 1); | |
| 460 | + lua_getfield(L, LUA_GLOBALSINDEX, "_PATH"); | |
| 510 | 461 | } |
| 511 | − lua_pushstring(L, path); /* push last suffix (`n' already includes this) */ | |
| 512 | − lua_concat(L, n); | |
| 462 | + if (!lua_isstring(L, -1)) | |
| 463 | + luaL_error(L, "global _PATH must be a string"); | |
| 464 | + return lua_tostring(L, -1); | |
| 513 | 465 | } |
| 514 | 466 | |
| 515 | 467 | |
| 516 | 468 | static int luaB_require (lua_State *L) { |
| 517 | − const char *path; | |
| 518 | − int status = LUA_ERRFILE; /* not found (yet) */ | |
| 519 | − luaL_checkstring(L, 1); | |
| 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); | |
| 469 | + const char *name = luaL_checkstring(L, 1); | |
| 470 | + const char *fname; | |
| 471 | + lua_getfield(L, lua_upvalueindex(1), name); | |
| 526 | 472 | if (lua_toboolean(L, -1)) /* is it there? */ |
| 527 | 473 | return 1; /* package is already loaded; return its result */ |
| 528 | − else { /* must load it */ | |
| 529 | − while (status == LUA_ERRFILE) { | |
| 530 | − lua_settop(L, 3); /* reset stack position */ | |
| 531 | − if ((path = pushnextpath(L, path)) == NULL) break; | |
| 532 | − pushcomposename(L); | |
| 533 | − status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */ | |
| 534 | − } | |
| 535 | − } | |
| 536 | − switch (status) { | |
| 537 | − case 0: { | |
| 538 | − lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */ | |
| 539 | − lua_insert(L, -2); /* put it below function */ | |
| 540 | − lua_pushvalue(L, 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 | − } | |
| 474 | + /* else must load it; first mark it as loaded */ | |
| 475 | + lua_pushboolean(L, 1); | |
| 476 | + lua_setfield(L, lua_upvalueindex(1), name); /* _LOADED[name] = true */ | |
| 477 | + fname = luaL_searchpath(L, name, getpath(L)); | |
| 478 | + if (fname == NULL || luaL_loadfile(L, fname) != 0) | |
| 479 | + return luaL_error(L, "error loading package `%s' (%s)", name, | |
| 480 | + lua_tostring(L, -1)); | |
| 481 | + lua_pushvalue(L, 1); /* pass name as argument to module */ | |
| 482 | + lua_call(L, 1, 1); /* run loaded module */ | |
| 483 | + if (!lua_isnil(L, -1)) /* nil return? */ | |
| 484 | + lua_setfield(L, lua_upvalueindex(1), name); | |
| 485 | + lua_getfield(L, lua_upvalueindex(1), name); /* return _LOADED[name] */ | |
| 486 | + return 1; | |
| 563 | 487 | } |
| 564 | 488 | |
| 565 | 489 | /* }====================================================== */ |
| @@ -572,14 +496,13 @@ static const luaL_reg base_funcs[] = { · 6 unmodified lines | ||
| 572 | 496 | {"getfenv", luaB_getfenv}, |
| 573 | 497 | {"setfenv", luaB_setfenv}, |
| 574 | 498 | {"next", luaB_next}, |
| 575 | − {"ipairs", luaB_ipairs}, | |
| 576 | − {"pairs", luaB_pairs}, | |
| 577 | 499 | {"print", luaB_print}, |
| 578 | 500 | {"tonumber", luaB_tonumber}, |
| 579 | 501 | {"tostring", luaB_tostring}, |
| 580 | 502 | {"type", luaB_type}, |
| 581 | 503 | {"assert", luaB_assert}, |
| 582 | 504 | {"unpack", luaB_unpack}, |
| 505 | + {"select", luaB_select}, | |
| 583 | 506 | {"rawequal", luaB_rawequal}, |
| 584 | 507 | {"rawget", luaB_rawget}, |
| 585 | 508 | {"rawset", luaB_rawset}, |
| @@ -591,7 +514,6 @@ static const luaL_reg base_funcs[] = { · 5 unmodified lines | ||
| 591 | 514 | {"dofile", luaB_dofile}, |
| 592 | 515 | {"loadstring", luaB_loadstring}, |
| 593 | 516 | {"load", luaB_load}, |
| 594 | − {"require", luaB_require}, | |
| 595 | 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 | 637 | static void base_open (lua_State *L) { |
| 638 | + const char *path; | |
| 709 | 639 | lua_pushvalue(L, LUA_GLOBALSINDEX); |
| 710 | 640 | luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ |
| 711 | 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 | 646 | /* `newproxy' needs a weaktable as upvalue */ |
| 714 | 647 | lua_newtable(L); /* new table `w' */ |
| 715 | 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 | 650 | lua_pushliteral(L, "kv"); |
| 718 | 651 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ |
| 719 | 652 | lua_pushcclosure(L, luaB_newproxy, 1); |
| 720 | − lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ | |
| 721 | − lua_setfield(L, -1, "_G"); /* set global _G */ | |
| 653 | + lua_setfield(L, LUA_GLOBALSINDEX, "newproxy"); /* set global `newproxy' */ | |
| 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 | 671 | LUALIB_API int luaopen_base (lua_State *L) { |
| 726 | 672 | base_open(L); |
| 727 | 673 | luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); |
| 728 | − lua_newtable(L); | |
| 729 | − lua_setglobal(L, REQTAB); | |
| 730 | 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 | 3 | ** Interface from Lua to its debug API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -10,6 +10,7 @@ · 4 unmodified lines | ||
| 10 | 10 | #include <string.h> |
| 11 | 11 | |
| 12 | 12 | #define ldblib_c |
| 13 | +#define LUA_LIB | |
| 13 | 14 | |
| 14 | 15 | #include "lua.h" |
| 15 | 16 | |
| @@ -260,7 +261,11 @@ static int debug (lua_State *L) { · 244 unmodified lines | ||
| 260 | 261 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || |
| 261 | 262 | strcmp(buffer, "cont\n") == 0) |
| 262 | 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 | 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 | 303 | lua_pushfstring(L, "%s:", ar.short_src); |
| 299 | 304 | if (ar.currentline > 0) |
| 300 | 305 | lua_pushfstring(L, "%d:", ar.currentline); |
| 301 | − switch (*ar.namewhat) { | |
| 302 | − case 'g': /* global */ | |
| 303 | − case 'l': /* local */ | |
| 304 | − case 'f': /* field */ | |
| 305 | − case 'm': /* method */ | |
| 306 | + if (*ar.namewhat != '\0') /* is there a name? */ | |
| 306 | 307 | lua_pushfstring(L, " in function `%s'", ar.name); |
| 307 | − break; | |
| 308 | − default: { | |
| 309 | − if (*ar.what == 'm') /* main? */ | |
| 310 | − lua_pushfstring(L, " in main chunk"); | |
| 311 | − else if (*ar.what == 'C' || *ar.what == 't') | |
| 312 | − lua_pushliteral(L, " ?"); /* C function or tail call */ | |
| 313 | − else | |
| 314 | − lua_pushfstring(L, " in function <%s:%d>", | |
| 315 | − ar.short_src, ar.linedefined); | |
| 316 | − } | |
| 308 | + else { | |
| 309 | + if (*ar.what == 'm') /* main? */ | |
| 310 | + lua_pushfstring(L, " in main chunk"); | |
| 311 | + else if (*ar.what == 'C' || *ar.what == 't') | |
| 312 | + lua_pushliteral(L, " ?"); /* C function or tail call */ | |
| 313 | + else | |
| 314 | + lua_pushfstring(L, " in function <%s:%d>", | |
| 315 | + ar.short_src, ar.linedefined); | |
| 317 | 316 | } |
| 318 | 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 | 3 | ** Standard I/O (and system) library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | #include <errno.h> |
| 9 | −#include <locale.h> | |
| 10 | 9 | #include <stdio.h> |
| 11 | 10 | #include <stdlib.h> |
| 12 | 11 | #include <string.h> |
| 13 | −#include <time.h> | |
| 14 | 12 | |
| 15 | 13 | #define liolib_c |
| 14 | +#define LUA_LIB | |
| 16 | 15 | |
| 17 | 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 | 23 | #define IO_INPUT 1 |
| 65 | 24 | #define IO_OUTPUT 2 |
| 66 | 25 | |
| 67 | 26 | |
| 27 | +static const char *const fnames[] = {"input", "output"}; | |
| 28 | + | |
| 29 | + | |
| 68 | 30 | static int pushresult (lua_State *L, int i, const char *filename) { |
| 69 | 31 | if (i) { |
| 70 | 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) { | |
| 86 | − FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE); | |
| 87 | − if (f == NULL) luaL_argerror(L, findex, "bad file"); | |
| 47 | +static void fileerror (lua_State *L, int arg, const char *filename) { | |
| 48 | + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); | |
| 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 | 56 | return f; |
| 89 | 57 | } |
| 90 | 58 | |
| 91 | 59 | |
| 92 | 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 | 62 | if (f == NULL) lua_pushnil(L); |
| 95 | 63 | else if (*f == NULL) |
| 96 | 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) { | |
| 104 | − FILE **f = topfile(L, findex); | |
| 71 | +static FILE *tofile (lua_State *L) { | |
| 72 | + FILE **f = topfile(L); | |
| 105 | 73 | if (*f == NULL) |
| 106 | 74 | luaL_error(L, "attempt to use a closed file"); |
| 107 | 75 | return *f; |
| @@ -117,18 +85,18 @@ static FILE *tofile (lua_State *L, int findex) { · 9 unmodified lines | ||
| 117 | 85 | static FILE **newfile (lua_State *L) { |
| 118 | 86 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); |
| 119 | 87 | *pf = NULL; /* file handle is currently `closed' */ |
| 120 | − luaL_getmetatable(L, FILEHANDLE); | |
| 88 | + luaL_getmetatable(L, LUA_FILEHANDLE); | |
| 121 | 89 | lua_setmetatable(L, -2); |
| 122 | 90 | return pf; |
| 123 | 91 | } |
| 124 | 92 | |
| 125 | 93 | |
| 126 | 94 | static int aux_close (lua_State *L) { |
| 127 | − FILE *f = tofile(L, 1); | |
| 95 | + FILE *f = tofile(L); | |
| 128 | 96 | if (f == stdin || f == stdout || f == stderr) |
| 129 | 97 | return 0; /* file cannot be closed */ |
| 130 | 98 | else { |
| 131 | − int ok = (pclose(f) != -1) || (fclose(f) == 0); | |
| 99 | + int ok = (fclose(f) == 0); | |
| 132 | 100 | if (ok) |
| 133 | 101 | *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */ |
| 134 | 102 | return ok; |
| @@ -144,7 +112,7 @@ static int io_close (lua_State *L) { · 9 unmodified lines | ||
| 144 | 112 | |
| 145 | 113 | |
| 146 | 114 | static int io_gc (lua_State *L) { |
| 147 | − FILE **f = topfile(L, 1); | |
| 115 | + FILE **f = topfile(L); | |
| 148 | 116 | if (*f != NULL) /* ignore closed files */ |
| 149 | 117 | aux_close(L); |
| 150 | 118 | return 0; |
| @@ -152,13 +120,11 @@ static int io_gc (lua_State *L) { · 1 unmodified line | ||
| 152 | 120 | |
| 153 | 121 | |
| 154 | 122 | static int io_tostring (lua_State *L) { |
| 155 | − char buff[4*sizeof(void *) + 2]; /* enough space for a `%p' */ | |
| 156 | − FILE **f = topfile(L, 1); | |
| 157 | − if (*f == NULL) | |
| 158 | − strcpy(buff, "closed"); | |
| 123 | + FILE *f = *topfile(L); | |
| 124 | + if (f == NULL) | |
| 125 | + lua_pushstring(L, "file (closed)"); | |
| 159 | 126 | else |
| 160 | − sprintf(buff, "%p", lua_touserdata(L, 1)); | |
| 161 | − lua_pushfstring(L, "file (%s)", buff); | |
| 127 | + lua_pushfstring(L, "file (%p)", f); | |
| 162 | 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 | 141 | static int io_tmpfile (lua_State *L) { |
| 190 | 142 | FILE **pf = newfile(L); |
| 191 | 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) { | |
| 197 | − lua_rawgeti(L, lua_upvalueindex(1), f); | |
| 198 | − return tofile(L, -1); | |
| 148 | +static FILE *getiofile (lua_State *L, int findex) { | |
| 149 | + FILE *f; | |
| 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 | 162 | if (filename) { |
| 206 | 163 | FILE **pf = newfile(L); |
| 207 | 164 | *pf = fopen(filename, mode); |
| 208 | − if (*pf == NULL) { | |
| 209 | − lua_pushfstring(L, "%s: %s", filename, strerror(errno)); | |
| 210 | − luaL_argerror(L, 1, lua_tostring(L, -1)); | |
| 211 | − } | |
| 165 | + if (*pf == NULL) | |
| 166 | + fileerror(L, 1, filename); | |
| 212 | 167 | } |
| 213 | 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 | 170 | lua_pushvalue(L, 1); |
| 216 | 171 | } |
| 172 | + lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE)); | |
| 217 | 173 | lua_rawseti(L, lua_upvalueindex(1), f); |
| 218 | 174 | } |
| 219 | 175 | /* return current value */ |
| @@ -236,7 +192,7 @@ static int io_readline (lua_State *L); · 16 unmodified lines | ||
| 236 | 192 | |
| 237 | 193 | |
| 238 | 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 | 196 | lua_pushvalue(L, idx); |
| 241 | 197 | lua_pushboolean(L, close); /* close/not close file when finished */ |
| 242 | 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 | 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 | 204 | aux_lines(L, 1, 0); |
| 249 | 205 | return 1; |
| 250 | 206 | } |
| @@ -260,7 +216,8 @@ static int io_lines (lua_State *L) { · 9 unmodified lines | ||
| 260 | 216 | const char *filename = luaL_checkstring(L, 1); |
| 261 | 217 | FILE **pf = newfile(L); |
| 262 | 218 | *pf = fopen(filename, "r"); |
| 263 | − luaL_argcheck(L, *pf, 1, strerror(errno)); | |
| 219 | + if (*pf == NULL) | |
| 220 | + fileerror(L, 1, filename); | |
| 264 | 221 | aux_lines(L, lua_gettop(L), 1); |
| 265 | 222 | return 1; |
| 266 | 223 | } |
| @@ -336,6 +293,7 @@ static int g_read (lua_State *L, FILE *f, int first) { · 69 unmodified lines | ||
| 336 | 293 | int nargs = lua_gettop(L) - 1; |
| 337 | 294 | int success; |
| 338 | 295 | int n; |
| 296 | + clearerr(f); | |
| 339 | 297 | if (nargs == 0) { /* no arguments? */ |
| 340 | 298 | success = read_line(L, f); |
| 341 | 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 | 333 | if (!success) { |
| 374 | 334 | lua_pop(L, 1); /* remove last result */ |
| 375 | 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 | 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 | 351 | static int io_readline (lua_State *L) { |
| 392 | 352 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2)); |
| 353 | + int sucess; | |
| 393 | 354 | if (f == NULL) /* file is already closed? */ |
| 394 | 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 | 360 | else { /* EOF */ |
| 397 | 361 | if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ |
| 398 | 362 | lua_settop(L, 0); |
| @@ -431,14 +395,14 @@ static int io_write (lua_State *L) { · 32 unmodified lines | ||
| 431 | 395 | |
| 432 | 396 | |
| 433 | 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 | 402 | static int f_seek (lua_State *L) { |
| 439 | 403 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; |
| 440 | 404 | static const char *const modenames[] = {"set", "cur", "end", NULL}; |
| 441 | − FILE *f = tofile(L, 1); | |
| 405 | + FILE *f = tofile(L); | |
| 442 | 406 | int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames); |
| 443 | 407 | lua_Integer offset = luaL_optinteger(L, 3, 0); |
| 444 | 408 | luaL_argcheck(L, op != -1, 2, "invalid mode"); |
| @@ -455,7 +419,7 @@ static int f_seek (lua_State *L) { · 10 unmodified lines | ||
| 455 | 419 | static int f_setvbuf (lua_State *L) { |
| 456 | 420 | static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; |
| 457 | 421 | static const char *const modenames[] = {"no", "full", "line", NULL}; |
| 458 | − FILE *f = tofile(L, 1); | |
| 422 | + FILE *f = tofile(L); | |
| 459 | 423 | int op = luaL_findstring(luaL_checkstring(L, 2), modenames); |
| 460 | 424 | luaL_argcheck(L, op != -1, 2, "invalid mode"); |
| 461 | 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 | 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 | 444 | {"close", io_close}, |
| 481 | 445 | {"flush", io_flush}, |
| 482 | 446 | {"open", io_open}, |
| 483 | − {"popen", io_popen}, | |
| 484 | 447 | {"read", io_read}, |
| 485 | 448 | {"tmpfile", io_tmpfile}, |
| 486 | 449 | {"type", io_type}, |
| @@ -504,239 +467,36 @@ static const luaL_reg flib[] = { · 17 unmodified lines | ||
| 504 | 467 | |
| 505 | 468 | |
| 506 | 469 | static void createmeta (lua_State *L) { |
| 507 | − luaL_newmetatable(L, FILEHANDLE); /* create new 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 */ | |
| 470 | + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ | |
| 514 | 471 | lua_pushvalue(L, -1); /* push metatable */ |
| 515 | 472 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ |
| 516 | − luaL_openlib(L, NULL, flib, 0); | |
| 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 | |
| 473 | + luaL_openlib(L, NULL, flib, 0); /* file methods */ | |
| 558 | 474 | } |
| 559 | 475 | |
| 560 | 476 | |
| 561 | −static int io_getenv (lua_State *L) { | |
| 562 | − lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ | |
| 563 | − return 1; | |
| 564 | −} | |
| 565 | − | |
| 566 | − | |
| 567 | −static int io_clock (lua_State *L) { | |
| 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 */ | |
| 477 | +static void createupval (lua_State *L) { | |
| 478 | + lua_newtable(L); | |
| 479 | + /* create (and set) default files */ | |
| 480 | + *newfile(L) = stdin; | |
| 481 | + lua_rawseti(L, -2, IO_INPUT); | |
| 482 | + *newfile(L) = stdout; | |
| 483 | + lua_rawseti(L, -2, IO_OUTPUT); | |
| 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 | 488 | LUALIB_API int luaopen_io (lua_State *L) { |
| 726 | − luaL_openlib(L, LUA_OSLIBNAME, syslib, 0); | |
| 727 | 489 | createmeta(L); |
| 490 | + createupval(L); | |
| 728 | 491 | lua_pushvalue(L, -1); |
| 729 | 492 | luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); |
| 730 | 493 | /* put predefined file handles into `io' table */ |
| 731 | − lua_pushliteral(L, "stdin"); | |
| 732 | − lua_rawgeti(L, 2, IO_INPUT); | |
| 733 | − lua_rawset(L, 3); | |
| 734 | − lua_pushliteral(L, "stdout"); | |
| 735 | − lua_rawgeti(L, 2, IO_OUTPUT); | |
| 736 | − lua_rawset(L, 3); | |
| 737 | − lua_pushliteral(L, "stderr"); | |
| 494 | + lua_rawgeti(L, -2, IO_INPUT); /* get current input from metatable */ | |
| 495 | + lua_setfield(L, -2, "stdin"); /* io.stdin = metatable[IO_INPUT] */ | |
| 496 | + lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from metatable */ | |
| 497 | + lua_setfield(L, -2, "stdout"); /* io.stdout = metatable[IO_OUTPUT] */ | |
| 738 | 498 | *newfile(L) = stderr; |
| 739 | − lua_rawset(L, 3); | |
| 499 | + lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */ | |
| 740 | 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 | 3 | ** Standard mathematical library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -9,6 +9,7 @@ · 3 unmodified lines | ||
| 9 | 9 | #include <math.h> |
| 10 | 10 | |
| 11 | 11 | #define lmathlib_c |
| 12 | +#define LUA_LIB | |
| 12 | 13 | |
| 13 | 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 | 26 | static int math_abs (lua_State *L) { |
| 39 | 27 | lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); |
| 40 | 28 | return 1; |
| 41 | 29 | } |
| 42 | 30 | |
| 43 | 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 | 33 | return 1; |
| 46 | 34 | } |
| 47 | 35 | |
| 48 | 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 | 38 | return 1; |
| 51 | 39 | } |
| 52 | 40 | |
| 53 | 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 | 43 | return 1; |
| 56 | 44 | } |
| 57 | 45 | |
| 58 | 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 | 48 | return 1; |
| 61 | 49 | } |
| 62 | 50 | |
| 63 | 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 | 53 | return 1; |
| 66 | 54 | } |
| 67 | 55 | |
| 68 | 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 | 58 | return 1; |
| 71 | 59 | } |
| 72 | 60 | |
| 73 | 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 | 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 | 3 | ** Dynamic library loader for Lua |
| 4 | 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 | 32 | #include "lua.h" |
| 30 | 33 | #include "lauxlib.h" |
| 31 | 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 | 3 | ** Standard library for string operations and pattern-matching |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -12,6 +12,7 @@ · 6 unmodified lines | ||
| 12 | 12 | #include <string.h> |
| 13 | 13 | |
| 14 | 14 | #define lstrlib_c |
| 15 | +#define LUA_LIB | |
| 15 | 16 | |
| 16 | 17 | #include "lua.h" |
| 17 | 18 | |
| @@ -20,9 +21,7 @@ · 2 unmodified lines | ||
| 20 | 21 | |
| 21 | 22 | |
| 22 | 23 | /* macro to `unsign' a character */ |
| 23 | −#ifndef uchar | |
| 24 | 24 | #define uchar(c) ((unsigned char)(c)) |
| 25 | −#endif | |
| 26 | 25 | |
| 27 | 26 | |
| 28 | 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 | 107 | static int str_byte (lua_State *L) { |
| 109 | 108 | size_t l; |
| 110 | 109 | const char *s = luaL_checklstring(L, 1, &l); |
| 111 | − sint32 pos = posrelat(luaL_optinteger(L, 2, 1), l); | |
| 112 | − if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */ | |
| 113 | − return 0; /* no answer */ | |
| 114 | − lua_pushinteger(L, uchar(s[pos-1])); | |
| 115 | − return 1; | |
| 110 | + sint32 posi = posrelat(luaL_optinteger(L, 2, 1), l); | |
| 111 | + sint32 pose = posrelat(luaL_optinteger(L, 3, posi), l); | |
| 112 | + int n, i; | |
| 113 | + if (posi <= 0) posi = 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 | 139 | static int writer (lua_State *L, const void* b, size_t size, void* B) { |
| 135 | 140 | (void)L; |
| 136 | 141 | luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); |
| 137 | − return 1; | |
| 142 | + return 0; | |
| 138 | 143 | } |
| 139 | 144 | |
| 140 | 145 | |
| 141 | 146 | static int str_dump (lua_State *L) { |
| 142 | 147 | luaL_Buffer b; |
| 143 | 148 | luaL_checktype(L, 1, LUA_TFUNCTION); |
| 149 | + lua_settop(L, 1); | |
| 144 | 150 | luaL_buffinit(L,&b); |
| 145 | − if (!lua_dump(L, writer, &b)) | |
| 151 | + if (lua_dump(L, writer, &b) != 0) | |
| 146 | 152 | luaL_error(L, "unable to dump given function"); |
| 147 | 153 | luaL_pushresult(&b); |
| 148 | 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 | 166 | #define CAP_UNFINISHED (-1) |
| 165 | 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 | 3 | ** Library for Table Manipulation |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stddef.h> |
| 9 | 9 | |
| 10 | 10 | #define ltablib_c |
| 11 | +#define LUA_LIB | |
| 11 | 12 | |
| 12 | 13 | #include "lua.h" |
| 13 | 14 | |
| @@ -22,7 +23,7 @@ static int luaB_foreachi (lua_State *L) { · 8 unmodified lines | ||
| 22 | 23 | int i; |
| 23 | 24 | int n = aux_getn(L, 1); |
| 24 | 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 | 27 | lua_pushvalue(L, 2); /* function */ |
| 27 | 28 | lua_pushinteger(L, i); /* 1st argument */ |
| 28 | 29 | lua_rawgeti(L, 1, i); /* 2nd argument */ |
| @@ -62,25 +63,26 @@ static int luaB_getn (lua_State *L) { · 33 unmodified lines | ||
| 62 | 63 | static int luaB_setn (lua_State *L) { |
| 63 | 64 | luaL_checktype(L, 1, LUA_TTABLE); |
| 64 | 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 | 71 | static int luaB_tinsert (lua_State *L) { |
| 70 | 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 | 74 | int pos; /* where to insert new element */ |
| 73 | 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 | 77 | else { |
| 76 | 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 | 80 | v = 3; /* function may be called with more than 3 args */ |
| 79 | 81 | } |
| 80 | − luaL_setn(L, 1, n); /* new size */ | |
| 81 | − while (--n >= pos) { /* move up elements */ | |
| 82 | − lua_rawgeti(L, 1, n); | |
| 83 | − lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ | |
| 82 | + luaL_setn(L, 1, e - LUA_FIRSTINDEX + 1); /* new size */ | |
| 83 | + while (--e >= pos) { /* move up elements */ | |
| 84 | + lua_rawgeti(L, 1, e); | |
| 85 | + lua_rawseti(L, 1, e+1); /* t[e+1] = t[e] */ | |
| 84 | 86 | } |
| 85 | 87 | lua_pushvalue(L, v); |
| 86 | 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 | 93 | static int luaB_tremove (lua_State *L) { |
| 92 | − int n = aux_getn(L, 1); | |
| 93 | − int pos = luaL_optint(L, 2, n); | |
| 94 | − if (n <= 0) return 0; /* table is `empty' */ | |
| 95 | − luaL_setn(L, 1, n-1); /* t.n = n-1 */ | |
| 94 | + int e = aux_getn(L, 1) + LUA_FIRSTINDEX - 1; | |
| 95 | + int pos = luaL_optint(L, 2, e); | |
| 96 | + if (e < LUA_FIRSTINDEX) return 0; /* table is `empty' */ | |
| 97 | + luaL_setn(L, 1, e - LUA_FIRSTINDEX); /* t.n = n-1 */ | |
| 96 | 98 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ |
| 97 | − for ( ;pos<n; pos++) { | |
| 99 | + for ( ;pos<e; pos++) { | |
| 98 | 100 | lua_rawgeti(L, 1, pos+1); |
| 99 | 101 | lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ |
| 100 | 102 | } |
| 101 | 103 | lua_pushnil(L); |
| 102 | − lua_rawseti(L, 1, n); /* t[n] = nil */ | |
| 104 | + lua_rawseti(L, 1, e); /* t[e] = nil */ | |
| 103 | 105 | return 1; |
| 104 | 106 | } |
| 105 | 107 | |
| @@ -108,16 +110,17 @@ static int str_concat (lua_State *L) { · 2 unmodified lines | ||
| 108 | 110 | luaL_Buffer b; |
| 109 | 111 | size_t lsep; |
| 110 | 112 | const char *sep = luaL_optlstring(L, 2, "", &lsep); |
| 111 | − int i = luaL_optint(L, 3, 1); | |
| 112 | − int n = luaL_optint(L, 4, 0); | |
| 113 | + int i = luaL_optint(L, 3, LUA_FIRSTINDEX); | |
| 114 | + int last = luaL_optint(L, 4, -2); | |
| 113 | 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 | 118 | luaL_buffinit(L, &b); |
| 116 | − for (; i <= n; i++) { | |
| 119 | + for (; i <= last; i++) { | |
| 117 | 120 | lua_rawgeti(L, 1, i); |
| 118 | 121 | luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings"); |
| 119 | 122 | luaL_addvalue(&b); |
| 120 | − if (i != n) | |
| 123 | + if (i != last) | |
| 121 | 124 | luaL_addlstring(&b, sep, lsep); |
| 122 | 125 | } |
| 123 | 126 | luaL_pushresult(&b); |
| @@ -223,7 +226,7 @@ static int luaB_sort (lua_State *L) { · 99 unmodified lines | ||
| 223 | 226 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ |
| 224 | 227 | luaL_checktype(L, 2, LUA_TFUNCTION); |
| 225 | 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 | 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 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -9,6 +9,7 @@ · 3 unmodified lines | ||
| 9 | 9 | #include <string.h> |
| 10 | 10 | |
| 11 | 11 | #define llex_c |
| 12 | +#define LUA_CORE | |
| 12 | 13 | |
| 13 | 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 | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -15,48 +15,9 @@ · 9 unmodified lines | ||
| 15 | 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 | 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 | 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 | 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 | 59 | typedef LUSER_ALIGNMENT_T L_Umaxalign; |
| 102 | −#endif | |
| 103 | 60 | |
| 104 | 61 | |
| 105 | −/* result of `usual argument conversion' over lua_Number */ | |
| 106 | −#ifndef LUA_UACNUMBER | |
| 107 | −typedef double l_uacNumber; | |
| 108 | −#else | |
| 62 | +/* result of a `usual argument conversion' over lua_Number */ | |
| 109 | 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 | 66 | #ifndef check_exp |
| @@ -138,43 +86,11 @@ typedef LUA_UACNUMBER l_uacNumber; · 19 unmodified lines | ||
| 138 | 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 | 90 | /* maximum stack for a Lua function */ |
| 164 | 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 | 95 | /* minimum size for the string table (must be power of 2) */ |
| 180 | 96 | #ifndef MINSTRTABSIZE |
| @@ -188,13 +104,4 @@ typedef lu_int32 Instruction; · 7 unmodified lines | ||
| 188 | 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 | 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 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stddef.h> |
| 9 | 9 | |
| 10 | 10 | #define lmem_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 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 | 77 | if (block == NULL && nsize > 0) |
| 77 | 78 | luaD_throw(L, LUA_ERRMEM); |
| 78 | 79 | lua_assert((nsize == 0) == (block == NULL)); |
| 79 | − g->nblocks -= osize; | |
| 80 | − g->nblocks += nsize; | |
| 80 | + g->totalbytes = (g->totalbytes - osize) + nsize; | |
| 81 | 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 | 3 | ** Some generic functions over Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -10,6 +10,7 @@ · 4 unmodified lines | ||
| 10 | 10 | #include <string.h> |
| 11 | 11 | |
| 12 | 12 | #define lobject_c |
| 13 | +#define LUA_CORE | |
| 13 | 14 | |
| 14 | 15 | #include "lua.h" |
| 15 | 16 | |
| @@ -21,11 +22,6 @@ · 5 unmodified lines | ||
| 21 | 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 | 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 | 98 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 103 | 99 | int n = 1; |
| 104 | 100 | pushstr(L, ""); |
| @@ -108,9 +104,10 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 3 unmodified lines | ||
| 108 | 104 | setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); |
| 109 | 105 | incr_top(L); |
| 110 | 106 | switch (*(e+1)) { |
| 111 | − case 's': | |
| 107 | + case 's': { | |
| 112 | 108 | pushstr(L, va_arg(argp, char *)); |
| 113 | 109 | break; |
| 110 | + } | |
| 114 | 111 | case 'c': { |
| 115 | 112 | char buff[2]; |
| 116 | 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 | 115 | pushstr(L, buff); |
| 119 | 116 | break; |
| 120 | 117 | } |
| 121 | − case 'd': | |
| 118 | + case 'd': { | |
| 122 | 119 | setnvalue(L->top, cast(lua_Number, va_arg(argp, int))); |
| 123 | 120 | incr_top(L); |
| 124 | 121 | break; |
| 125 | − case 'f': | |
| 122 | + } | |
| 123 | + case 'f': { | |
| 126 | 124 | setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber))); |
| 127 | 125 | incr_top(L); |
| 128 | 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 | 135 | pushstr(L, "%"); |
| 131 | 136 | break; |
| 137 | + } | |
| 132 | 138 | default: { |
| 133 | 139 | char buff[3]; |
| 134 | 140 | buff[0] = '%'; |
| @@ -177,7 +183,7 @@ void luaO_chunkid (char *out, const char *source, int bufflen) { · 42 unmodified lines | ||
| 177 | 183 | strcat(out, source); |
| 178 | 184 | } |
| 179 | 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 | 187 | bufflen -= sizeof(" [string \"...\"] "); |
| 182 | 188 | if (len > bufflen) len = bufflen; |
| 183 | 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 | 3 | ** Type definitions for Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -249,6 +249,10 @@ typedef struct Proto { · 243 unmodified lines | ||
| 249 | 249 | } Proto; |
| 250 | 250 | |
| 251 | 251 | |
| 252 | +/* mask for new-style vararg */ | |
| 253 | +#define NEWSTYLEVARARG 2 | |
| 254 | + | |
| 255 | + | |
| 252 | 256 | typedef struct LocVar { |
| 253 | 257 | TString *varname; |
| 254 | 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 | 3 | ** See Copyright Notice in lua.h |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | |
| 7 | 7 | #define lopcodes_c |
| 8 | +#define LUA_CORE | |
| 8 | 9 | |
| 9 | 10 | #include "lua.h" |
| 10 | 11 | |
| @@ -14,8 +15,6 @@ · 3 unmodified lines | ||
| 14 | 15 | |
| 15 | 16 | /* ORDER OP */ |
| 16 | 17 | |
| 17 | −#ifdef LUA_OPNAMES | |
| 18 | − | |
| 19 | 18 | const char *const luaP_opnames[NUM_OPCODES] = { |
| 20 | 19 | "MOVE", |
| 21 | 20 | "LOADK", |
| @@ -52,10 +51,10 @@ const char *const luaP_opnames[NUM_OPCODES] = { · 30 unmodified lines | ||
| 52 | 51 | "SETLIST", |
| 53 | 52 | "SETLISTO", |
| 54 | 53 | "CLOSE", |
| 55 | − "CLOSURE" | |
| 54 | + "CLOSURE", | |
| 55 | + "VARARG" | |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | −#endif | |
| 59 | 58 | |
| 60 | 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 | 96 | ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */ |
| 98 | 97 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ |
| 99 | 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 | 3 | ** Opcodes for Lua virtual machine |
| 4 | 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 | 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 | 47 | #define POS_B (POS_C + SIZE_C) |
| 46 | 48 | #define POS_Bx POS_C |
| 47 | −#define POS_A (POS_B + SIZE_B) | |
| 48 | 49 | |
| 49 | 50 | |
| 50 | 51 | /* |
| 51 | 52 | ** limits for opcode arguments. |
| 52 | 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 | 57 | #define MAXARG_Bx ((1<<SIZE_Bx)-1) |
| 57 | 58 | #define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */ |
| 58 | 59 | #else |
| @@ -76,10 +77,11 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ · 17 unmodified lines | ||
| 76 | 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 SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o))) | |
| 80 | +#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) | |
| 81 | +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ | |
| 82 | + ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP)))) | |
| 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 | 85 | #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ |
| 84 | 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 | 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 | 105 | | (cast(Instruction, a)<<POS_A) \ |
| 104 | 106 | | (cast(Instruction, b)<<POS_B) \ |
| 105 | 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 | 110 | | (cast(Instruction, a)<<POS_A) \ |
| 109 | 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 | 140 | ** R(x) - register |
| 122 | 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 | 202 | OP_SETLISTO,/* A Bx */ |
| 184 | 203 | |
| 185 | 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 | 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 | 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 | 218 | and can be 0: OP_CALL then sets `top' to last_result+1, so |
| 198 | 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 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <string.h> |
| 9 | 9 | |
| 10 | 10 | #define lparser_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 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 | 32 | #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) |
| 30 | 33 | |
| 31 | 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 | 274 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { |
| 272 | 275 | FuncState *fs = ls->fs; |
| 273 | 276 | int extra = nvars - nexps; |
| 274 | − if (e->k == VCALL) { | |
| 277 | + if (hasmultret(e->k)) { | |
| 275 | 278 | extra++; /* includes call itself */ |
| 276 | − if (extra <= 0) extra = 0; | |
| 277 | − else luaK_reserveregs(fs, extra-1); | |
| 278 | − luaK_setcallreturns(fs, e, extra); /* call provides the difference */ | |
| 279 | + if (extra < 0) extra = 0; | |
| 280 | + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ | |
| 281 | + if (extra > 1) luaK_reserveregs(fs, extra-1); | |
| 279 | 282 | } |
| 280 | 283 | else { |
| 281 | 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 | 394 | lexstate.nestlevel = 0; |
| 392 | 395 | luaX_setinput(L, &lexstate, z, luaS_new(L, name)); |
| 393 | 396 | open_func(&lexstate, &funcstate); |
| 397 | + funcstate.f->is_vararg = NEWSTYLEVARARG; | |
| 394 | 398 | next(&lexstate); /* read first token */ |
| 395 | 399 | chunk(&lexstate); |
| 396 | 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 | 485 | static void lastlistfield (FuncState *fs, struct ConsControl *cc) { |
| 482 | 486 | if (cc->tostore == 0) return; |
| 483 | − if (cc->v.k == VCALL) { | |
| 484 | − luaK_setcallreturns(fs, &cc->v, LUA_MULTRET); | |
| 487 | + if (hasmultret(cc->v.k)) { | |
| 488 | + luaK_setmultret(fs, &cc->v); | |
| 485 | 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 | 492 | else { |
| 488 | 493 | if (cc->v.k != VVOID) |
| @@ -556,12 +561,8 @@ static void parlist (LexState *ls) { · 67 unmodified lines | ||
| 556 | 561 | if (ls->t.token != ')') { /* is `parlist' not empty? */ |
| 557 | 562 | do { |
| 558 | 563 | switch (ls->t.token) { |
| 559 | − case TK_NAME: { /* param -> NAME [ `=' `...' ] */ | |
| 564 | + case TK_NAME: { /* param -> NAME */ | |
| 560 | 565 | new_localvar(ls, str_checkname(ls), nparams++); |
| 561 | − if (testnext(ls, '=')) { | |
| 562 | − check(ls, TK_DOTS); | |
| 563 | − f->is_vararg = 1; | |
| 564 | − } | |
| 565 | 566 | break; |
| 566 | 567 | } |
| 567 | 568 | case TK_DOTS: { /* param -> `...' */ |
| @@ -627,7 +628,7 @@ static void funcargs (LexState *ls, expdesc *f) { · 59 unmodified lines | ||
| 627 | 628 | args.k = VVOID; |
| 628 | 629 | else { |
| 629 | 630 | explist1(ls, &args); |
| 630 | − luaK_setcallreturns(fs, &args, LUA_MULTRET); | |
| 631 | + luaK_setmultret(fs, &args); | |
| 631 | 632 | } |
| 632 | 633 | check_match(ls, ')', '(', line); |
| 633 | 634 | break; |
| @@ -648,7 +649,7 @@ static void funcargs (LexState *ls, expdesc *f) { · 14 unmodified lines | ||
| 648 | 649 | } |
| 649 | 650 | lua_assert(f->k == VNONRELOC); |
| 650 | 651 | base = f->info; /* base register for call */ |
| 651 | − if (args.k == VCALL) | |
| 652 | + if (hasmultret(args.k)) | |
| 652 | 653 | nparams = LUA_MULTRET; /* open call */ |
| 653 | 654 | else { |
| 654 | 655 | if (args.k != VVOID) |
| @@ -737,43 +738,47 @@ static void simpleexp (LexState *ls, expdesc *v) { · 82 unmodified lines | ||
| 737 | 738 | switch (ls->t.token) { |
| 738 | 739 | case TK_NUMBER: { |
| 739 | 740 | init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); |
| 740 | − next(ls); /* must use `seminfo' before `next' */ | |
| 741 | 741 | break; |
| 742 | 742 | } |
| 743 | 743 | case TK_STRING: { |
| 744 | 744 | codestring(ls, v, ls->t.seminfo.ts); |
| 745 | − next(ls); /* must use `seminfo' before `next' */ | |
| 746 | 745 | break; |
| 747 | 746 | } |
| 748 | 747 | case TK_NIL: { |
| 749 | 748 | init_exp(v, VNIL, 0); |
| 750 | − next(ls); | |
| 751 | 749 | break; |
| 752 | 750 | } |
| 753 | 751 | case TK_TRUE: { |
| 754 | 752 | init_exp(v, VTRUE, 0); |
| 755 | − next(ls); | |
| 756 | 753 | break; |
| 757 | 754 | } |
| 758 | 755 | case TK_FALSE: { |
| 759 | 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 | 765 | break; |
| 762 | 766 | } |
| 763 | 767 | case '{': { /* constructor */ |
| 764 | 768 | constructor(ls, v); |
| 765 | − break; | |
| 769 | + return; | |
| 766 | 770 | } |
| 767 | 771 | case TK_FUNCTION: { |
| 768 | 772 | next(ls); |
| 769 | 773 | body(ls, v, 0, ls->linenumber); |
| 770 | − break; | |
| 774 | + return; | |
| 771 | 775 | } |
| 772 | 776 | default: { |
| 773 | 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 | 955 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ |
| 951 | 956 | } |
| 952 | 957 | else { |
| 953 | − luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */ | |
| 958 | + luaK_setoneret(ls->fs, &e); /* close last expression */ | |
| 954 | 959 | luaK_storevar(ls->fs, &lh->v, &e); |
| 955 | 960 | return; /* avoid default */ |
| 956 | 961 | } |
| @@ -976,12 +981,6 @@ static int cond (LexState *ls) { · 19 unmodified lines | ||
| 976 | 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 | 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 | 1239 | FuncState *fs = ls->fs; |
| 1241 | 1240 | struct LHS_assign v; |
| 1242 | 1241 | primaryexp(ls, &v.v); |
| 1243 | − if (v.v.k == VCALL) { /* stat -> func */ | |
| 1244 | − luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ | |
| 1245 | − } | |
| 1242 | + if (v.v.k == VCALL) /* stat -> func */ | |
| 1243 | + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ | |
| 1246 | 1244 | else { /* stat -> assignment */ |
| 1247 | 1245 | v.prev = NULL; |
| 1248 | 1246 | assignment(ls, &v, 1); |
| @@ -1260,9 +1258,9 @@ static void retstat (LexState *ls) { · 11 unmodified lines | ||
| 1260 | 1258 | first = nret = 0; /* return no values */ |
| 1261 | 1259 | else { |
| 1262 | 1260 | nret = explist1(ls, &e); /* optional return values */ |
| 1263 | − if (e.k == VCALL) { | |
| 1264 | − luaK_setcallreturns(fs, &e, LUA_MULTRET); | |
| 1265 | − if (nret == 1) { /* tail call? */ | |
| 1261 | + if (hasmultret(e.k)) { | |
| 1262 | + luaK_setmultret(fs, &e); | |
| 1263 | + if (e.k == VCALL && nret == 1) { /* tail call? */ | |
| 1266 | 1264 | SET_OPCODE(getcode(fs,&e), OP_TAILCALL); |
| 1267 | 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 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -30,7 +30,8 @@ typedef enum { · 24 unmodified lines | ||
| 30 | 30 | VJMP, /* info = instruction pc */ |
| 31 | 31 | VRELOCABLE, /* info = instruction pc */ |
| 32 | 32 | VNONRELOC, /* info = result register */ |
| 33 | − VCALL /* info = result register */ | |
| 33 | + VCALL, /* info = instruction pc */ | |
| 34 | + VVARARG /* info = instruction pc */ | |
| 34 | 35 | } expkind; |
| 35 | 36 | |
| 36 | 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 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stddef.h> |
| 9 | 9 | |
| 10 | 10 | #define lstate_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 13 | #include "lua.h" |
| 13 | 14 | |
| @@ -56,6 +57,7 @@ static void stack_init (lua_State *L1, lua_State *L) { · 42 unmodified lines | ||
| 56 | 57 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; |
| 57 | 58 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); |
| 58 | 59 | L1->ci = L1->base_ci; |
| 60 | + L1->ci->func = L1->top; | |
| 59 | 61 | setnilvalue(L1->top++); /* `function' entry for this `ci' */ |
| 60 | 62 | L1->base = L1->ci->base = L1->top; |
| 61 | 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 | 78 | static void f_luaopen (lua_State *L, void *ud) { |
| 77 | 79 | Udata *u; /* head of udata list */ |
| 80 | + global_State *g = G(L); | |
| 78 | 81 | UNUSED(ud); |
| 79 | 82 | u = cast(Udata *, luaM_malloc(L, sizeudata(0))); |
| 80 | 83 | u->uv.len = 0; |
| 81 | 84 | u->uv.metatable = NULL; |
| 82 | − G(L)->firstudata = obj2gco(u); | |
| 85 | + g->firstudata = obj2gco(u); | |
| 83 | 86 | luaC_link(L, obj2gco(u), LUA_TUSERDATA); |
| 84 | 87 | setbit(u->uv.marked, FIXEDBIT); |
| 85 | 88 | setbit(L->marked, FIXEDBIT); |
| 86 | 89 | stack_init(L, L); /* init stack */ |
| 87 | 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 | 92 | sethvalue(L, registry(L), luaH_new(L, 4, 4)); /* registry */ |
| 89 | 93 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ |
| 90 | 94 | luaT_init(L); |
| 91 | 95 | luaX_init(L); |
| 92 | 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 | 124 | static void close_state (lua_State *L) { |
| 120 | 125 | global_State *g = G(L); |
| 121 | 126 | luaF_close(L, L->stack); /* close all upvalues for this thread */ |
| 122 | − luaC_sweepall(L); /* collect all elements */ | |
| 123 | − lua_assert(g->rootgc == obj2gco(L)); | |
| 124 | − luaS_freeall(L); | |
| 127 | + luaC_freeall(L); /* collect all objects */ | |
| 128 | + lua_assert(g->rootgc == NULL); | |
| 129 | + lua_assert(g->strt.nuse == 0); | |
| 130 | + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); | |
| 125 | 131 | luaZ_freebuffer(L, &g->buff); |
| 126 | 132 | freestack(L, L); |
| 127 | − lua_assert(g->nblocks == sizeof(LG)); | |
| 133 | + lua_assert(g->totalbytes == sizeof(LG)); | |
| 128 | 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 | 142 | preinit_state(L1, G(L)); |
| 137 | 143 | stack_init(L1, L); /* init stack */ |
| 138 | 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 | 149 | lua_assert(iswhite(obj2gco(L1))); |
| 140 | 150 | return L1; |
| 141 | 151 | } |
| @@ -169,7 +179,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 27 unmodified lines | ||
| 169 | 179 | setnilvalue(registry(L)); |
| 170 | 180 | luaZ_initbuffer(L, &g->buff); |
| 171 | 181 | g->panic = NULL; |
| 172 | − g->gcstate = GCSfinalize; | |
| 182 | + g->gcstate = GCSpause; | |
| 183 | + g->gcgenerational = 0; | |
| 173 | 184 | g->rootgc = obj2gco(L); |
| 174 | 185 | g->sweepstrgc = 0; |
| 175 | 186 | g->sweepgc = &g->rootgc; |
| @@ -181,13 +192,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 5 unmodified lines | ||
| 181 | 192 | setnilvalue(gkey(g->dummynode)); |
| 182 | 193 | setnilvalue(gval(g->dummynode)); |
| 183 | 194 | g->dummynode->next = NULL; |
| 184 | − g->nblocks = sizeof(LG); | |
| 195 | + g->totalbytes = sizeof(LG); | |
| 185 | 196 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { |
| 186 | 197 | /* memory allocation error: free partial state */ |
| 187 | 198 | close_state(L); |
| 188 | 199 | L = NULL; |
| 189 | 200 | } |
| 190 | − lua_userstateopen(L); | |
| 201 | + else | |
| 202 | + lua_userstateopen(L); | |
| 191 | 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 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -14,30 +14,6 @@ · 8 unmodified lines | ||
| 14 | 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 | 18 | struct lua_longjmp; /* defined in ldo.c */ |
| 43 | 19 | |
| @@ -70,25 +46,20 @@ typedef struct stringtable { · 26 unmodified lines | ||
| 70 | 46 | ** informations about a call |
| 71 | 47 | */ |
| 72 | 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 | 51 | StkId top; /* top for this function */ |
| 75 | − union { | |
| 76 | − struct { /* for Lua functions */ | |
| 77 | − const Instruction *savedpc; | |
| 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; | |
| 52 | + int nresults; /* expected number of results from this function */ | |
| 53 | + const Instruction *savedpc; | |
| 54 | + int tailcalls; /* number of tail calls lost under this entry */ | |
| 84 | 55 | } CallInfo; |
| 85 | 56 | |
| 86 | 57 | |
| 87 | 58 | |
| 88 | −#define curr_func(L) (clvalue(L->base - 1)) | |
| 89 | −#define ci_func(ci) (clvalue((ci)->base - 1)) | |
| 59 | +#define curr_func(L) (clvalue(L->ci->func)) | |
| 60 | +#define ci_func(ci) (clvalue((ci)->func)) | |
| 90 | 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 | 69 | stringtable strt; /* hash table for strings */ |
| 99 | 70 | lua_Alloc realloc; /* function to reallocate memory */ |
| 100 | 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 | 75 | GCObject *rootgc; /* list of all collectable objects */ |
| 103 | 76 | GCObject *firstudata; /* udata go to the end of `rootgc' */ |
| 104 | 77 | GCObject **sweepgc; /* position of sweep in `rootgc' */ |
| @@ -107,10 +80,11 @@ typedef struct global_State { · 2 unmodified lines | ||
| 107 | 80 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| 108 | 81 | GCObject *weak; /* list of weak tables (to be cleared) */ |
| 109 | 82 | GCObject *tmudata; /* list of userdata to be GC */ |
| 110 | − int gcstate; /* state of garbage collector */ | |
| 111 | 83 | Mbuffer buff; /* temporary buffer for string concatentation */ |
| 112 | 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 | 88 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 115 | 89 | TValue _registry; |
| 116 | 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 | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <string.h> |
| 9 | 9 | |
| 10 | 10 | #define lstring_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 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 | 22 | void luaS_resize (lua_State *L, int newsize) { |
| 28 | 23 | GCObject **newhash; |
| 29 | 24 | stringtable *tb; |
| 30 | 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 | 28 | newhash = luaM_newvector(L, newsize, GCObject *); |
| 33 | 29 | tb = &G(L)->strt; |
| 34 | 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 | 3 | ** String table (keep all strings handled by Lua) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -26,7 +26,6 @@ · 20 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | void luaS_resize (lua_State *L, int newsize); |
| 28 | 28 | Udata *luaS_newudata (lua_State *L, size_t s); |
| 29 | −void luaS_freeall (lua_State *L); | |
| 30 | 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 | 3 | ** Lua tables (hash) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -21,6 +21,7 @@ · 15 unmodified lines | ||
| 21 | 21 | #include <string.h> |
| 22 | 22 | |
| 23 | 23 | #define ltable_c |
| 24 | +#define LUA_CORE | |
| 24 | 25 | |
| 25 | 26 | #include "lua.h" |
| 26 | 27 | |
| @@ -36,19 +37,14 @@ · 9 unmodified lines | ||
| 36 | 37 | /* |
| 37 | 38 | ** max size of array part is 2^MAXBITS |
| 38 | 39 | */ |
| 39 | −#if BITS_INT > 26 | |
| 40 | +#if LUA_BITSINT > 26 | |
| 40 | 41 | #define MAXBITS 24 |
| 41 | 42 | #else |
| 42 | −#define MAXBITS (BITS_INT-2) | |
| 43 | +#define MAXBITS (LUA_BITSINT-2) | |
| 43 | 44 | #endif |
| 44 | 45 | |
| 45 | 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 | 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 | 270 | int i; |
| 275 | 271 | int oldasize = t->sizearray; |
| 276 | 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 | 311 | static void rehash (lua_State *L, Table *t) { |
| 316 | 312 | int nasize, nhsize; |
| 317 | 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 | 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 | 377 | setobj2t(L, gkey(mp), key); |
| 402 | − luaC_barrier(L, t, key); | |
| 378 | + luaC_barriert(L, t, key); | |
| 403 | 379 | lua_assert(ttisnil(gval(mp))); |
| 404 | 380 | for (;;) { /* correct `firstfree' */ |
| 405 | 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 | 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 | 432 | const TValue *luaH_get (Table *t, const TValue *key) { |
| 472 | 433 | switch (ttype(key)) { |
| 434 | + case LUA_TNIL: return &luaO_nilobject; | |
| 473 | 435 | case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); |
| 474 | 436 | case LUA_TNUMBER: { |
| 475 | 437 | int k; |
| @@ -478,7 +440,14 @@ const TValue *luaH_get (Table *t, const TValue *key) { · 2 unmodified lines | ||
| 478 | 440 | return luaH_getnum(t, k); /* use specialized version */ |
| 479 | 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 | 3 | ** Lua tables (hash) |
| 4 | 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 | 22 | const TValue *luaH_get (Table *t, const TValue *key); |
| 23 | 23 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key); |
| 24 | 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 | 26 | void luaH_free (lua_State *L, Table *t); |
| 26 | 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 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <string.h> |
| 9 | 9 | |
| 10 | 10 | #define ltm_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 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 | 2 | It can be used as a batch interpreter and also interactively. |
| 3 | 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 | 10 | -v show version information |
| 11 | 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 | 14 | all standard libraries. For a minimal interpreter, see ../../etc/min.c. |
| 15 | 15 | |
| 16 | 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 | 3 | ** Lua stand-alone interpreter |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -26,73 +26,25 @@ · 20 unmodified lines | ||
| 26 | 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 | 33 | static const char *progname = PROGNAME; |
| 67 | 34 | |
| 68 | 35 | |
| 69 | 36 | |
| 70 | −static const luaL_reg lualibs[] = { | |
| 71 | − {"base", luaopen_base}, | |
| 72 | − {"table", luaopen_table}, | |
| 73 | − {"io", luaopen_io}, | |
| 74 | − {"string", luaopen_string}, | |
| 75 | − {"math", luaopen_math}, | |
| 76 | − {"debug", luaopen_debug}, | |
| 77 | − {"loadlib", luaopen_loadlib}, | |
| 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) { | |
| 37 | +static void lstop (lua_State *L, lua_Debug *ar) { | |
| 86 | 38 | (void)ar; /* unused arg. */ |
| 87 | − lua_sethook(l, NULL, 0, 0); | |
| 88 | − luaL_error(l, "interrupted!"); | |
| 39 | + lua_sethook(L, NULL, 0, 0); | |
| 40 | + luaL_error(L, "interrupted!"); | |
| 89 | 41 | } |
| 90 | 42 | |
| 91 | 43 | |
| 92 | 44 | static void laction (int i) { |
| 93 | 45 | signal(i, SIG_DFL); /* if another SIGINT happens before lstop, |
| 94 | 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 | 72 | if (status && !lua_isnil(L, -1)) { |
| 121 | 73 | const char *msg = lua_tostring(L, -1); |
| 122 | 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 | 83 | int status; |
| 132 | 84 | int base = lua_gettop(L) - narg; /* function index */ |
| 133 | 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) { | |
| 150 | − int i; | |
| 101 | +static int getargs (lua_State *L, char *argv[], int n) { | |
| 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 | 108 | lua_newtable(L); |
| 152 | 109 | for (i=0; argv[i]; i++) { |
| 153 | − lua_pushnumber(L, i - n); | |
| 154 | 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) { | |
| 161 | − if (status == 0) status = lcall(0, 1); | |
| 162 | − return report(status); | |
| 163 | −} | |
| 164 | − | |
| 165 | − | |
| 166 | −static int file_input (const char *name) { | |
| 167 | − return docall(luaL_loadfile(L, name)); | |
| 117 | +static int dofile (lua_State *L, const char *name) { | |
| 118 | + int status = luaL_loadfile(L, name) || docall(L, 0, 1); | |
| 119 | + return report(L, status); | |
| 168 | 120 | } |
| 169 | 121 | |
| 170 | 122 | |
| 171 | −static int dostring (const char *s, const char *name) { | |
| 172 | − return docall(luaL_loadbuffer(L, s, strlen(s), name)); | |
| 123 | +static int dostring (lua_State *L, const char *s, const char *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) { | |
| 177 | − lua_pushliteral(L, "require"); | |
| 178 | − lua_rawget(L, LUA_GLOBALSINDEX); | |
| 179 | − if (!lua_isfunction(L, -1)) { /* no `require' defined? */ | |
| 180 | − lua_pop(L, 1); | |
| 181 | − return file_input(name); | |
| 182 | − } | |
| 183 | − else { | |
| 184 | − lua_pushstring(L, name); | |
| 185 | − return report(lcall(1, 1)); | |
| 129 | +static int dolibrary (lua_State *L, const char *name) { | |
| 130 | + lua_getfield(L, LUA_GLOBALSINDEX, "_PATH"); | |
| 131 | + if (!lua_isstring(L, -1)) { | |
| 132 | + l_message(progname, "global _PATH must be a string"); | |
| 133 | + return 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 | 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 | 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 | 156 | static char buffer[MAXINPUT]; |
| 214 | 157 | if (prompt) { |
| 215 | 158 | fputs(prompt, stdout); |
| @@ -218,7 +161,7 @@ static int readline (lua_State *l, const char *prompt) { · 2 unmodified lines | ||
| 218 | 161 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) |
| 219 | 162 | return 0; /* read fails */ |
| 220 | 163 | else { |
| 221 | − lua_pushstring(l, buffer); | |
| 164 | + lua_pushstring(L, buffer); | |
| 222 | 165 | return 1; |
| 223 | 166 | } |
| 224 | 167 | } |
| @@ -226,7 +169,7 @@ static int readline (lua_State *l, const char *prompt) { · 1 unmodified line | ||
| 226 | 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 | 173 | const char *p = NULL; |
| 231 | 174 | lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2"); |
| 232 | 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 | 184 | if (status == LUA_ERRSYNTAX && |
| 242 | 185 | strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) { |
| 243 | 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 | 195 | int status; |
| 253 | 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 | 198 | return -1; |
| 256 | 199 | if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ |
| 257 | 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 | 203 | for (;;) { /* repeat until gets a complete line */ |
| 261 | 204 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); |
| 262 | − if (!incomplete(status)) break; /* cannot try to add lines? */ | |
| 263 | − if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */ | |
| 205 | + if (!incomplete(L, status)) break; /* cannot try to add lines? */ | |
| 206 | + if (lua_readline(L, get_prompt(L, 0)) == 0) /* no more input? */ | |
| 264 | 207 | return -1; |
| 265 | 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 | 217 | int status; |
| 275 | 218 | const char *oldprogname = progname; |
| 276 | 219 | progname = NULL; |
| 277 | − while ((status = load_string()) != -1) { | |
| 278 | − if (status == 0) status = lcall(0, 0); | |
| 279 | − report(status); | |
| 220 | + print_version(); | |
| 221 | + while ((status = loadline(L)) != -1) { | |
| 222 | + if (status == 0) status = docall(L, 0, 0); | |
| 223 | + report(L, status); | |
| 280 | 224 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ |
| 281 | 225 | lua_getglobal(L, "print"); |
| 282 | 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) { | |
| 295 | − if (argv[1] == NULL) { /* no more arguments? */ | |
| 296 | − if (stdin_is_tty()) { | |
| 297 | − print_version(); | |
| 298 | − manual_input(); | |
| 299 | − } | |
| 238 | +static int checkvar (lua_State *L) { | |
| 239 | + const char *name = lua_tostring(L, 2); | |
| 240 | + if (name) | |
| 241 | + luaL_error(L, "attempt to access undefined variable `%s'", name); | |
| 242 | + return 0; | |
| 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 | 253 | else |
| 301 | − file_input(NULL); /* executes stdin as a file */ | |
| 254 | + dofile(L, NULL); /* executes stdin as a file */ | |
| 302 | 255 | } |
| 303 | 256 | else { /* other arguments; loop over them */ |
| 304 | 257 | int i; |
| @@ -314,25 +267,35 @@ static int handle_argv (char *argv[], int *interactive) { · 9 unmodified lines | ||
| 314 | 267 | goto endloop; /* stop handling arguments */ |
| 315 | 268 | } |
| 316 | 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 | 272 | break; |
| 319 | 273 | } |
| 320 | 274 | case 'i': { |
| 321 | − *interactive = 1; | |
| 275 | + *interactive = 2; /* force interactive mode after arguments */ | |
| 322 | 276 | break; |
| 323 | 277 | } |
| 324 | 278 | case 'v': { |
| 279 | + clearinteractive(interactive); | |
| 325 | 280 | print_version(); |
| 326 | 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 | 290 | case 'e': { |
| 329 | 291 | const char *chunk = argv[i] + 2; |
| 292 | + clearinteractive(interactive); | |
| 330 | 293 | if (*chunk == '\0') chunk = argv[++i]; |
| 331 | 294 | if (chunk == NULL) { |
| 332 | 295 | print_usage(); |
| 333 | 296 | return 1; |
| 334 | 297 | } |
| 335 | − if (dostring(chunk, "=<command line>") != 0) | |
| 298 | + if (dostring(L, chunk, "=<command line>") != 0) | |
| 336 | 299 | return 1; |
| 337 | 300 | break; |
| 338 | 301 | } |
| @@ -343,19 +306,12 @@ static int handle_argv (char *argv[], int *interactive) { · 4 unmodified lines | ||
| 343 | 306 | print_usage(); |
| 344 | 307 | return 1; |
| 345 | 308 | } |
| 346 | − if (load_file(filename)) | |
| 309 | + if (dolibrary(L, filename)) | |
| 347 | 310 | return 1; /* stop if file fails */ |
| 348 | 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 | 313 | default: { |
| 314 | + clearinteractive(interactive); | |
| 359 | 315 | print_usage(); |
| 360 | 316 | return 1; |
| 361 | 317 | } |
| @@ -363,31 +319,30 @@ static int handle_argv (char *argv[], int *interactive) { · 1 unmodified line | ||
| 363 | 319 | } endloop: |
| 364 | 320 | if (argv[i] != NULL) { |
| 365 | 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 | 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 | 335 | return 0; |
| 372 | 336 | } |
| 373 | 337 | |
| 374 | 338 | |
| 375 | −static void openstdlibs (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) { | |
| 339 | +static int handle_luainit (lua_State *L) { | |
| 385 | 340 | const char *init = getenv("LUA_INIT"); |
| 386 | 341 | if (init == NULL) return 0; /* status OK */ |
| 387 | 342 | else if (init[0] == '@') |
| 388 | − return file_input(init+1); | |
| 343 | + return dofile(L, init+1); | |
| 389 | 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) { | |
| 402 | − struct Smain *s = (struct Smain *)lua_touserdata(l, 1); | |
| 356 | +static int pmain (lua_State *L) { | |
| 357 | + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); | |
| 403 | 358 | int status; |
| 404 | − int interactive = 0; | |
| 359 | + int interactive = 1; | |
| 405 | 360 | if (s->argv[0] && s->argv[0][0]) progname = s->argv[0]; |
| 406 | − L = l; | |
| 407 | − lua_userinit(l); /* open libraries */ | |
| 408 | − status = handle_luainit(); | |
| 361 | + globalL = L; | |
| 362 | + lua_userinit(L); /* open libraries */ | |
| 363 | + status = handle_luainit(L); | |
| 409 | 364 | if (status == 0) { |
| 410 | − status = handle_argv(s->argv, &interactive); | |
| 411 | − if (status == 0 && interactive) manual_input(); | |
| 365 | + status = handle_argv(L, s->argv, &interactive); | |
| 366 | + if (status == 0 && interactive) dotty(L); | |
| 412 | 367 | } |
| 413 | 368 | s->status = status; |
| 414 | 369 | return 0; |
| @@ -418,16 +373,16 @@ static int pmain (lua_State *l) { · 3 unmodified lines | ||
| 418 | 373 | int main (int argc, char *argv[]) { |
| 419 | 374 | int status; |
| 420 | 375 | struct Smain s; |
| 421 | − lua_State *l = lua_open(); /* create state */ | |
| 422 | − if (l == NULL) { | |
| 376 | + lua_State *L = lua_open(); /* create state */ | |
| 377 | + if (L == NULL) { | |
| 423 | 378 | l_message(argv[0], "cannot create state: not enough memory"); |
| 424 | 379 | return EXIT_FAILURE; |
| 425 | 380 | } |
| 426 | 381 | s.argc = argc; |
| 427 | 382 | s.argv = argv; |
| 428 | − status = lua_cpcall(l, &pmain, &s); | |
| 429 | − report(status); | |
| 430 | − lua_close(l); | |
| 383 | + status = lua_cpcall(L, &pmain, &s); | |
| 384 | + report(L, status); | |
| 385 | + lua_close(L); | |
| 431 | 386 | return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; |
| 432 | 387 | } |
| 433 | 388 | |
| @@ -5,7 +5,7 @@ LUA= ../.. · 4 unmodified lines | ||
| 5 | 5 | include $(LUA)/config |
| 6 | 6 | |
| 7 | 7 | INCS= -I$(INC) -I.. $(EXTRA_INCS) |
| 8 | −OBJS= luac.o print.o lopcodes.o | |
| 8 | +OBJS= luac.o print.o | |
| 9 | 9 | SRCS= luac.c print.c |
| 10 | 10 | |
| 11 | 11 | T= $(BIN)/luac |
| @@ -15,10 +15,6 @@ all: $T · 3 unmodified lines | ||
| 15 | 15 | $T: $(OBJS) $(LIB)/liblua.a ../lib/lauxlib.o |
| 16 | 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 | 18 | $(LIB)/liblua.a: |
| 23 | 19 | cd ..; $(MAKE) |
| 24 | 20 | |
| @@ -1 +0,0 @@ | ||
| 1 | −../RCS | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | This is luac, the Lua compiler. |
| 2 | 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 | 5 | The main advantages of pre-compiling chunks are: faster loading, protecting |
| 6 | 6 | source code from user changes, and off-line syntax error detection. |
| 7 | 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 | 3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -9,6 +9,9 @@ · 3 unmodified lines | ||
| 9 | 9 | #include <stdlib.h> |
| 10 | 10 | #include <string.h> |
| 11 | 11 | |
| 12 | +#define luac_c | |
| 13 | +#define LUA_CORE | |
| 14 | + | |
| 12 | 15 | #include "lua.h" |
| 13 | 16 | #include "lauxlib.h" |
| 14 | 17 | |
| @@ -43,8 +46,7 @@ static void fatal(const char* message) · 28 unmodified lines | ||
| 43 | 46 | |
| 44 | 47 | static void cannot(const char* what) |
| 45 | 48 | { |
| 46 | − fprintf(stderr,"%s: cannot %s output file %s: %s\n", | |
| 47 | − progname,what,output,strerror(errno)); | |
| 49 | + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); | |
| 48 | 50 | exit(EXIT_FAILURE); |
| 49 | 51 | } |
| 50 | 52 | |
| @@ -84,13 +86,14 @@ static int doargs(int argc, char* argv[]) · 33 unmodified lines | ||
| 84 | 86 | break; |
| 85 | 87 | } |
| 86 | 88 | else if (IS("-")) /* end of options; use stdin */ |
| 87 | − return i; | |
| 89 | + break; | |
| 88 | 90 | else if (IS("-l")) /* list */ |
| 89 | − listing=1; | |
| 91 | + ++listing; | |
| 90 | 92 | else if (IS("-o")) /* output file */ |
| 91 | 93 | { |
| 92 | 94 | output=argv[++i]; |
| 93 | 95 | if (output==NULL || *output==0) usage("`-o' needs argument"); |
| 96 | + if (IS("-")) output=NULL; | |
| 94 | 97 | } |
| 95 | 98 | else if (IS("-p")) /* parse only */ |
| 96 | 99 | dumping=0; |
| @@ -112,11 +115,7 @@ static int doargs(int argc, char* argv[]) · 15 unmodified lines | ||
| 112 | 115 | return i; |
| 113 | 116 | } |
| 114 | 117 | |
| 115 | −static Proto* toproto(lua_State* L, int i) | |
| 116 | −{ | |
| 117 | − const Closure* c=(const Closure*)lua_topointer(L,i); | |
| 118 | − return c->l.p; | |
| 119 | −} | |
| 118 | +#define toproto(L,i) (clvalue(L->top+(i))->l.p) | |
| 120 | 119 | |
| 121 | 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 | 123 | return toproto(L,-1); |
| 125 | 124 | else |
| 126 | 125 | { |
| 127 | − int i,pc=0; | |
| 126 | + int i,pc; | |
| 128 | 127 | Proto* f=luaF_newproto(L); |
| 129 | 128 | setptvalue2s(L,L->top,f); incr_top(L); |
| 130 | 129 | f->source=luaS_newliteral(L,"=(" PROGNAME ")"); |
| 131 | 130 | f->maxstacksize=1; |
| 131 | + pc=2*n+1; | |
| 132 | + f->code=luaM_newvector(L,pc,Instruction); | |
| 133 | + f->sizecode=pc; | |
| 132 | 134 | f->p=luaM_newvector(L,n,Proto*); |
| 133 | 135 | f->sizep=n; |
| 134 | − f->sizecode=2*n+1; | |
| 135 | − f->code=luaM_newvector(L,f->sizecode,Instruction); | |
| 136 | + pc=0; | |
| 136 | 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 | 140 | f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); |
| 140 | 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 | 148 | static int writer(lua_State* L, const void* p, size_t size, void* u) |
| 148 | 149 | { |
| 149 | 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 | −{ | |
| 155 | − UNUSED(L); | |
| 156 | − fatal("not enough memory!"); | |
| 157 | − return 0; | |
| 158 | −} | |
| 154 | +void unprint(lua_State* L, const char* name); | |
| 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 | 166 | Proto* f; |
| 164 | − int i=doargs(argc,argv); | |
| 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); | |
| 167 | + int i; | |
| 170 | 168 | if (!lua_checkstack(L,argc)) fatal("too many input files"); |
| 171 | 169 | for (i=0; i<argc; i++) |
| 172 | 170 | { |
| @@ -174,10 +172,10 @@ int main(int argc, char* argv[]) · 1 unmodified line | ||
| 174 | 172 | if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1)); |
| 175 | 173 | } |
| 176 | 174 | f=combine(L,argc); |
| 177 | − if (listing) luaU_print(f); | |
| 175 | + if (listing) luaU_print(f,listing>1); | |
| 178 | 176 | if (dumping) |
| 179 | 177 | { |
| 180 | − FILE* D=fopen(output,"wb"); | |
| 178 | + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); | |
| 181 | 179 | if (D==NULL) cannot("open"); |
| 182 | 180 | lua_lock(L); |
| 183 | 181 | luaU_dump(L,f,writer,D,stripping); |
| @@ -185,6 +183,21 @@ int main(int argc, char* argv[]) · 1 unmodified line | ||
| 185 | 183 | if (ferror(D)) cannot("write"); |
| 186 | 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 | 201 | lua_close(L); |
| 189 | 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 | 3 | ** print bytecodes |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <ctype.h> | |
| 7 | 8 | #include <stdio.h> |
| 8 | 9 | |
| 9 | −#if 1 | |
| 10 | −#define DEBUG_PRINT | |
| 11 | −#endif | |
| 12 | − | |
| 13 | −#ifndef LUA_OPNAMES | |
| 14 | −#define LUA_OPNAMES | |
| 15 | −#endif | |
| 10 | +#define LUA_CORE | |
| 16 | 11 | |
| 17 | 12 | #include "ldebug.h" |
| 18 | 13 | #include "lobject.h" |
| @@ -38,7 +33,7 @@ static void PrintString(const Proto* f, int n) · 19 unmodified lines | ||
| 38 | 33 | case '\r': printf("\\r"); break; |
| 39 | 34 | case '\t': printf("\\t"); break; |
| 40 | 35 | case '\v': printf("\\v"); break; |
| 41 | − default: putchar(*s); break; | |
| 36 | + default: printf(isprint(*s) ? "%c" : "\\%03d",*s); | |
| 42 | 37 | } |
| 43 | 38 | } |
| 44 | 39 | putchar('"'); |
| @@ -88,13 +83,11 @@ static void PrintCode(const Proto* f) · 43 unmodified lines | ||
| 88 | 83 | { |
| 89 | 84 | case iABC: |
| 90 | 85 | printf("%d",a); |
| 91 | − if (getBMode(o)!=OpArgN) | |
| 92 | − { if (b>=MAXSTACK) printf(" #%d",b-MAXSTACK); else printf(" %d",b); } | |
| 93 | − if (getCMode(o)!=OpArgN) | |
| 94 | − { if (c>=MAXSTACK) printf(" #%d",c-MAXSTACK); else printf(" %d",c); } | |
| 86 | + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); | |
| 87 | + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); | |
| 95 | 88 | break; |
| 96 | 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 | 91 | break; |
| 99 | 92 | case iAsBx: |
| 100 | 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 | 108 | break; |
| 116 | 109 | case OP_GETTABLE: |
| 117 | 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 | 112 | break; |
| 120 | 113 | case OP_SETTABLE: |
| 121 | 114 | case OP_ADD: |
| @@ -126,12 +119,12 @@ static void PrintCode(const Proto* f) · 4 unmodified lines | ||
| 126 | 119 | case OP_EQ: |
| 127 | 120 | case OP_LT: |
| 128 | 121 | case OP_LE: |
| 129 | − if (b>=MAXSTACK || c>=MAXSTACK) | |
| 122 | + if (ISK(b) || ISK(c)) | |
| 130 | 123 | { |
| 131 | 124 | printf("\t; "); |
| 132 | − if (b>=MAXSTACK) PrintConstant(f,b-MAXSTACK); else printf("-"); | |
| 125 | + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); | |
| 133 | 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 | 129 | break; |
| 137 | 130 | case OP_JMP: |
| @@ -161,15 +154,13 @@ static const char* Source(const Proto* f) · 23 unmodified lines | ||
| 161 | 154 | return "(string)"; |
| 162 | 155 | } |
| 163 | 156 | |
| 164 | −#define IsMain(f) (f->lineDefined==0) | |
| 165 | − | |
| 166 | 157 | #define SS(x) (x==1)?"":"s" |
| 167 | 158 | #define S(x) x,SS(x) |
| 168 | 159 | |
| 169 | 160 | static void PrintHeader(const Proto* f) |
| 170 | 161 | { |
| 171 | 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 | 164 | S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); |
| 174 | 165 | printf("%d%s param%s, %d stack%s, %d upvalue%s, ", |
| 175 | 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 | 169 | S(f->sizelocvars),S(f->sizek),S(f->sizep)); |
| 179 | 170 | } |
| 180 | 171 | |
| 181 | −#ifdef DEBUG_PRINT | |
| 182 | 172 | static void PrintConstants(const Proto* f) |
| 183 | 173 | { |
| 184 | 174 | int i,n=f->sizek; |
| 185 | 175 | printf("constants (%d) for %p:\n",n,VOID(f)); |
| 186 | 176 | for (i=0; i<n; i++) |
| 187 | 177 | { |
| 188 | − printf("\t%d\t",i); | |
| 178 | + printf("\t%d\t",i+1); | |
| 189 | 179 | PrintConstant(f,i); |
| 190 | 180 | printf("\n"); |
| 191 | 181 | } |
| @@ -212,17 +202,17 @@ static void PrintUpvalues(const Proto* f) · 20 unmodified lines | ||
| 212 | 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 | 208 | int i,n=f->sizep; |
| 220 | 209 | PrintHeader(f); |
| 221 | 210 | PrintCode(f); |
| 222 | −#ifdef DEBUG_PRINT | |
| 223 | − PrintConstants(f); | |
| 224 | − PrintLocals(f); | |
| 225 | − PrintUpvalues(f); | |
| 226 | −#endif | |
| 227 | − for (i=0; i<n; i++) luaU_print(f->p[i]); | |
| 211 | + if (full) | |
| 212 | + { | |
| 213 | + PrintConstants(f); | |
| 214 | + PrintLocals(f); | |
| 215 | + PrintUpvalues(f); | |
| 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 | 3 | ** load pre-compiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stddef.h> |
| 9 | 9 | |
| 10 | 10 | #define lundump_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 13 | #include "lua.h" |
| 13 | 14 | |
| @@ -261,15 +262,15 @@ static void LoadHeader (LoadState* S) · 247 unmodified lines | ||
| 261 | 262 | /* |
| 262 | 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 | 267 | LoadState S; |
| 267 | − if (*s=='@' || *s=='=') | |
| 268 | − S.name=s+1; | |
| 269 | − else if (*s==LUA_SIGNATURE[0]) | |
| 268 | + if (*name=='@' || *name=='=') | |
| 269 | + S.name=name+1; | |
| 270 | + else if (*name==LUA_SIGNATURE[0]) | |
| 270 | 271 | S.name="binary string"; |
| 271 | 272 | else |
| 272 | − S.name=s; | |
| 273 | + S.name=name; | |
| 273 | 274 | S.L=L; |
| 274 | 275 | S.Z=Z; |
| 275 | 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 | 3 | ** load pre-compiled Lua chunks |
| 4 | 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 | 17 | int luaU_endianness (void); |
| 18 | 18 | |
| 19 | 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 | 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 | 25 | /* definitions for headers of binary files */ |
| 26 | 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 | 3 | ** Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,10 +8,8 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <stdlib.h> |
| 9 | 9 | #include <string.h> |
| 10 | 10 | |
| 11 | −/* needed only when `lua_number2str' uses `sprintf' */ | |
| 12 | −#include <stdio.h> | |
| 13 | − | |
| 14 | 11 | #define lvm_c |
| 12 | +#define LUA_CORE | |
| 15 | 13 | |
| 16 | 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 | 30 | /* limit for table tag-method chains (to avoid loops) */ |
| 39 | 31 | #define MAXTAGLOOP 100 |
| 40 | 32 | |
| @@ -66,8 +58,8 @@ int luaV_tostring (lua_State *L, StkId obj) { · 25 unmodified lines | ||
| 66 | 58 | static void traceexec (lua_State *L, const Instruction *pc) { |
| 67 | 59 | lu_byte mask = L->hookmask; |
| 68 | 60 | CallInfo *ci = L->ci; |
| 69 | − const Instruction *oldpc = ci->u.l.savedpc; | |
| 70 | − ci->u.l.savedpc = pc; | |
| 61 | + const Instruction *oldpc = ci->savedpc; | |
| 62 | + ci->savedpc = pc; | |
| 71 | 63 | if (mask > LUA_MASKLINE) { /* instruction-hook set? */ |
| 72 | 64 | if (L->hookcount == 0) { |
| 73 | 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 | 111 | int loop; |
| 119 | 112 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 120 | 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 | 117 | if (!ttisnil(res) || /* result is no nil? */ |
| 125 | 118 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ |
| 126 | 119 | setobj2s(L, val, res); |
| 127 | − return; | |
| 120 | + return L->base; | |
| 128 | 121 | } |
| 129 | 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 | 126 | luaG_typeerror(L, t, "index"); |
| 127 | + } | |
| 133 | 128 | if (ttisfunction(tm)) { |
| 129 | + L->ci->savedpc = pc; | |
| 134 | 130 | prepTMcall(L, tm, t, key); |
| 135 | 131 | callTMres(L, val); |
| 136 | − return; | |
| 132 | + return L->base; | |
| 137 | 133 | } |
| 138 | 134 | t = tm; /* else repeat with `tm' */ |
| 139 | 135 | } |
| 136 | + L->ci->savedpc = pc; | |
| 140 | 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 | 144 | int loop; |
| 146 | 145 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 147 | 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 | 150 | if (!ttisnil(oldval) || /* result is no nil? */ |
| 152 | 151 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ |
| 153 | 152 | setobj2t(L, oldval, val); |
| 154 | − luaC_barrier(L, h, val); | |
| 155 | − return; | |
| 153 | + luaC_barriert(L, h, val); | |
| 154 | + return L->base; | |
| 156 | 155 | } |
| 157 | 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 | 160 | luaG_typeerror(L, t, "index"); |
| 161 | + } | |
| 161 | 162 | if (ttisfunction(tm)) { |
| 163 | + L->ci->savedpc = pc; | |
| 162 | 164 | prepTMcall(L, tm, t, key); |
| 163 | 165 | setobj2s(L, L->top+3, val); /* 3th argument */ |
| 164 | 166 | callTM(L); |
| 165 | − return; | |
| 167 | + return L->base; | |
| 166 | 168 | } |
| 167 | 169 | t = tm; /* else repeat with `tm' */ |
| 168 | 170 | } |
| 171 | + L->ci->savedpc = pc; | |
| 169 | 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 | 308 | char *buffer; |
| 305 | 309 | int i; |
| 306 | 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 | 314 | n++; |
| 309 | 315 | } |
| 310 | − if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow"); | |
| 311 | 316 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 312 | 317 | tl = 0; |
| 313 | 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 | 332 | const TValue *rc, TMS op, const Instruction *pc) { |
| 328 | 333 | TValue tempb, tempc; |
| 329 | 334 | const TValue *b, *c; |
| 330 | − L->ci->u.l.savedpc = pc; | |
| 335 | + L->ci->savedpc = pc; | |
| 331 | 336 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && |
| 332 | 337 | (c = luaV_tonumber(rc, &tempc)) != NULL) { |
| 333 | 338 | switch (op) { |
| @@ -364,13 +369,13 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb, · 30 unmodified lines | ||
| 364 | 369 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) |
| 365 | 370 | #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) |
| 366 | 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 | 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 | 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 | 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 | 387 | if (L->hookmask & LUA_MASKCALL) |
| 383 | 388 | luaD_callhook(L, LUA_HOOKCALL, -1); |
| 384 | 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 | 392 | base = L->base; |
| 387 | − cl = &clvalue(base - 1)->l; | |
| 388 | 393 | k = cl->p->k; |
| 389 | 394 | /* main loop of interpreter */ |
| 390 | 395 | for (;;) { |
| @@ -394,7 +399,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines | ||
| 394 | 399 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| 395 | 400 | traceexec(L, pc); /***/ |
| 396 | 401 | if (L->isSuspended) { /* did hook yield? */ |
| 397 | − L->ci->u.l.savedpc = pc - 1; | |
| 402 | + L->ci->savedpc = pc - 1; | |
| 398 | 403 | return NULL; |
| 399 | 404 | } |
| 400 | 405 | base = L->base; |
| @@ -402,85 +407,73 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line | ||
| 402 | 407 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
| 403 | 408 | ra = RA(i); |
| 404 | 409 | lua_assert(base == L->ci->base && base == L->base); |
| 405 | − lua_assert(L->top <= L->stack + L->stacksize && L->top >= base); | |
| 406 | − lua_assert(L->top == L->ci->top || | |
| 407 | − GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || | |
| 408 | − GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO); | |
| 410 | + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | |
| 411 | + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); | |
| 409 | 412 | switch (GET_OPCODE(i)) { |
| 410 | 413 | case OP_MOVE: { |
| 411 | 414 | setobjs2s(L, ra, RB(i)); |
| 412 | − break; | |
| 415 | + continue; | |
| 413 | 416 | } |
| 414 | 417 | case OP_LOADK: { |
| 415 | 418 | setobj2s(L, ra, KBx(i)); |
| 416 | − break; | |
| 419 | + continue; | |
| 417 | 420 | } |
| 418 | 421 | case OP_LOADBOOL: { |
| 419 | 422 | setbvalue(ra, GETARG_B(i)); |
| 420 | 423 | if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ |
| 421 | − break; | |
| 424 | + continue; | |
| 422 | 425 | } |
| 423 | 426 | case OP_LOADNIL: { |
| 424 | 427 | TValue *rb = RB(i); |
| 425 | 428 | do { |
| 426 | 429 | setnilvalue(rb--); |
| 427 | 430 | } while (rb >= ra); |
| 428 | − break; | |
| 431 | + continue; | |
| 429 | 432 | } |
| 430 | 433 | case OP_GETUPVAL: { |
| 431 | 434 | int b = GETARG_B(i); |
| 432 | 435 | setobj2s(L, ra, cl->upvals[b]->v); |
| 433 | − break; | |
| 436 | + continue; | |
| 434 | 437 | } |
| 435 | 438 | case OP_GETGLOBAL: { |
| 436 | 439 | TValue *rb = KBx(i); |
| 437 | 440 | lua_assert(ttisstring(rb) && ttistable(&cl->g)); |
| 438 | − L->ci->u.l.savedpc = pc; | |
| 439 | − luaV_gettable(L, &cl->g, rb, ra); /***/ | |
| 440 | − base = L->base; | |
| 441 | − break; | |
| 441 | + base = luaV_gettable(L, &cl->g, rb, ra, pc); /***/ | |
| 442 | + continue; | |
| 442 | 443 | } |
| 443 | 444 | case OP_GETTABLE: { |
| 444 | − L->ci->u.l.savedpc = pc; | |
| 445 | − luaV_gettable(L, RB(i), RKC(i), ra); /***/ | |
| 446 | − base = L->base; | |
| 447 | − break; | |
| 445 | + base = luaV_gettable(L, RB(i), RKC(i), ra, pc); /***/ | |
| 446 | + continue; | |
| 448 | 447 | } |
| 449 | 448 | case OP_SETGLOBAL: { |
| 450 | 449 | lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); |
| 451 | − L->ci->u.l.savedpc = pc; | |
| 452 | − luaV_settable(L, &cl->g, KBx(i), ra); /***/ | |
| 453 | − base = L->base; | |
| 454 | − break; | |
| 450 | + base = luaV_settable(L, &cl->g, KBx(i), ra, pc); /***/ | |
| 451 | + continue; | |
| 455 | 452 | } |
| 456 | 453 | case OP_SETUPVAL: { |
| 457 | 454 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
| 458 | 455 | setobj(L, uv->v, ra); |
| 459 | 456 | luaC_barrier(L, uv, ra); |
| 460 | − break; | |
| 457 | + continue; | |
| 461 | 458 | } |
| 462 | 459 | case OP_SETTABLE: { |
| 463 | − L->ci->u.l.savedpc = pc; | |
| 464 | − luaV_settable(L, ra, RKB(i), RKC(i)); /***/ | |
| 465 | − base = L->base; | |
| 466 | − break; | |
| 460 | + base = luaV_settable(L, ra, RKB(i), RKC(i), pc); /***/ | |
| 461 | + continue; | |
| 467 | 462 | } |
| 468 | 463 | case OP_NEWTABLE: { |
| 469 | 464 | int b = GETARG_B(i); |
| 470 | 465 | b = fb2int(b); |
| 471 | 466 | sethvalue(L, ra, luaH_new(L, b, GETARG_C(i))); |
| 472 | − L->ci->u.l.savedpc = pc; | |
| 467 | + L->ci->savedpc = pc; | |
| 473 | 468 | luaC_checkGC(L); /***/ |
| 474 | 469 | base = L->base; |
| 475 | − break; | |
| 470 | + continue; | |
| 476 | 471 | } |
| 477 | 472 | case OP_SELF: { |
| 478 | 473 | StkId rb = RB(i); |
| 479 | 474 | setobjs2s(L, ra+1, rb); |
| 480 | − L->ci->u.l.savedpc = pc; | |
| 481 | − luaV_gettable(L, rb, RKC(i), ra); /***/ | |
| 482 | − base = L->base; | |
| 483 | − break; | |
| 475 | + base = luaV_gettable(L, rb, RKC(i), ra, pc); /***/ | |
| 476 | + continue; | |
| 484 | 477 | } |
| 485 | 478 | case OP_ADD: { |
| 486 | 479 | TValue *rb = RKB(i); |
| @@ -490,7 +483,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines | ||
| 490 | 483 | } |
| 491 | 484 | else |
| 492 | 485 | base = Arith(L, ra, rb, rc, TM_ADD, pc); /***/ |
| 493 | − break; | |
| 486 | + continue; | |
| 494 | 487 | } |
| 495 | 488 | case OP_SUB: { |
| 496 | 489 | TValue *rb = RKB(i); |
| @@ -500,7 +493,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines | ||
| 500 | 493 | } |
| 501 | 494 | else |
| 502 | 495 | base = Arith(L, ra, rb, rc, TM_SUB, pc); /***/ |
| 503 | − break; | |
| 496 | + continue; | |
| 504 | 497 | } |
| 505 | 498 | case OP_MUL: { |
| 506 | 499 | TValue *rb = RKB(i); |
| @@ -510,7 +503,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines | ||
| 510 | 503 | } |
| 511 | 504 | else |
| 512 | 505 | base = Arith(L, ra, rb, rc, TM_MUL, pc); /***/ |
| 513 | − break; | |
| 506 | + continue; | |
| 514 | 507 | } |
| 515 | 508 | case OP_DIV: { |
| 516 | 509 | TValue *rb = RKB(i); |
| @@ -520,11 +513,11 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines | ||
| 520 | 513 | } |
| 521 | 514 | else |
| 522 | 515 | base = Arith(L, ra, rb, rc, TM_DIV, pc); /***/ |
| 523 | − break; | |
| 516 | + continue; | |
| 524 | 517 | } |
| 525 | 518 | case OP_POW: { |
| 526 | 519 | base = Arith(L, ra, RKB(i), RKC(i), TM_POW, pc); /***/ |
| 527 | − break; | |
| 520 | + continue; | |
| 528 | 521 | } |
| 529 | 522 | case OP_UNM: { |
| 530 | 523 | const TValue *rb = RB(i); |
| @@ -534,113 +527,131 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 3 unmodified lines | ||
| 534 | 527 | } |
| 535 | 528 | else { |
| 536 | 529 | setnilvalue(&temp); |
| 537 | − L->ci->u.l.savedpc = pc; | |
| 530 | + L->ci->savedpc = pc; | |
| 538 | 531 | if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) /***/ |
| 539 | 532 | luaG_aritherror(L, RB(i), &temp); |
| 540 | 533 | base = L->base; |
| 541 | 534 | } |
| 542 | − break; | |
| 535 | + continue; | |
| 543 | 536 | } |
| 544 | 537 | case OP_NOT: { |
| 545 | 538 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ |
| 546 | 539 | setbvalue(ra, res); |
| 547 | − break; | |
| 540 | + continue; | |
| 548 | 541 | } |
| 549 | 542 | case OP_CONCAT: { |
| 550 | 543 | int b = GETARG_B(i); |
| 551 | 544 | int c = GETARG_C(i); |
| 552 | − L->ci->u.l.savedpc = pc; | |
| 545 | + L->ci->savedpc = pc; | |
| 553 | 546 | luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ /***/ |
| 554 | 547 | luaC_checkGC(L); /***/ |
| 555 | 548 | base = L->base; |
| 556 | 549 | setobjs2s(L, RA(i), base+b); |
| 557 | − break; | |
| 550 | + continue; | |
| 558 | 551 | } |
| 559 | 552 | case OP_JMP: { |
| 560 | − dojump(pc, GETARG_sBx(i)); | |
| 561 | − break; | |
| 553 | + dojump(L, pc, GETARG_sBx(i)); | |
| 554 | + continue; | |
| 562 | 555 | } |
| 563 | 556 | case OP_EQ: { |
| 564 | − L->ci->u.l.savedpc = pc; | |
| 557 | + L->ci->savedpc = pc; | |
| 565 | 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 | 560 | base = L->base; |
| 568 | − break; | |
| 561 | + continue; | |
| 569 | 562 | } |
| 570 | 563 | case OP_LT: { |
| 571 | − L->ci->u.l.savedpc = pc; | |
| 564 | + L->ci->savedpc = pc; | |
| 572 | 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 | 567 | base = L->base; |
| 575 | − break; | |
| 568 | + continue; | |
| 576 | 569 | } |
| 577 | 570 | case OP_LE: { |
| 578 | − L->ci->u.l.savedpc = pc; | |
| 571 | + L->ci->savedpc = pc; | |
| 579 | 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 | 574 | base = L->base; |
| 582 | − break; | |
| 575 | + continue; | |
| 583 | 576 | } |
| 584 | 577 | case OP_TEST: { |
| 585 | 578 | TValue *rb = RB(i); |
| 586 | 579 | if (l_isfalse(rb) == GETARG_C(i)) pc++; |
| 587 | 580 | else { |
| 588 | 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: | |
| 594 | − case OP_TAILCALL: { /***/ | |
| 595 | − StkId firstResult; | |
| 586 | + case OP_CALL: { /***/ | |
| 587 | + int pcr; | |
| 596 | 588 | int b = GETARG_B(i); |
| 589 | + int nresults = GETARG_C(i) - 1; | |
| 597 | 590 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 598 | − L->ci->u.l.savedpc = pc; | |
| 599 | − firstResult = luaD_precall(L, ra); | |
| 600 | − if (firstResult) { | |
| 601 | − int nresults = GETARG_C(i) - 1; | |
| 602 | − if (firstResult > L->top) { /* yield? */ | |
| 603 | − (L->ci - 1)->u.l.savedpc = pc; | |
| 604 | − return NULL; | |
| 605 | − } | |
| 591 | + L->ci->savedpc = pc; | |
| 592 | + pcr = luaD_precall(L, ra, nresults); | |
| 593 | + if (pcr == PCRLUA) { | |
| 594 | + nexeccalls++; | |
| 595 | + goto callentry; /* restart luaV_execute over new Lua function */ | |
| 596 | + } | |
| 597 | + else if (pcr == PCRC) { | |
| 606 | 598 | /* it was a C function (`precall' called it); adjust results */ |
| 607 | − luaD_poscall(L, nresults, firstResult); | |
| 608 | 599 | if (nresults >= 0) L->top = L->ci->top; |
| 600 | + base = L->base; | |
| 601 | + continue; | |
| 609 | 602 | } |
| 610 | − else { /* it is a Lua function */ | |
| 611 | − if (GET_OPCODE(i) == OP_CALL) /* regular call? */ | |
| 612 | − nexeccalls++; | |
| 613 | − else { /* tail call: put new frame in place of previous one */ | |
| 614 | − int aux; | |
| 615 | − base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */ | |
| 616 | − ra = RA(i); | |
| 617 | − if (L->openupval) luaF_close(L, base); | |
| 618 | − for (aux = 0; ra+aux < L->top; aux++) /* move frame down */ | |
| 619 | − setobjs2s(L, base+aux-1, ra+aux); | |
| 620 | − (L->ci - 1)->top = L->top = base+aux; /* correct top */ | |
| 621 | − (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; | |
| 622 | − (L->ci - 1)->u.l.tailcalls++; /* one more call lost */ | |
| 623 | − L->ci--; /* remove new frame */ | |
| 624 | − L->base = L->ci->base; | |
| 625 | − } | |
| 603 | + else { | |
| 604 | + lua_assert(pcr == PCRYIELD); | |
| 605 | + return NULL; | |
| 606 | + } | |
| 607 | + } | |
| 608 | + case OP_TAILCALL: { /***/ | |
| 609 | + int pcr; | |
| 610 | + int b = GETARG_B(i); | |
| 611 | + if (b != 0) L->top = ra+b; /* else previous instruction set top */ | |
| 612 | + L->ci->savedpc = pc; | |
| 613 | + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | |
| 614 | + pcr = luaD_precall(L, ra, LUA_MULTRET); | |
| 615 | + if (pcr == PCRLUA) { | |
| 616 | + /* tail call: put new frame in place of previous one */ | |
| 617 | + CallInfo *ci = L->ci - 1; /* previous frame */ | |
| 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 | 631 | goto callentry; |
| 627 | 632 | } |
| 628 | − base = L->base; | |
| 629 | − break; | |
| 633 | + else if (pcr == PCRC) { | |
| 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 | 643 | case OP_RETURN: { |
| 632 | 644 | CallInfo *ci = L->ci - 1; /* previous function frame */ |
| 633 | 645 | int b = GETARG_B(i); |
| 634 | 646 | if (b != 0) L->top = ra+b-1; |
| 635 | 647 | if (L->openupval) luaF_close(L, base); |
| 636 | − L->ci->u.l.savedpc = pc; | |
| 648 | + L->ci->savedpc = pc; | |
| 637 | 649 | if (--nexeccalls == 0) /* was previous function running `here'? */ |
| 638 | 650 | return ra; /* no: return */ |
| 639 | 651 | else { /* yes: continue its execution */ |
| 640 | − int nresults; | |
| 652 | + int nresults = (ci+1)->nresults; | |
| 641 | 653 | lua_assert(isLua(ci)); |
| 642 | − lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); | |
| 643 | − nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; | |
| 654 | + lua_assert(GET_OPCODE(*(ci->savedpc - 1)) == OP_CALL); | |
| 644 | 655 | luaD_poscall(L, nresults, ra); |
| 645 | 656 | if (nresults >= 0) L->top = L->ci->top; |
| 646 | 657 | goto retentry; |
| @@ -651,17 +662,17 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 4 unmodified lines | ||
| 651 | 662 | lua_Number idx = nvalue(ra) + step; /* increment index */ |
| 652 | 663 | lua_Number limit = nvalue(ra+1); |
| 653 | 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 | 666 | setnvalue(ra, idx); /* update internal index... */ |
| 656 | 667 | setnvalue(ra+3, idx); /* ...and external index */ |
| 657 | 668 | } |
| 658 | − break; | |
| 669 | + continue; | |
| 659 | 670 | } |
| 660 | 671 | case OP_FORPREP: { /***/ |
| 661 | 672 | const TValue *init = ra; |
| 662 | 673 | const TValue *plimit = ra+1; |
| 663 | 674 | const TValue *pstep = ra+2; |
| 664 | − L->ci->u.l.savedpc = pc; | |
| 675 | + L->ci->savedpc = pc; | |
| 665 | 676 | if (!tonumber(init, ra)) |
| 666 | 677 | luaG_runerror(L, "`for' initial value must be a number"); |
| 667 | 678 | else if (!tonumber(plimit, ra+1)) |
| @@ -669,8 +680,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line | ||
| 669 | 680 | else if (!tonumber(pstep, ra+2)) |
| 670 | 681 | luaG_runerror(L, "`for' step must be a number"); |
| 671 | 682 | setnvalue(ra, nvalue(ra) - nvalue(pstep)); |
| 672 | − dojump(pc, GETARG_sBx(i)); | |
| 673 | − break; | |
| 683 | + dojump(L, pc, GETARG_sBx(i)); | |
| 684 | + continue; | |
| 674 | 685 | } |
| 675 | 686 | case OP_TFORLOOP: { |
| 676 | 687 | StkId cb = ra + 3; /* call base */ |
| @@ -678,7 +689,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line | ||
| 678 | 689 | setobjs2s(L, cb+1, ra+1); |
| 679 | 690 | setobjs2s(L, cb, ra); |
| 680 | 691 | L->top = cb+3; /* func. + 2 args (state and index) */ |
| 681 | − L->ci->u.l.savedpc = pc; | |
| 692 | + L->ci->savedpc = pc; | |
| 682 | 693 | luaD_call(L, cb, GETARG_C(i)); /***/ |
| 683 | 694 | L->top = L->ci->top; |
| 684 | 695 | base = L->base; |
| @@ -687,26 +698,25 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 2 unmodified lines | ||
| 687 | 698 | pc++; /* skip jump (break loop) */ |
| 688 | 699 | else { |
| 689 | 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 | 705 | case OP_TFORPREP: { /* for compatibility only */ |
| 695 | 706 | if (ttistable(ra)) { |
| 696 | 707 | setobjs2s(L, ra+1, ra); |
| 697 | 708 | setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); |
| 698 | 709 | } |
| 699 | − dojump(pc, GETARG_sBx(i)); | |
| 700 | − break; | |
| 710 | + dojump(L, pc, GETARG_sBx(i)); | |
| 711 | + continue; | |
| 701 | 712 | } |
| 702 | 713 | case OP_SETLIST: |
| 703 | 714 | case OP_SETLISTO: { |
| 704 | − int bc; | |
| 705 | − int n; | |
| 715 | + int bc = GETARG_Bx(i); | |
| 716 | + int n, last; | |
| 706 | 717 | Table *h; |
| 707 | 718 | runtime_check(L, ttistable(ra)); |
| 708 | 719 | h = hvalue(ra); |
| 709 | − bc = GETARG_Bx(i); | |
| 710 | 720 | if (GET_OPCODE(i) == OP_SETLIST) |
| 711 | 721 | n = (bc&(LFIELDS_PER_FLUSH-1)) + 1; |
| 712 | 722 | else { |
| @@ -714,16 +724,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 1 unmodified line | ||
| 714 | 724 | L->top = L->ci->top; |
| 715 | 725 | } |
| 716 | 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 | 730 | for (; n > 0; n--) { |
| 718 | 731 | TValue *val = ra+n; |
| 719 | − setobj2t(L, luaH_setnum(L, h, bc+n), val); | |
| 720 | − luaC_barrier(L, h, val); | |
| 732 | + setobj2t(L, luaH_setnum(L, h, last--), val); | |
| 733 | + luaC_barriert(L, h, val); | |
| 721 | 734 | } |
| 722 | − break; | |
| 735 | + continue; | |
| 723 | 736 | } |
| 724 | 737 | case OP_CLOSE: { |
| 725 | 738 | luaF_close(L, ra); |
| 726 | − break; | |
| 739 | + continue; | |
| 727 | 740 | } |
| 728 | 741 | case OP_CLOSURE: { |
| 729 | 742 | Proto *p; |
| @@ -742,10 +755,25 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { · 12 unmodified lines | ||
| 742 | 755 | } |
| 743 | 756 | } |
| 744 | 757 | setclvalue(L, ra, ncl); |
| 745 | − L->ci->u.l.savedpc = pc; | |
| 758 | + L->ci->savedpc = pc; | |
| 746 | 759 | luaC_checkGC(L); /***/ |
| 747 | 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 | 3 | ** Lua virtual machine |
| 4 | 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 | 26 | int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); |
| 27 | 27 | const TValue *luaV_tonumber (const TValue *obj, TValue *n); |
| 28 | 28 | int luaV_tostring (lua_State *L, StkId obj); |
| 29 | −void 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); | |
| 29 | +StkId luaV_gettable (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 | 33 | StkId luaV_execute (lua_State *L, int nexeccalls); |
| 32 | 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 | 3 | ** a generic input stream interface |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -8,6 +8,7 @@ · 2 unmodified lines | ||
| 8 | 8 | #include <string.h> |
| 9 | 9 | |
| 10 | 10 | #define lzio_c |
| 11 | +#define LUA_CORE | |
| 11 | 12 | |
| 12 | 13 | #include "lua.h" |
| 13 | 14 | |