Compare commits

...

2026 Commits

Author SHA1 Message Date
Roberto Ierusalimschy
5b33e39855 removed deprecated functions getn-foreach-foreachi 2010-11-23 15:21:14 -02:00
Roberto Ierusalimschy
a64cf8fac9 'test' -> 'btest' 2010-11-22 16:06:33 -02:00
Roberto Ierusalimschy
092fa71ddd conventional names for bitwise operators 2010-11-22 14:39:20 -02:00
Roberto Ierusalimschy
a2eaad5d81 'gfind' was deprecated in 5.1 2010-11-19 14:25:51 -02:00
Roberto Ierusalimschy
54771c5afa keep 'seminfo->ts' even for reserved words, just in case
(some lhf's tools need this)
2010-11-18 16:38:44 -02:00
Roberto Ierusalimschy
bcce769d29 avoid "unreacheable code" warnings 2010-11-18 16:38:27 -02:00
Roberto Ierusalimschy
24baa919c1 small bug: 'find' did not detect magic chars after a \0 in a pattern
and did a plain search in those cases
2010-11-16 18:39:41 -02:00
Roberto Ierusalimschy
d1c0efdb7d comment about compatibility-only functions 2010-11-16 17:20:01 -02:00
Roberto Ierusalimschy
566758de79 'getuservalue' accepts any type of argument 2010-11-16 16:01:28 -02:00
Roberto Ierusalimschy
50334faad6 no more compatibility with (veryyyy) old ref system 2010-11-16 15:43:29 -02:00
Roberto Ierusalimschy
cee7a8e1ec -DLUA_COMPAT_ALL is the default 2010-11-16 09:39:42 -02:00
Roberto Ierusalimschy
8c21f463ed 'debug' library is loaded by default 2010-11-12 13:48:30 -02:00
Roberto Ierusalimschy
a1952d9c41 'l_tvar' renamed to 'l_tg' 2010-11-12 13:47:34 -02:00
Roberto Ierusalimschy
1a46a713d2 new macro 'l_tvar' to easy the use of mathlib with other floating
types (float and long double)
2010-11-11 13:39:12 -02:00
Roberto Ierusalimschy
23b9ceb0a4 allows larger array parts in tables (no need to restrict it to 2^26) 2010-11-11 13:38:43 -02:00
Roberto Ierusalimschy
0a6a6b9d9d no more sentinel to detect loops in module dependencies;
usual message for infinite recursion is good enough.
2010-11-10 18:00:04 -02:00
Roberto Ierusalimschy
1b54197491 better error message when light userdata is used instead of a
full userdata
2010-11-10 16:06:10 -02:00
Roberto Ierusalimschy
c97aa9485c new function 'luaL_setmetatable' 2010-11-10 16:05:36 -02:00
Roberto Ierusalimschy
e885b91326 'luaL_typeerror' deprecated 2010-11-10 15:38:10 -02:00
Roberto Ierusalimschy
fa1f724378 when reading blocks with given size, try to read whole block
at once
2010-11-09 14:57:49 -02:00
Roberto Ierusalimschy
2a966116b1 detail (message) 2010-11-09 09:04:15 -02:00
Roberto Ierusalimschy
43ec354722 added support for conditional use of %Lg when using long double 2010-11-08 15:38:37 -02:00
Roberto Ierusalimschy
700b003fb5 when reading large files, double buffer size at each iteration 2010-11-08 15:27:22 -02:00
Roberto Ierusalimschy
f722ba6890 code should not use "defined" types, but "typedef"s types when they
are available (i.e., after including lua.h) + small changes to make
conversions more portable across diferent types for lua_Number
(long double) and lua_Unsigned (long long unsigned)
2010-11-08 14:33:20 -02:00
Roberto Ierusalimschy
c7d4da8746 correction to allow lua_Unsigned larger than usigned int 2010-11-08 14:31:22 -02:00
Roberto Ierusalimschy
f1629217f1 code for conversion macros moved from luaconf to llimits + 'uint'
renamed to 'unsigned' in those macros
2010-11-03 13:16:17 -02:00
Roberto Ierusalimschy
fdd5f2f7a3 comment typos 2010-10-29 15:52:46 -02:00
Roberto Ierusalimschy
c6ef3e2672 bug: by-one error when creating short source names (luaO_chunkid) 2010-10-29 13:54:55 -02:00
Roberto Ierusalimschy
ba8dca00ac detail (ununsed parameter) 2010-10-29 12:35:09 -02:00
Roberto Ierusalimschy
9be89a1864 'luaL_checkversion' also checks convertions (number to integer types) 2010-10-29 10:52:21 -02:00
Roberto Ierusalimschy
b9f371a3c2 added another option for ieeeendian 2010-10-29 09:13:21 -02:00
Roberto Ierusalimschy
4834de8427 comment typo 2010-10-29 09:13:14 -02:00
Roberto Ierusalimschy
94043a3a1a more robust implementation for 'luaO_str2d' 2010-10-28 13:39:03 -02:00
Roberto Ierusalimschy
e642cc4206 correct handling of negative numbers in non-10 bases by 'tonumber'
(e.g., tonumber(-34, 8))
2010-10-28 13:36:30 -02:00
Roberto Ierusalimschy
da57477c3d added more platforms for ieeeendianess + small comments 2010-10-28 13:18:25 -02:00
Roberto Ierusalimschy
f39034889d stricter control over number of bits in each operation 2010-10-28 13:17:29 -02:00
Roberto Ierusalimschy
6b053a63cb added check for architectures with known endianess (only i386 now) 2010-10-27 15:16:37 -02:00
Roberto Ierusalimschy
572e5e6b28 new names for bit functions (mimicking assembler) 2010-10-27 14:50:32 -02:00
Roberto Ierusalimschy
6098e06e09 better organization for coercion functions between lua_Number and
integer types + IEEE trick to be used in most platforms, by default
2010-10-26 17:32:19 -02:00
Roberto Ierusalimschy
c6b64ffe65 new type lua_Unsigned and corresponding projection/injection functions 2010-10-25 18:31:11 -02:00
Roberto Ierusalimschy
4590a89b32 corrected warnings from different compilers (mostly casts and small
details)
2010-10-25 17:01:37 -02:00
Roberto Ierusalimschy
1475cb59bf version from lhf 2010-10-25 12:33:38 -02:00
Roberto Ierusalimschy
9e8e60dd5f bitlib renamed to 'bit32' + new function for arithmetic shift 2010-10-25 12:32:36 -02:00
Roberto Ierusalimschy
d72ec210c7 POS_A replaced by POS_Ax (which is more "precise") 2010-10-25 10:24:55 -02:00
Roberto Ierusalimschy
c77baf752c comment 2010-10-25 10:24:36 -02:00
Roberto Ierusalimschy
a122688091 better error message for 'lua -e -i' 2010-10-18 14:06:33 -02:00
Roberto Ierusalimschy
f3026c36c2 details in opcode list 2010-10-13 13:45:54 -03:00
Roberto Ierusalimschy
cd0ebd0a80 'proto->source' may be NULL (if dump strips debug information) 2010-10-11 17:24:42 -03:00
Roberto Ierusalimschy
8bc33a088c 'os.exit' acceps booleans as status (for EXIT_SUCESS and EXIT_FAILURE) 2010-10-05 09:18:03 -03:00
Roberto Ierusalimschy
c3eb89544f 'luaL_loadlib' accepts Utf8 BOM in the beginning of files 2010-10-01 15:53:00 -03:00
Roberto Ierusalimschy
ffff9a49da 'nresults' in CallInfo now refers to number of results that the current
function returns (and not what it expects from a call)
2010-09-30 14:21:31 -03:00
Roberto Ierusalimschy
b22356e5c5 hexadecimal constants may be floating values too 2010-09-13 18:49:58 -03:00
Roberto Ierusalimschy
a289a62717 'loadin' should not check whether upvalue is called '_ENV',
because its name may be unknown when there is no debug information.
2010-09-07 16:38:36 -03:00
Roberto Ierusalimschy
e3eabcf913 'lua_[gs]etupvalue' may work even without debug information
(that is, without upvalue names)
2010-09-07 16:35:04 -03:00
Roberto Ierusalimschy
0df2238063 name "_ENV" configurable through 'luaconf.h' 2010-09-07 16:21:39 -03:00
Roberto Ierusalimschy
6828f6d427 new parameter 'majorinc' to control frequency of major collections
in generational mode
2010-09-03 11:14:01 -03:00
Roberto Ierusalimschy
daa5fe3e31 'loadin' should accept any value for the environment (not only tables) +
it should check whether chunk has upvalue named '_ENV'
2010-08-23 15:03:11 -03:00
Roberto Ierusalimschy
8d9ea59d28 'pushclosure' -> 'codeclosure' (as there is another 'pushclosure' in
'lvm.c) + small detail
2010-08-23 14:32:34 -03:00
Roberto Ierusalimschy
5e7dbd0b8b api checks to ensure that thread is OK when using lua_call/lua_pcall 2010-08-04 15:40:28 -03:00
Roberto Ierusalimschy
cd6c276e41 use index 0 for header of list of free references 2010-08-03 17:21:16 -03:00
Roberto Ierusalimschy
fd4b4a2a68 detail: registry._PRELOAD must be a table, no need to check 2010-08-02 14:14:48 -03:00
Roberto Ierusalimschy
d447945685 'module'/'luaL_register' and associates are deprecated 2010-07-28 12:51:59 -03:00
Roberto Ierusalimschy
78f9635111 several new comments 2010-07-26 12:53:23 -03:00
Roberto Ierusalimschy
8b7cf8c62d 'lua_[gs]etenv' -> 'lua_[gs]etuservalue' 2010-07-25 12:18:19 -03:00
Roberto Ierusalimschy
73b0a3451d environment variables consulted by Lua may be version-specific 2010-07-25 12:03:37 -03:00
Roberto Ierusalimschy
85c1461422 new macros LUA_VERSION_{MAJOR/MINOR/RELEASE} 2010-07-25 12:02:41 -03:00
Roberto Ierusalimschy
5ba556d27a using curly brackets to mark blocks of '#if/#else/#endif's 2010-07-18 11:34:45 -03:00
Roberto Ierusalimschy
81dd13f4c6 new way to distinguish between indexing tables in registers and
tables in upvalues (+ fixed small bug when checking conflicts in
multiple assignments)
2010-07-07 13:27:29 -03:00
Roberto Ierusalimschy
6a02bbe1e2 better organization for fields in struct 'expdesc' 2010-07-02 17:42:40 -03:00
Roberto Ierusalimschy
7631c29b2f comand-line option '-l' creates global with given name after
requiring module
2010-07-02 14:36:32 -03:00
Roberto Ierusalimschy
a9dc7c8828 functions lua_tonumber/lua_tointeger replaced by lua_tonumberx/lua_tointegerx
that have an extra out parameter with conversion status
2010-07-02 14:35:06 -03:00
Roberto Ierusalimschy
7192afafee new module policy: C modules do not create globals and do not register
themselves with 'require' (let 'require' do its work); new auxiliary
functions luaL_newlib/luaL_newlibtable/luaL_setfuncs/luaL_requiref.
Old luaL_register will be deprecated.
2010-07-02 08:38:13 -03:00
Roberto Ierusalimschy
a139e2e003 old (and complex) luaL_findtable now used only in compatibility code
inside lauxlib.c
2010-06-30 14:40:27 -03:00
Roberto Ierusalimschy
a71c5f6f53 typo in comments 2010-06-30 11:11:17 -03:00
Roberto Ierusalimschy
d9ea6eca7c macro 'key2tal' replaced by 'gkey' (as both were equal) 2010-06-25 09:18:10 -03:00
Roberto Ierusalimschy
ca3865cf1b 'getlocal' gets information about parameters of Lua functions 2010-06-21 13:30:12 -03:00
Roberto Ierusalimschy
bef5980744 no more support for old Mac OS systems 2010-06-18 14:23:02 -03:00
Roberto Ierusalimschy
409741e900 'what' may be NULL in 'kname' 2010-06-16 10:44:36 -03:00
Roberto Ierusalimschy
b98de30b8f 'ipair' is back 2010-06-13 16:41:34 -03:00
Roberto Ierusalimschy
9f48712c15 use ANSI versions of DLL functions in Windows 2010-06-13 16:36:17 -03:00
Roberto Ierusalimschy
bd262d591f 'coroutine' library separated from 'baselib' 2010-06-10 18:30:26 -03:00
Roberto Ierusalimschy
0d116c3ada unused '#include' removed 2010-06-10 18:27:09 -03:00
Roberto Ierusalimschy
79f11fb2bb back with #-comments for binary files 2010-06-09 14:53:59 -03:00
Roberto Ierusalimschy
fabe4ec487 better barrier for prototypes 2010-06-07 13:55:34 -03:00
Roberto Ierusalimschy
575074fd85 Lua closures are cached for reuse 2010-06-04 10:25:10 -03:00
Roberto Ierusalimschy
545f43065f 'luaF_newLclosure' gets prototype of new closure as argument 2010-06-04 10:06:15 -03:00
Roberto Ierusalimschy
3819c30e55 better names for barrier macros 2010-06-04 10:05:29 -03:00
Roberto Ierusalimschy
e94fac8956 bug: generational collection was not running collector! (must write
a test for this...)
2010-06-02 15:36:58 -03:00
Roberto Ierusalimschy
2c1a5d678d factoring out common code in 'module' and 'luaL_openlib' 2010-05-31 13:34:19 -03:00
Roberto Ierusalimschy
bd619b9311 new macro MAXUPVAL (maximum number of upvalues per closure) 2010-05-31 13:08:55 -03:00
Roberto Ierusalimschy
aca84ee1a0 correct definition for 'lua_cpcall' (tested) 2010-05-28 11:27:07 -03:00
Roberto Ierusalimschy
5038e3c58c corrected compatibility macro 'lua_cpcall' (untested) 2010-05-27 09:06:42 -03:00
Roberto Ierusalimschy
5a7dee0c5d added class '%g' in patterns (for graphical characters) 2010-05-24 16:34:57 -03:00
Roberto Ierusalimschy
ddf1f2a053 GC should not run when stopped, even in hard tests 2010-05-24 16:29:46 -03:00
Roberto Ierusalimschy
e34d3c06b0 it is better to call open functions with lua_call to not mess
the caller stack
2010-05-20 09:57:59 -03:00
Roberto Ierusalimschy
e8a2c36909 more comments 2010-05-18 14:32:19 -03:00
Roberto Ierusalimschy
3c39a0e8cb bug: loadfile of binary files read first character twice 2010-05-18 14:21:24 -03:00
Roberto Ierusalimschy
3d45a8eb1c really stop collection during finalizers 2010-05-17 17:39:31 -03:00
Roberto Ierusalimschy
3d80aeab5a lua_pushstring may reallocate the stack, making 'o' a dangling
pointer
2010-05-17 17:10:17 -03:00
Roberto Ierusalimschy
3811e23b32 detail (comment) 2010-05-17 15:30:27 -03:00
Roberto Ierusalimschy
12c764ed1e semicolons now represent the empty statement 2010-05-15 10:32:02 -03:00
Roberto Ierusalimschy
e99e9a9473 patches for last two bugs (string.format and io.read) 2010-05-14 12:34:57 -03:00
Roberto Ierusalimschy
f35ac38e1d updated depenency lists + eliminated duplication of definitions
for MYCFLAGS, MYLDFLAGS, and MYLIBS.
2010-05-14 12:08:10 -03:00
Roberto Ierusalimschy
058279d548 comments 2010-05-14 12:03:43 -03:00
Roberto Ierusalimschy
69ba1ac441 new "instruction" 'absindex' 2010-05-14 10:15:54 -03:00
Roberto Ierusalimschy
4a925c1552 in 'absindex', do not need to call gettop (can inline it) 2010-05-14 10:15:26 -03:00
Roberto Ierusalimschy
cf531912f2 one more macro (mvdispatch) to easy experiments with alternative
dispatch methods
2010-05-13 16:53:05 -03:00
Roberto Ierusalimschy
0d00729e31 detail (breaking a long line) 2010-05-13 09:03:26 -03:00
Roberto Ierusalimschy
b6e9fcbd70 use of macro ('vmcase') to format all cases in main switch of
'luaV_execute' (to facilitate experiences with direct threading)
2010-05-12 17:40:35 -03:00
Roberto Ierusalimschy
8554baeacf small changes in 'luaV_execute' to make cases more regularly formatted 2010-05-12 17:31:33 -03:00
Roberto Ierusalimschy
f5b7f077ec added comments to '#else' and '#endif' in long conditionals 2010-05-12 11:17:36 -03:00
Roberto Ierusalimschy
e924a7f9ea new API function 'lua_absindex' 2010-05-12 11:09:20 -03:00
Roberto Ierusalimschy
4fd76b8148 avoid "strong" cast 2010-05-11 17:49:26 -03:00
Roberto Ierusalimschy
de0f51a02c wrong type being assigned (not detected because of obj2gco macro) 2010-05-11 17:48:36 -03:00
Roberto Ierusalimschy
0567221848 udata in 'tobefnz' list be have old bit on (it will be cleared
when udata is moved to 'allgc' list)
2010-05-10 15:24:36 -03:00
Roberto Ierusalimschy
1c1a98e872 corrected some places where an old object could end up in front
of a new one + minimal documentation about this problem
2010-05-10 15:23:45 -03:00
Roberto Ierusalimschy
c006f085d9 new macro 'resetoldbit' 2010-05-10 13:46:49 -03:00
Roberto Ierusalimschy
a48e330f37 macros 'lua_number2int' and 'lua_number2uint' for Visual Studio
corrected and tested
2010-05-10 13:38:58 -03:00
Roberto Ierusalimschy
dcc070683c avoid reserving LUA_RIDX_LAST slots in any table used by reference
system. Store free list in a field indexed by a unique name,
instead of using a numerical index.
2010-05-10 12:25:02 -03:00
Roberto Ierusalimschy
2d81cfa4e1 corrected definition of 'lua_register' (there is no LUA_ENVIRONINDEX
anymore)
2010-05-10 10:50:20 -03:00
Roberto Ierusalimschy
0bccf03d7e slightly better definition for 'changenvalue' 2010-05-07 15:44:46 -03:00
Roberto Ierusalimschy
ad2b5decc8 'lua_assert' can be empty when assertions are off 2010-05-07 15:44:12 -03:00
Roberto Ierusalimschy
32c1764b5d slightly better definition for 'isgray' 2010-05-07 15:43:51 -03:00
Roberto Ierusalimschy
de97177744 avoid 'else assert' (which may result in an empty else) 2010-05-07 15:43:24 -03:00
Roberto Ierusalimschy
fa2ddb070a details (to avoid too long strings in assertions) 2010-05-07 15:23:17 -03:00
Roberto Ierusalimschy
0fac33da9e bug: incremental sweep was not cleaning old bits (as it stopped in the
first old object) + bug: moving udata to 'udgc' list might put old
object in front a new one + some new macros + generational mode may
be in 'pause' state (it just skips 'markroot')
2010-05-07 15:19:36 -03:00
Roberto Ierusalimschy
8e1bdda66a stupid bug when calling 'luaC_changemode' (in function lua_gc) 2010-05-07 15:10:01 -03:00
Roberto Ierusalimschy
9c1347e647 more tests in 'lua_checkmemory' + more information in function
'gccolor'
2010-05-07 15:09:23 -03:00
Roberto Ierusalimschy
b373a40133 new macro 'isgenerational' + new macro 'isold' + better deffinition
for 'isdead', compatible with the code used by 'sweeplist'
2010-05-07 15:08:05 -03:00
Roberto Ierusalimschy
25951e0ea5 some cleaning in 'sweeplist' (threads do not need to be traversed
if they are going to be collected + use of bit masks to unify
differences in generational and incremental modes)
2010-05-06 15:18:07 -03:00
Roberto Ierusalimschy
a4f20e3c8b comments 2010-05-06 15:17:22 -03:00
Roberto Ierusalimschy
8c583c61a3 more tests in 'lua_checkmemory' 2010-05-06 15:16:57 -03:00
Roberto Ierusalimschy
d2ea5b00b7 new function 'luaC_changemode' +
bug: objects entering the 'allgc' list must have their OLDBIT cleared
(upvalues being cleared) + bug: in 'checkSizes', KGC_EMERGENCY is
stored in 'gckind' field, not in 'gcstate' + current white changes when
entering sweep phase (so there are dead objects only in that phase)
2010-05-05 15:58:36 -03:00
Roberto Ierusalimschy
d77898597e new function 'luaC_changemode' 2010-05-05 15:53:41 -03:00
Roberto Ierusalimschy
237f755dca typos in comments 2010-05-05 15:49:56 -03:00
Roberto Ierusalimschy
7444b5a1d5 better documentation of GC costs 2010-05-05 10:39:58 -03:00
Roberto Ierusalimschy
e7ce7e1850 changes in patch to monitor garbage collection 2010-05-04 15:10:02 -03:00
Roberto Ierusalimschy
3e662cec89 full GC must run finalizers only after finishing everything else
(including a return to generational mode if needed)
2010-05-04 15:09:06 -03:00
Roberto Ierusalimschy
fde866e303 details (comments) 2010-05-04 14:25:19 -03:00
Roberto Ierusalimschy
2d7a81a204 missing parentheses in declaration 2010-05-04 14:21:08 -03:00
Roberto Ierusalimschy
658ea8752b no need to handle '\0' differently from other control chars in
format '%q'
2010-05-04 14:20:33 -03:00
Roberto Ierusalimschy
aa73403ba4 no need of a KGC_FORCED collection kind; it has the same behavior of
a normal collection
2010-05-03 14:39:48 -03:00
Roberto Ierusalimschy
0c27de2e7b no more 'finalize' phase in GC; finalizers are called along the
entire cycle
2010-05-03 14:33:39 -03:00
Roberto Ierusalimschy
d25f7f9d78 items in 'tobefnz' are kept black (as before recent change) and changed
to white only when needed (being moved to 'allgc' when not keeping
invariant).
2010-05-03 08:55:40 -03:00
Roberto Ierusalimschy
85555646e3 invariant must be kept in atomic 'phase' too 2010-05-03 08:24:30 -03:00
Roberto Ierusalimschy
4d871ee973 "gray lists" only need to be valid when 'keepinvariant' is true 2010-04-30 15:37:14 -03:00
Roberto Ierusalimschy
b9e1dec2cb added comment explaining a bit about the invariants of the collector 2010-04-30 15:36:45 -03:00
Roberto Ierusalimschy
dc2b8a0073 detail 2010-04-30 15:36:22 -03:00
Roberto Ierusalimschy
9a9fe42deb wrong comment 2010-04-30 15:17:24 -03:00
Roberto Ierusalimschy
0062db1e06 default PAUSE should be 200 (differences may be corrected in
internal multiplers)
+ check for unbilt stack equal the one used by lgc.c
2010-04-30 11:22:23 -03:00
Roberto Ierusalimschy
23001d8607 nasty GC bug: upvalue must be turned white when not keeping invariant,
but barrier was not being called when uv->v were already white.
2010-04-29 18:43:36 -03:00
Roberto Ierusalimschy
5d79c6684b removed commented-out debugging code 2010-04-29 18:42:33 -03:00
Roberto Ierusalimschy
3410dcd375 new way to control GC speed 2010-04-29 14:35:10 -03:00
Roberto Ierusalimschy
5a7a0c72d8 'luaC_linkupval' embedded into call site 2010-04-29 14:34:35 -03:00
Roberto Ierusalimschy
ee7478e884 improved 'lua_checkmemory', with better control over gray objects 2010-04-29 14:33:51 -03:00
Roberto Ierusalimschy
aaa5d7adab 'luaC_linkupval' moved into 'lfunc.c' code + new way to control GC speed 2010-04-29 14:32:40 -03:00
Roberto Ierusalimschy
3eb1788bb4 new way to control GC speed (keeping a 'debt' counter) 2010-04-29 14:31:31 -03:00
Roberto Ierusalimschy
00114a95b2 lots of new comments + small changes in loop controls + other small
"janitor work"
2010-04-26 14:58:00 -03:00
Roberto Ierusalimschy
4aaf0ef75c "to-be-finalized" objects marked and sweeped like all other objects 2010-04-20 17:15:30 -03:00
Roberto Ierusalimschy
ed720d09f3 upvalue barriers for Lua functions must act on the upvalue itself,
not on its closure
2010-04-20 17:14:50 -03:00
Roberto Ierusalimschy
376e939ef6 missing parentheses around 'luaL_pushresultsize' declaration 2010-04-19 15:52:15 -03:00
Roberto Ierusalimschy
9d28e2b3e5 bug with io.read(op, "*n") 2010-04-19 15:04:58 -03:00
Roberto Ierusalimschy
49ca1f7083 allows thread switches (when/if there are thread switches) in the same
places that finalizers can run (so they should be safe...)
2010-04-19 14:58:46 -03:00
Roberto Ierusalimschy
4db6f20770 ensure that 'luai_userstatethread' is always called (even if
'stack_init' throws a memory error)
2010-04-19 14:40:13 -03:00
Roberto Ierusalimschy
cca71912e6 'gcinfo' was deprecated in version 5.0. 2010-04-19 14:02:02 -03:00
Roberto Ierusalimschy
8003e9544d 'string.format' may get buffer as an argument when there are
missing arguments and format string is too long
2010-04-19 13:39:25 -03:00
Roberto Ierusalimschy
973d81efb3 complete control over number of each kind of object allocated 2010-04-19 13:38:25 -03:00
Roberto Ierusalimschy
26d4a73962 with light C functions, 'pairs' does not need to keep 'next' as an
upvalue.
2010-04-19 13:36:06 -03:00
Roberto Ierusalimschy
99a39f6f4a tells the allocation function that the first block is a thread 2010-04-19 13:34:46 -03:00
Roberto Ierusalimschy
1bb407e494 in lua_gc/step, 'luaC_step' changes GCthreshold, so there was little
control over the real step size.
2010-04-19 13:33:19 -03:00
Roberto Ierusalimschy
53f9499f7f "light C function" is a better name than "C-function pointer" 2010-04-18 10:22:48 -03:00
Roberto Ierusalimschy
575befc394 comparsion tag methods follow the same rule as other binary TMs 2010-04-18 10:15:11 -03:00
Roberto Ierusalimschy
e7ffb1b501 macro LUA_USE_LONGJMP allows choosing longjmp when compiling Lua as
C++ code
2010-04-18 09:41:35 -03:00
Roberto Ierusalimschy
c066ac10a9 better line numbers for function calls and unary/binary operators +
null statement + no more "ambiguous syntax" restriction
2010-04-17 09:46:32 -03:00
Roberto Ierusalimschy
1e6940f291 'gcstate' now also runs collector until given state + small changes
in 'testC' to test 'lua_topointer' and 'lua_tocfunction'
2010-04-16 14:42:49 -03:00
Roberto Ierusalimschy
d8d81ba891 new escape sequence '\*' + several comments + moving options from
switch default into cases (as now locale is fixed)
2010-04-16 09:31:07 -03:00
Roberto Ierusalimschy
cf22133b69 no need to avoid calling ctype functions as now they are implemented
by us (no inefficiencies due to accessing locale information)
2010-04-15 16:44:43 -03:00
Roberto Ierusalimschy
b7be05ad27 invalid instructions "cannot" happen 2010-04-15 16:43:43 -03:00
Roberto Ierusalimschy
afdb19ac82 no more 'ccall' nor 'cpcall' functions. (With light C functions they
are obsolete.)
2010-04-14 12:14:21 -03:00
Roberto Ierusalimschy
7dfa4cd655 first implementation of light C functions 2010-04-14 12:13:48 -03:00
Roberto Ierusalimschy
fc6203ee43 BUG: 'string.format' may get buffer when there are missing arguments 2010-04-12 13:13:02 -03:00
Roberto Ierusalimschy
b2dd246b7a better control in 'totalmem' over choosing counters 2010-04-12 13:07:39 -03:00
Roberto Ierusalimschy
d20ff60615 new macro LUA_NUMTAGS 2010-04-12 13:07:29 -03:00
Roberto Ierusalimschy
d41b467320 check memory allows strings to live in the main GC list (it should
work ok).
2010-04-12 09:42:07 -03:00
Roberto Ierusalimschy
4541243355 patterns now accept '\0' as a regular character 2010-04-12 09:00:50 -03:00
Roberto Ierusalimschy
9100f7479a new implementation for Generic Buffer manipulation (using userdata as
temporary buffer space)
2010-04-09 13:14:46 -03:00
Roberto Ierusalimschy
055104f5b6 keep memory-error message in the global state, so that its use
does not depend on Lua internalizing strings to avoid a string
creation on memory errors
2010-04-08 14:16:46 -03:00
Roberto Ierusalimschy
28aa733c15 macro 'eqstr' was being used to compare non-string entities 2010-04-08 14:06:33 -03:00
Roberto Ierusalimschy
6abde1b05a no need to keep "_ENV" name in global state (can be kept in lex state) 2010-04-05 13:35:37 -03:00
Roberto Ierusalimschy
d394d5536a new macro 'eqstr' 2010-04-05 13:26:37 -03:00
Roberto Ierusalimschy
a2f98314a3 'lua_pushstring' now uses 'luaS_new' 2010-04-05 11:21:38 -03:00
Roberto Ierusalimschy
a09c8d7beb cannot sweep main thread in sweepstring phase 2010-04-05 11:15:35 -03:00
Roberto Ierusalimschy
f80ff7a336 'luaS_new' changed from macro to function 2010-04-03 17:24:18 -03:00
Roberto Ierusalimschy
a08fc34ee4 avoid using 'luaS_new' when can use 'luaS_newlstr' 2010-04-02 12:39:07 -03:00
Roberto Ierusalimschy
d00d2eaf51 small changes in 'luaO_pushvfstring' 2010-04-02 12:30:27 -03:00
Roberto Ierusalimschy
11126422d9 option to return GC to normal (incremental, non generational) mode 2010-04-02 12:19:19 -03:00
Roberto Ierusalimschy
e54668b696 added proper code to trace garbage collection 2010-04-02 11:37:41 -03:00
Roberto Ierusalimschy
9eb832de54 work related to hooks moved from 'luaV_execute' to 'traceexec' 2010-03-29 17:45:49 -03:00
Roberto Ierusalimschy
82a1f5d354 comments 2010-03-29 14:44:31 -03:00
Roberto Ierusalimschy
a8d3aa14fd global table now is only kept in the registry 2010-03-29 14:43:14 -03:00
Roberto Ierusalimschy
064e406f67 no more fenvs! 2010-03-26 17:58:11 -03:00
Roberto Ierusalimschy
5c87f61e6b major collections in generational mode 2010-03-25 16:37:23 -03:00
Roberto Ierusalimschy
3aa9598177 'mainthread' is not inserted in the 'allgc' list anymore, but swept
separately.
2010-03-25 10:06:36 -03:00
Roberto Ierusalimschy
64d39ed1b6 generational mode no longer sweep old objects 2010-03-24 12:51:10 -03:00
Roberto Ierusalimschy
4433dbb5f5 userdata with finalizers are kept in a separated list ('udgc'), instead
of at the end of 'rootgc' (which was renamed to 'allgc', as it is not
"root" in the usual meaning for collectors)
2010-03-24 10:07:01 -03:00
Roberto Ierusalimschy
5cb128ea54 BUG: emergency collector might resize 'strt' (string table) when
creating a new string
+ atomic and markroot steps has some cost
+ full collection must leave collector in proper state when mode
is generational
2010-03-23 17:16:06 -03:00
Roberto Ierusalimschy
74123e9686 draft version of a generational mode for garbage collection. (Not well
tested; no major collections; ...)
2010-03-22 15:28:03 -03:00
Roberto Ierusalimschy
9c196bebad detail (wrong comment about LUAI_GCPAUSE) 2010-03-22 14:45:55 -03:00
Roberto Ierusalimschy
28b2566c97 'lua_assert' not visible from libraries 2010-03-22 14:28:31 -03:00
Roberto Ierusalimschy
caf74dd731 'cpcall' renamed to 'ccall' as it does not do a protected call 2010-03-19 18:04:17 -03:00
Roberto Ierusalimschy
62840c5fad 'ipairs' is deprecated 2010-03-19 12:52:48 -03:00
Roberto Ierusalimschy
5ca7cdd709 for compatibility only: 'module' changes the first upvalue of
calling function to affect its environment
2010-03-19 12:02:34 -03:00
Roberto Ierusalimschy
1514e49d43 avoid using function environments in C libraries (as it probably will
be deprecated)
2010-03-17 18:37:37 -03:00
Roberto Ierusalimschy
22ef84b6c8 '_ENV' name permanently stored in global state for easier access 2010-03-13 12:55:42 -03:00
Roberto Ierusalimschy
63a2b62468 must include 'string.h' because a macro uses 'strlen' 2010-03-13 12:55:01 -03:00
Roberto Ierusalimschy
489253d753 better definitions for lua_[gs]etglobal + less uses of ENVIRONINDEX 2010-03-13 00:57:46 -03:00
Roberto Ierusalimschy
25c557ec63 first version of _ENV; no more global variables 2010-03-12 16:14:06 -03:00
Roberto Ierusalimschy
f292760f12 small optimization in luaL_addlstring (avoid adding chars one by one)
(suggested by Chuck Coffing)
2010-03-12 15:59:32 -03:00
Roberto Ierusalimschy
1124cb1247 first step towards _ENV: all chunks have an puvalues _ENV with the
global table
2010-03-08 13:55:52 -03:00
Roberto Ierusalimschy
c295147874 when finding a 'name' for a function, handle the case when the function
is a for iterator
2010-03-05 11:01:29 -03:00
Roberto Ierusalimschy
e560ac4862 when searching for a variable name, look existing upvalues before
goingg to upper levels
2010-03-04 15:12:57 -03:00
Roberto Ierusalimschy
915a9a912c just in case, better to flush error messages 2010-03-03 15:53:02 -03:00
Roberto Ierusalimschy
ae0a5e2142 new option '*L' for io.read + options for io.lines 2010-03-03 15:48:57 -03:00
Roberto Ierusalimschy
347f0c33d1 avoid 'continue' unless necessary 2010-02-27 18:16:24 -03:00
Roberto Ierusalimschy
622e448710 removed useless test (argv[i] cannot be NULL when i<argc) 2010-02-27 18:15:36 -03:00
Roberto Ierusalimschy
0fe2576a39 new instructions to optimize indexing on upvalues 2010-02-26 17:40:29 -03:00
Roberto Ierusalimschy
d08d237a49 detail: in loadfile read function, no need to return NULL on EOF;
size ==0 is enough to signal EOF.
2010-02-18 17:37:57 -02:00
Roberto Ierusalimschy
64a7ec987c avoid using 'ungetc' in loadfile 2010-02-18 17:32:41 -02:00
Roberto Ierusalimschy
4274738e81 new macro 'luai_writestringerror' 2010-02-18 17:18:41 -02:00
Roberto Ierusalimschy
0d7d559dcc no need to flush either stderr or \n-terminated outputs 2010-02-11 15:12:27 -02:00
Roberto Ierusalimschy
af512ad6da use of 'conventional' names for shift and rotate operations +
right/left versions for them
2010-02-11 13:55:29 -02:00
Roberto Ierusalimschy
d27108ccd5 removed support for '#fist-line comment' on binary files (as binary
files do not have lines...)
2010-02-11 13:52:50 -02:00
Roberto Ierusalimschy
a838b3b496 better usage messages, showing entire offending argument 2010-02-09 09:58:57 -02:00
Roberto Ierusalimschy
4c54cd3a10 when yielding, original 'func' value must be kept and restored so
that 'poscall' puts results in the right slot.
2010-02-09 09:56:29 -02:00
Roberto Ierusalimschy
c8ff7de7f0 field 'oldtop' renamed to 'extra', as it can be used for other
purposes
2010-02-09 09:55:37 -02:00
Roberto Ierusalimschy
3bae8e047c typo (thanks to Gavin) 2010-02-05 17:09:09 -02:00
Roberto Ierusalimschy
4f5f2fe367 new function 'luaL_cpcall' 2010-01-21 14:49:21 -02:00
Roberto Ierusalimschy
01586d539e typo in comment 2010-01-21 14:31:24 -02:00
Roberto Ierusalimschy
c8ab34ab7a better messages for invalid options 2010-01-21 14:31:06 -02:00
Roberto Ierusalimschy
36ab1ee10c __unm metamethod gets nil as its 2nd parameter 2010-01-15 14:23:58 -02:00
Roberto Ierusalimschy
193ce46970 table.pack was locking last result, avoiding its collection 2010-01-13 17:59:10 -02:00
Roberto Ierusalimschy
b678f246a4 HINSTANCE -> HMODULE (they are the same thing, but the MS documentation
uses the latter) + LoadLibrary -> LoadLibraryEx with optional arguments,
to allow the option LOAD_WITH_ALTERED_SEARCH_PATH
2010-01-13 14:30:27 -02:00
Roberto Ierusalimschy
f270e7f044 warnings that are not compatible with C++ separated from other warning
options
2010-01-13 14:19:54 -02:00
Roberto Ierusalimschy
070d3743a7 "no value" added to array luaT_typenames + occurrences of "userdata"
in that array unified in a single address
2010-01-13 14:18:25 -02:00
Roberto Ierusalimschy
0c7de97d47 correct error message when yielding from outside a coroutine 2010-01-13 14:17:32 -02:00
Roberto Ierusalimschy
900b7d4514 on 64-bit machines, an address may not fit into a 'long', so it
is better to convert from pointer to void to pointer to function
directly, even if ANSI C does not like it.
2010-01-13 14:09:05 -02:00
Roberto Ierusalimschy
91f0b20a0e missing standard defines 2010-01-12 17:40:02 -02:00
Roberto Ierusalimschy
e4b4623abc 'searchpath' changes dots into directory separators 2010-01-11 15:55:25 -02:00
Roberto Ierusalimschy
cef96b73e1 added casts from int to enumerations to follow C++ rules 2010-01-11 15:38:30 -02:00
Roberto Ierusalimschy
427e01eb63 removed useless initialization 2010-01-11 15:37:59 -02:00
Roberto Ierusalimschy
d320c908d0 conversion from pointer to void to pointer to function seems more
"correct" if done through an integral type (because conversions
between pointers and numbers are allowed, only "implementation
defined").
2010-01-11 15:34:59 -02:00
Roberto Ierusalimschy
8bfc696676 missing 'external' in variable declaration 2010-01-11 15:33:09 -02:00
Roberto Ierusalimschy
97a35e70af pathes corrected to 5.2 2010-01-11 15:15:30 -02:00
Roberto Ierusalimschy
03b556b963 corrected copyright notice to 2010 2010-01-11 15:15:11 -02:00
Roberto Ierusalimschy
572b94bbcb include of 'windows.h' moved to where it is needed 2010-01-11 15:11:24 -02:00
Roberto Ierusalimschy
692209fa8d Dynamic C functions should be created with the global table as their
initial environments
2010-01-11 15:06:31 -02:00
Roberto Ierusalimschy
953d499ea2 changed macro lua_number2int for Windows (added brackets; some recent
compilers complain about the old format) + added missing definition
for 'lua_number2int' in Windows case.
2010-01-11 14:35:20 -02:00
Roberto Ierusalimschy
a541ada194 "-"-trick in C packages now accept name-v13... 2010-01-11 14:10:47 -02:00
Roberto Ierusalimschy
55d3138397 removed old prototype for 'luaI_openlib' (which does not exist anymore) 2010-01-11 14:00:45 -02:00
Roberto Ierusalimschy
e74e56f2b1 better may to force recompilation when makefile changes 2010-01-08 18:05:36 -02:00
Roberto Ierusalimschy
1ebf109c53 'setobj' must assing fields one by one, to allow trick of using
pad space in table keys
2010-01-08 18:00:20 -02:00
Roberto Ierusalimschy
f75be1cb28 removed parentheses around some function names in their definitions 2010-01-08 13:16:56 -02:00
Roberto Ierusalimschy
16d2ad88fe some changes in compatibility macros: added LUA_COMPAT_ALL + compatibility
macros from lua.h and lauxlib.h moved to luaconf.h
2010-01-06 13:15:04 -02:00
Roberto Ierusalimschy
f3a6815000 compatibility code removed or moved to luaconf.h 2010-01-06 13:14:15 -02:00
Roberto Ierusalimschy
19f8c87375 compatibility code moved to luaconf.h 2010-01-06 13:08:00 -02:00
Roberto Ierusalimschy
5bcfe0c700 new debug info 'isvararg' and 'nparams' 2010-01-06 12:42:35 -02:00
Roberto Ierusalimschy
8cd395564c no need to use two different defines (LUA_DL_DLOPEN and LUA_USE_DLOPEN) 2010-01-06 12:35:17 -02:00
Roberto Ierusalimschy
389c890ed3 again changing macro to function to save a few bytes 2010-01-06 09:48:02 -02:00
Roberto Ierusalimschy
e3866afa97 macro 'luaY_checklimit' changed into a function (and renamed 'checklimit').
It makes no sense to trade space for time in the parser.
2010-01-05 16:46:58 -02:00
Roberto Ierusalimschy
25189b420d field 'nups' in struct 'lua_Debug' changed from 'int' to 'unsigned
char' to save some space (even C functions cannot have more than
maxchar upvalues).
2010-01-05 16:33:26 -02:00
Roberto Ierusalimschy
cec25167d1 new api_check that 'pcallk' cannot be called inside hooks 2010-01-04 16:17:51 -02:00
Roberto Ierusalimschy
1fd4c482a0 reorganization of switch in function 'match' (details) 2010-01-04 14:37:19 -02:00
Roberto Ierusalimschy
35e729fa6d comments + small details 2010-01-04 14:36:39 -02:00
Roberto Ierusalimschy
0dc09cb42e 'unpack' moved to table library (and therefore "renamed" to
'table.unpack'.
2009-12-28 14:30:31 -02:00
Roberto Ierusalimschy
cc1cbd19a0 'lua_cpcall' is deprecated + other small changes in 'pmain' (comments
and reordering to check arguments before running any Lua code)
2009-12-22 14:47:12 -02:00
Roberto Ierusalimschy
cb3f95d516 'lua_cpcall' is deprecated 2009-12-22 14:47:00 -02:00
Roberto Ierusalimschy
f84b575cfa no more pseudoindex LUA_GLOBALSINDEX; global table now accessible
through registry
2009-12-22 13:32:50 -02:00
Roberto Ierusalimschy
3cb343efd6 code for error message for 'setn' removed 2009-12-18 14:53:12 -02:00
Roberto Ierusalimschy
ec0fc1a13b missing parentheses around 'lua_version' + moving typdef's before
the extra include
2009-12-18 13:32:36 -02:00
Roberto Ierusalimschy
c3a6f3fa1c 'lua_objlen' replaced by 'lua_rawlen', 'lua_len', and 'luaL_len' 2009-12-17 14:20:01 -02:00
Roberto Ierusalimschy
0bbdddc86b allocator function receives the tag of object being allocated in 'osize'
when 'ptr' is NULL.
2009-12-17 13:46:44 -02:00
Roberto Ierusalimschy
b3b8dfaaea yet more options moved from luaconf.h into internal files 2009-12-17 11:08:51 -02:00
Roberto Ierusalimschy
adc6a4865b macro name change: LUA_INIT->LUA_INIT_VAR 2009-12-17 11:07:41 -02:00
Roberto Ierusalimschy
2108754e46 macro name change: LUA_PATH->LUA_PATH_VAR, LUA_CPATH->LUA_CPATH_VAR,
LUA_PATHSEP->LUA_PATH_SEP, LUA_EXECDIR->LUA_EXEC_DIR
2009-12-17 11:06:47 -02:00
Roberto Ierusalimschy
46f1429936 more options moved from luaconf.h into internal files 2009-12-17 10:50:20 -02:00
Roberto Ierusalimschy
e0f9d1c8f5 removed export of function only for coco 2009-12-17 10:28:57 -02:00
Roberto Ierusalimschy
de6fc75d63 several configuration options that do not change often moved out of
luaconf.h and into more internal files
2009-12-17 10:26:09 -02:00
Roberto Ierusalimschy
2af0d3b459 allocator function receives the tag of object being allocated in 'osize'
when 'ptr' is NULL.
2009-12-16 14:42:58 -02:00
Roberto Ierusalimschy
9fbe0690fb base-level C use global table as its environment 2009-12-15 09:25:36 -02:00
Roberto Ierusalimschy
a25b8ff69c detail ('lua_tolstring' instead of lua_objlen) 2009-12-15 09:25:16 -02:00
Roberto Ierusalimschy
15b823ce4f cleaner way to add extra space in a lua state. 2009-12-14 13:27:30 -02:00
Roberto Ierusalimschy
8da245bfd2 better to keep GC state numbers sequential, to optimize switch in
'singlestep'
2009-12-11 19:31:14 -02:00
Roberto Ierusalimschy
a2a2abcba4 new function 'luaC_runtilstate' to advance GC until a "valid" state 2009-12-11 17:14:59 -02:00
Roberto Ierusalimschy
2e51792596 avoid using deprecated macros lua_[gs]etglobal 2009-12-11 11:40:44 -02:00
Roberto Ierusalimschy
3a9ae612a4 macro 'ngcotouv' is the same as 'gco2uv', so it was removed 2009-12-11 11:39:34 -02:00
Roberto Ierusalimschy
9db693a57c detail (comment) 2009-12-10 17:00:33 -02:00
Roberto Ierusalimschy
1375435e4a several new features in testC to allow better testing of lua_resume
at the C API level
2009-12-10 16:21:28 -02:00
Roberto Ierusalimschy
2bb19ccf08 reordering of some functions + cleaner way to code lua_resume/resume +
small bug in lua_resume (in case of calling errors lua_resume should
remove only new arguments from the stack and push error message).
2009-12-10 16:20:07 -02:00
Roberto Ierusalimschy
64d5df7772 detail (lua_resume should empty coroutine stack even if they do not
fit into caller stack)
2009-12-10 16:17:37 -02:00
Roberto Ierusalimschy
2643da67c6 error messages from 'lua_resume' must be generated in protected mode,
to avoid raising memory errors
2009-12-08 16:59:24 -02:00
Roberto Ierusalimschy
ed117bb42a lua_checkstack does not raise memory errors (instead it signals them) 2009-12-08 14:15:43 -02:00
Roberto Ierusalimschy
a4472490bc new 'table.pack' function 2009-12-07 13:50:27 -02:00
Roberto Ierusalimschy
86312e1a7d lua_objlen calls __len metamethod on tables (if present) 2009-12-07 13:49:47 -02:00
Roberto Ierusalimschy
df1dc3f1f5 strings in C scripts may be delimited by quotes + new functionality to
set C scripts as C hooks
2009-12-01 14:49:48 -02:00
Roberto Ierusalimschy
513d0258d9 details 2009-12-01 14:31:04 -02:00
Roberto Ierusalimschy
cfa8bc3ca4 continuations may be upvalues too 2009-11-27 13:39:31 -02:00
Roberto Ierusalimschy
a654e82f5c coroutines may have C bodies 2009-11-27 13:38:51 -02:00
Roberto Ierusalimschy
3e41afcec5 extra api checks for number of returns of C functions and for lua_yield 2009-11-27 13:37:59 -02:00
Roberto Ierusalimschy
3acf5ec5a1 update of file dependencies (gcc -MM) 2009-11-27 12:39:31 -02:00
Roberto Ierusalimschy
93695db903 'table.maxn' deprecated 2009-11-26 15:35:13 -02:00
Roberto Ierusalimschy
9107dd115c no more compatibility code for 'string.gfind' 2009-11-26 14:49:28 -02:00
Roberto Ierusalimschy
dc4c459546 a few new warnings 2009-11-26 14:36:55 -02:00
Roberto Ierusalimschy
19a6c38745 detail in 'currentpc' (only needs to work for Lua functions) 2009-11-26 13:34:15 -02:00
Roberto Ierusalimschy
3c4d970a7b comment typos 2009-11-26 09:39:20 -02:00
Roberto Ierusalimschy
b0f2b288a6 new scheme for debug info about tail calls: no more 'fake' stack entries,
but stack entry knows whether it was tail called
2009-11-25 13:27:51 -02:00
Roberto Ierusalimschy
2b25489b47 'notail' -> 'noextrachars' ('notail' may confuse with tail calls) 2009-11-24 16:05:12 -02:00
Roberto Ierusalimschy
a6f465f558 new mark LUAMOD_API for all luaopen_* functions 2009-11-24 10:05:44 -02:00
Roberto Ierusalimschy
9a41506b8f 'os.exit' should close state only when second argument is true 2009-11-23 16:20:38 -02:00
Roberto Ierusalimschy
9a6d9ea57a GC may get stuck during a parser and avoids proper resizing of the
string table, making its lists grow too much and degrading performance.
2009-11-23 12:59:30 -02:00
Roberto Ierusalimschy
062e809e54 new macros 'LUAI_DDEC'/'LUAI_DDEF' to better control declarations and
definitions of non-static variables
2009-11-19 17:06:52 -02:00
Roberto Ierusalimschy
b4c1824824 'luaV_arith' must be marked 'LUAI_FUNC' (as all non-static functions) 2009-11-19 17:04:58 -02:00
Roberto Ierusalimschy
2e5ef6a9fb new macro 'isdummy' 2009-11-19 15:54:07 -02:00
Roberto Ierusalimschy
1dea393058 small corrections for 'luaall.c' 2009-11-19 14:26:52 -02:00
Roberto Ierusalimschy
45dec34597 comments 2009-11-19 14:26:29 -02:00
Roberto Ierusalimschy
b40a38a8ac remove declaration of removed function 2009-11-19 14:24:41 -02:00
Roberto Ierusalimschy
ac899a6307 'debug.joinupvalue' -> 'debug.upvaluejoin' 2009-11-18 13:50:18 -02:00
Roberto Ierusalimschy
ce444bff33 (huge) simplification of GC management 2009-11-18 11:13:47 -02:00
Roberto Ierusalimschy
2d5931ebc8 ensure that reader function cannot yield during parsing 2009-11-17 14:46:44 -02:00
Roberto Ierusalimschy
35fa276099 parser/scanner keep GC running 2009-11-17 14:33:38 -02:00
Roberto Ierusalimschy
b51d76ce8d when doing hard memory tests, perform a full GC at every possible step 2009-11-17 09:56:03 -02:00
Roberto Ierusalimschy
95020afb63 'module' returns the new module (to be used with lexical environments) 2009-11-16 13:51:19 -02:00
Roberto Ierusalimschy
c5050b1c41 functions 'getfenv' and 'setfenv' are deprecated 2009-11-16 13:51:03 -02:00
Roberto Ierusalimschy
b9063a08f5 new function 'loadin' 2009-11-13 15:01:40 -02:00
Roberto Ierusalimschy
7fe405739c renaming: 'lua_upvaladdr' -> 'lua_upvalueid',
'lua_upvaljoin' -> 'lua_upvaluejoin'
2009-11-09 17:10:48 -02:00
Roberto Ierusalimschy
1ce819333d new option 'isrunning' for 'lua_gc' (and 'collectgarbage') 2009-11-09 16:55:17 -02:00
Roberto Ierusalimschy
88eb901f81 registry and global table may be changed through the API without a
write barrier, so GC should visit them in the atomic phase.
2009-11-09 16:29:21 -02:00
Roberto Ierusalimschy
2583bac3d3 several small changes to simplify changing TValue if needed 2009-11-06 15:09:27 -02:00
Roberto Ierusalimschy
63a3b1a1eb macro 'checkvalref' redefined as function (to avoid too long macros) 2009-11-06 15:08:43 -02:00
Roberto Ierusalimschy
fbf866a1a5 macro 'gkey' returns a "real" TValue* 2009-11-06 15:07:48 -02:00
Roberto Ierusalimschy
49a67c6d3f new macro 'NILCONSTANT' to initialize nil constants 2009-11-06 15:07:12 -02:00
Roberto Ierusalimschy
a921d81033 avoid using 'ttype' when there is an explicit test + macro 'checkdeadkey'
to avoid repetitions
2009-11-06 15:06:19 -02:00
Roberto Ierusalimschy
155dd01163 avoid using 'ttype' when there is an explicit test 2009-11-06 15:05:34 -02:00
Roberto Ierusalimschy
599789a907 better to enclose macros in 'if' bodies with brackets 2009-11-06 15:03:37 -02:00
Roberto Ierusalimschy
9756f56354 better control over accesses to TValue fields 2009-11-05 15:43:54 -02:00
Roberto Ierusalimschy
b7d5f18d71 api functions to manipulate upvalues do not need to check their
arguments (the caller must check them before calling)
2009-11-05 15:26:00 -02:00
Roberto Ierusalimschy
5598b2bc55 new functions to identify and join upvalues 2009-11-05 14:48:31 -02:00
Roberto Ierusalimschy
77077b39d5 comment explaining OP_VARARG was wrong (and corresponding code was not
very clear)
2009-10-28 10:20:07 -02:00
Roberto Ierusalimschy
5bc91c6405 no more one environment per thread: all threads share a single global
environment
2009-10-23 17:12:19 -02:00
Roberto Ierusalimschy
f5073de0a7 'ipairs' goes until length of array instead of stopping at the first nil 2009-10-23 10:50:25 -02:00
Roberto Ierusalimschy
f6ed285cf2 new hash for doubles based on frexp, to avoid low-level tricks 2009-10-23 10:31:12 -02:00
Roberto Ierusalimschy
1448e736f0 better documentation for constructor syntax 2009-10-14 13:43:11 -03:00
Roberto Ierusalimschy
6e415e9387 local function definition does not need to correct debug information 2009-10-13 16:35:42 -03:00
Roberto Ierusalimschy
b114c99a60 two small bugs: 'debug.getinfo' did not consider negative indices as out
of range + 'debug.[gs]etlocal' crash on tail calls
2009-10-13 16:07:40 -03:00
Roberto Ierusalimschy
916587508c parser keeps list of active local variables in a single dynamic array,
therefore saving C stack space
2009-10-11 17:02:19 -03:00
Roberto Ierusalimschy
a5382b763c new function lua_copy 2009-10-05 13:44:33 -03:00
Roberto Ierusalimschy
ba21aa8b2b 'cpcall' must ensure correct environment for called function 2009-09-30 17:49:47 -03:00
Roberto Ierusalimschy
d119cf3035 a few more instructions to testC (func2udata and getfield) 2009-09-30 17:49:25 -03:00
Roberto Ierusalimschy
0ac3d07ea6 first implementation of lexical environments 2009-09-30 12:38:37 -03:00
Roberto Ierusalimschy
5938212748 information about upvalues (where they come from) kept in Proto structure,
instead of sequence of pseudo-opcodes after OP_CLOSURE
2009-09-28 13:32:50 -03:00
Roberto Ierusalimschy
1829911d7c some operations may shrink g->totalbytes so g->estimate must be
more flexible
2009-09-28 10:50:34 -03:00
Roberto Ierusalimschy
bed2cb725a initialize g->estimate (just in case) 2009-09-28 10:50:19 -03:00
Roberto Ierusalimschy
ab75bd23ee handle extended opcodes (with OP_EXTRAARG) when checking metamethod
calls
2009-09-28 09:37:17 -03:00
Roberto Ierusalimschy
cee94df6e0 function list in luaL_register may be NULL for an empty list 2009-09-28 09:36:40 -03:00
Roberto Ierusalimschy
fcc46467fa limit of constants per function changed to 2^26 using extra arguments
to opcodes LOADK, GETGLOBAL, and SETGLOBAL
2009-09-23 17:33:05 -03:00
Roberto Ierusalimschy
f8e354e240 detail (space between function name and its parameter list) 2009-09-23 17:14:00 -03:00
Roberto Ierusalimschy
a650378822 'cpcall' reimplemented as a predefined value in the registry 2009-09-21 09:09:52 -03:00
Roberto Ierusalimschy
99182c6872 references must start after predefined values in the registry 2009-09-18 15:58:45 -03:00
Roberto Ierusalimschy
67cae2854c 'lua_mainthread' replaced by new preregistered value LUA_RIDX_MAINTHREAD 2009-09-17 15:04:21 -03:00
Roberto Ierusalimschy
0e45ffb8e4 first implementation of 'lua_yieldk' (yield with continuation) 2009-09-14 11:30:39 -03:00
Roberto Ierusalimschy
071e54ae0b extra facilities to testC: comments + commands print, callk and yield +
Cfunc with extra upvalues
2009-09-09 17:44:10 -03:00
Roberto Ierusalimschy
a68494fb32 'debug.[gs]etupvalue' should be able to access C upvalues too 2009-09-09 17:32:19 -03:00
Roberto Ierusalimschy
4b44793dc5 "bug": lua_createtable with sizes changed (array <-> record) 2009-09-07 11:24:12 -03:00
Roberto Ierusalimschy
90e2a716c8 details + comments 2009-09-05 09:39:29 -03:00
Roberto Ierusalimschy
d9fbbe1f23 "file:write" returns "file" in case of success 2009-09-01 16:10:48 -03:00
Roberto Ierusalimschy
4a714cebd1 API checks now have explanatory messages 2009-08-31 11:26:28 -03:00
Roberto Ierusalimschy
5b6be84106 ensures that argument 'mode' to 'io.open' matches "[rwa]%+?b?", to
avoid passing invalid modes to 'fopen'.
2009-08-28 10:51:57 -03:00
Roberto Ierusalimschy
b2bb2f7f59 better machinery to test continuations in the C API 2009-08-26 14:41:26 -03:00
Roberto Ierusalimschy
f096ab5421 correct way to check arguments to 'strftime' 2009-08-25 16:58:08 -03:00
Roberto Ierusalimschy
4e1ffc482a test for 'fs' being NULL at the end of 'close_func' is useless ('fs'
cannot be NULl and the new ls->fs can only be NULL when the token
is EOS, in which case anchor_token has no effect).
2009-08-10 17:41:04 -03:00
Roberto Ierusalimschy
bc439e21cd avoid an unprotected call to 'lua_tostring' which theoretically may
cause a panicked exit
2009-08-10 13:23:19 -03:00
Roberto Ierusalimschy
1b4480003b "stange numbers" (-0 and NaN) also go to the constant table (as
strings with their binary representation). Therefore, constant
folding may produce these results.
2009-08-10 12:31:44 -03:00
Roberto Ierusalimschy
42167804b8 luaH_[gs]etnum renamed to luaH_[gs]etint (as they only accept integers,
not generic numbers).
2009-08-07 14:53:28 -03:00
Roberto Ierusalimschy
3135a6bbab luaH_[gs]etnum renamed to luaH_[gs]etint (as they only accept integers,
not generic numbers)
2009-08-07 13:17:41 -03:00
Roberto Ierusalimschy
95cbc402dc "But" -> "Bug" (misspelling) 2009-08-05 10:09:38 -03:00
Roberto Ierusalimschy
decada8dc2 'debug.getfenv' does not check whether it has an argument 2009-08-04 15:51:19 -03:00
Roberto Ierusalimschy
ee5d03b42a small bug: debug.getfenv should check whether it has an argument 2009-08-04 15:27:57 -03:00
Roberto Ierusalimschy
323f33d014 'collectgarbage"count"' returns a second argument with the count%1024. 2009-08-04 15:20:18 -03:00
Roberto Ierusalimschy
55dc7fb240 bug: stack must be cleared until its end (including extra size) +
control of stack size moved to 'ldo.c'
2009-07-16 13:26:09 -03:00
Roberto Ierusalimschy
11d7ba79f2 tail calls do not need to move whole new frame down, only its slice
up to last parameter (the rest has not been used yet)
2009-07-15 15:38:16 -03:00
Roberto Ierusalimschy
bd5fa9cc8f new macro 'getproto' 2009-07-15 15:37:19 -03:00
Roberto Ierusalimschy
2658c94925 detail (comment: 'correspoding' -> 'corresponding') 2009-07-15 14:57:30 -03:00
Roberto Ierusalimschy
215885768c 'index2adr' -> 'index2addr' (correct spelling) 2009-07-15 14:57:03 -03:00
Roberto Ierusalimschy
a5f68589c0 avoid using 'UNUSED' (not defined outside the kernel) 2009-07-15 14:49:48 -03:00
Roberto Ierusalimschy
28419c4383 'luaL_tolstring' uses 'lua_tolstring' instead of 'lua_tostring' and
'lua_objlen'
2009-07-15 14:47:34 -03:00
Roberto Ierusalimschy
5bff2aaf47 calls with LUA_MULTRET may leave no free slots in the stack 2009-07-15 14:35:20 -03:00
Roberto Ierusalimschy
f76f4cb79d new way to control stack overflow, controling only total size of the stack 2009-07-15 14:26:14 -03:00
Roberto Ierusalimschy
abb85fc059 new definition for 'luaD_checkstack' to avoid possible overflows 2009-07-08 13:06:51 -03:00
Roberto Ierusalimschy
aabe3ddbf4 errors in 'resume' should be all protected 2009-07-08 13:06:07 -03:00
Roberto Ierusalimschy
0c258c8492 smart use of varargs may create functions that return too
many arguments and overflow the stack of C functions.
2009-07-02 16:57:34 -03:00
Roberto Ierusalimschy
d57c9cdefc BUG: 'luaV_settable' may invalidate a reference to a table and try
to reuse it.
2009-07-01 18:10:33 -03:00
Roberto Ierusalimschy
afb3f7e754 bug: 'luaV_settable' may invalidate a reference to a table and try
to reuse it.
2009-07-01 17:31:25 -03:00
Roberto Ierusalimschy
88564c3aec Standard library for bitwise operations 2009-07-01 13:17:08 -03:00
Roberto Ierusalimschy
3abe3da9fb new module 'lbitlib.c' for bitwise operations 2009-07-01 13:16:40 -03:00
Roberto Ierusalimschy
eb8499c8e0 use of LUAI_UINT32 replaced by 'unsigned LUA_INT32' (one less
definition needed)
2009-07-01 13:14:15 -03:00
Roberto Ierusalimschy
47c562435b better error messages for luaL_checkversion 2009-06-19 11:21:57 -03:00
Roberto Ierusalimschy
02504d86d3 l_version may be local to 'lua_version' 2009-06-19 11:21:23 -03:00
Roberto Ierusalimschy
4a818f068a 'checkversion' implemented in the auxiliary library 2009-06-18 15:59:58 -03:00
Roberto Ierusalimschy
1d6ebce296 new function 'lua_version' (so that 'checkversion' can be implemented
in the auxiliary library)
2009-06-18 15:59:18 -03:00
Roberto Ierusalimschy
bc3e02a1b7 default paths have dot option as the last one (to improve security) 2009-06-18 15:19:36 -03:00
Roberto Ierusalimschy
f4eed60ca9 better treatment of integer formats in string.format 2009-06-18 13:51:03 -03:00
Roberto Ierusalimschy
c1de1fdac6 small optimization in 'lua_arith' (avoids overhead in the common case
of both arguments being numbers)
2009-06-18 13:36:40 -03:00
Roberto Ierusalimschy
a36c8e1718 new macro 'changenvalue' 2009-06-18 13:36:40 -03:00
Roberto Ierusalimschy
d7872dcf91 small optimization (reorder of BinOpr enum to unify some cases
in switches)
2009-06-18 13:35:05 -03:00
Roberto Ierusalimschy
14115170bc lua_objlen should not work for numbers (according to the manual) 2009-06-17 15:38:54 -03:00
Roberto Ierusalimschy
ec52149485 'lua_lessthan' replaced by more generic 'lua_compare' 2009-06-17 14:53:50 -03:00
Roberto Ierusalimschy
6980cb1aa7 new functions 'lua_arith' and 'lua_compare' 2009-06-17 14:53:14 -03:00
Roberto Ierusalimschy
59a59fafc6 exports luaV_arith to be used by lua_arith 2009-06-17 14:51:07 -03:00
Roberto Ierusalimschy
2bdd194f43 exports luaV_arith to be used by lua_arith + uses 'luaO_arith' to
perform basic arith. operations
2009-06-17 14:50:09 -03:00
Roberto Ierusalimschy
96fa34ec32 constant folding uses 'luaO_arith' to perform basic operations 2009-06-17 14:49:09 -03:00
Roberto Ierusalimschy
6a024df440 new function 'luaO_arith' to perform basic arithmetic operations 2009-06-17 14:48:34 -03:00
Roberto Ierusalimschy
77fd93188e 'lessequal' renamed 'luaV_lessequal' and exported to be used by
'lua_compare'
2009-06-17 13:17:14 -03:00
Roberto Ierusalimschy
a21c89ddc8 new API function 'lua_mainthread' 2009-06-15 16:51:31 -03:00
Roberto Ierusalimschy
49b88b1c39 patch for wrong code generation for some particular boolean expressions 2009-06-15 11:12:59 -03:00
Roberto Ierusalimschy
3db5f60547 BUG: "(((1 or false) and true) or false)" gives wrong result 2009-06-15 10:52:08 -03:00
Roberto Ierusalimschy
2258ec6bc9 'getline' renamed to 'getfuncline' (to avoid problems with POSIX) 2009-06-10 13:57:53 -03:00
Roberto Ierusalimschy
2598138ece new function 'luaK_codek' (detail) 2009-06-10 13:52:03 -03:00
Roberto Ierusalimschy
4a67e48611 new macro 'condmovestack' instead of 'condhardstacktests' 2009-06-08 16:35:59 -03:00
Roberto Ierusalimschy
5cdec7d124 added "\n" at the end of 'package.config' (so that the string
is a sequence of complete lines)
2009-06-04 16:34:24 -03:00
Roberto Ierusalimschy
9423e22aa3 no more L->base + ci->base only for Lua functions (C functions may use
'func')
2009-06-01 16:09:26 -03:00
Roberto Ierusalimschy
57f8414de1 small bug in 'luaV_concat' (L->top was left incorrect in some cases) 2009-05-27 14:11:27 -03:00
Roberto Ierusalimschy
139d562861 type of 'luai_ctype_' array changed to unsigned (safer for bitwise
operations)
2009-05-27 13:51:15 -03:00
Roberto Ierusalimschy
eea6d10866 details (use ci->base instead of L->base when possible) 2009-05-22 12:19:54 -03:00
Roberto Ierusalimschy
019ebcb85f errors in finalizers are propagated with code LUA_ERRGCMM (ERRor in
__gc MetaMethod)
2009-05-21 17:06:11 -03:00
Roberto Ierusalimschy
889284ebd0 hexadecimal escape sequences in strings + better error messages for
bad decimal escape sequences
2009-05-18 14:28:04 -03:00
Roberto Ierusalimschy
6956331093 new macro 'zungetc' 2009-05-18 14:26:25 -03:00
Roberto Ierusalimschy
92479f1a8b new property 'lisupper' (needed to compute values for hexa digits) 2009-05-18 14:15:14 -03:00
Roberto Ierusalimschy
e67dc3a227 'symbexec' merged with 'getobjname' (as only use for symbolic execution
now is to find a "good" name for an object)
2009-05-04 15:26:21 -03:00
Roberto Ierusalimschy
0cc3add9f8 variable renaming: 'lualibs' -> 'loadedlibs'; 'luareqlibs' ->
'preloadedlibs'
2009-05-01 10:46:35 -03:00
Roberto Ierusalimschy
71c2eeff98 comments 2009-05-01 10:37:11 -03:00
Roberto Ierusalimschy
d7bc346d7a no more code checking 2009-04-30 14:42:21 -03:00
Roberto Ierusalimschy
673c456cba resize string hash table only when new size is smaller than current one 2009-04-29 14:09:41 -03:00
Roberto Ierusalimschy
ea44570883 hash table for strings is rehashed in place 2009-04-29 14:09:41 -03:00
Roberto Ierusalimschy
e091a254df new way to GC stacks: the entire stack must be correct all the times;
the 'dead' part of a stack (after the top) must have only nil's, so
that 'top' may go up without cleaning the stack.
2009-04-28 16:04:36 -03:00
Roberto Ierusalimschy
58c3aa8b5f malicious zero-length string in binary code may segfault Lua +
wrong code generation for some particular boolean expressions
2009-04-27 17:11:11 -03:00
Roberto Ierusalimschy
c1f78ff3d3 unused arguments removed 2009-04-27 15:58:31 -03:00
Roberto Ierusalimschy
e5249b9fb5 'exit' changed to 'abort' in case of panic (+ some extra comments)
'abort' seems more in line with panic ("abnormal termination")
2009-04-26 18:55:35 -03:00
Roberto Ierusalimschy
d3037d97ec several small improvements based on 'ci' being fixed now (including
erasing savedpc from lua_State)
2009-04-17 19:00:01 -03:00
Roberto Ierusalimschy
c6b442bd36 'luaM_freearray' does not need array type as argument 2009-04-17 11:40:13 -03:00
Roberto Ierusalimschy
4f88418170 'CallInfo' stack implemented as double-linked list instead of an array 2009-04-17 11:28:06 -03:00
Roberto Ierusalimschy
311e9f3ceb 'nresults' is saved in CallInfo from the caller, not the called 2009-04-15 13:53:39 -03:00
Roberto Ierusalimschy
8775f25830 new function 'T.makeCfunc' (for later use) 2009-04-14 16:10:17 -03:00
Roberto Ierusalimschy
70a63fa5ad first implementation of yieldable 'pcall' 2009-04-08 15:04:33 -03:00
Roberto Ierusalimschy
fffbaede75 detail 2009-04-03 12:58:03 -03:00
Roberto Ierusalimschy
ae9ad6c694 added comment explaining why the 'feof' test when loading a file 2009-04-02 16:54:06 -03:00
Roberto Ierusalimschy
83d2dbb15d Lua will abort anyway, so 'panic' does not need to. 2009-03-31 14:25:08 -03:00
Roberto Ierusalimschy
4e43741943 in 'lua_call', avoid preparing a continuation when thread cannot yield. 2009-03-30 15:39:20 -03:00
Roberto Ierusalimschy
a274596ecc avoid making 'lastfree' an invalid pointer 2009-03-30 15:38:24 -03:00
Roberto Ierusalimschy
7e9bc41fe7 'loadlib(lib, "*")' loads 'lib' with global names exported to all 2009-03-26 19:25:05 -03:00
Roberto Ierusalimschy
b1e1c15ced small bug: EOZ is a valid character to be tested 2009-03-26 15:53:52 -03:00
Roberto Ierusalimschy
3dbf305408 no more support for old-style varargs 2009-03-26 09:57:01 -03:00
Roberto Ierusalimschy
6d0ae11c57 'context' added to suspendable calls 2009-03-23 11:26:12 -03:00
Roberto Ierusalimschy
3ca739b418 'math.random' uses lua_Number to manage its arguments (there is no
reason to lose range).
2009-03-17 14:55:39 -03:00
Roberto Ierusalimschy
9e613b8583 missing argument to 'assert' raises "assertion failed" error 2009-03-16 13:30:50 -03:00
Roberto Ierusalimschy
9428ec42d0 new optional argument to 'load', to control allowed modes (binary or
textual chunks)
2009-03-13 12:50:03 -03:00
Roberto Ierusalimschy
6ffcf21367 ctype 'lalpha' includes '_' (as '_' behaves as a letter from the
point of view of Lua)
2009-03-11 10:27:32 -03:00
Roberto Ierusalimschy
6427c61e7c added macro 'lisxdigit' (just in case :) 2009-03-10 14:42:33 -03:00
Roberto Ierusalimschy
ba484b9eb1 yielding across lua_call (first version) 2009-03-10 14:14:37 -03:00
Roberto Ierusalimschy
f9d015523e better notes about some opcodes (comments only) 2009-03-09 12:27:56 -03:00
Roberto Ierusalimschy
1817dfc301 initial separation, in CallInfo, of what is relevant only to Lua
functions or only to C functions
2009-03-04 10:32:29 -03:00
Roberto Ierusalimschy
7837e34e56 new states have a reasonable panic function +
testC may run code on different threads +
rename of some testC operations ('rawcall'->'call', 'call'->'pcall')
2009-03-03 15:52:36 -03:00
Roberto Ierusalimschy
910310d3ba if thread has no error handling, try main thread handler before panicking 2009-03-03 15:51:24 -03:00
Roberto Ierusalimschy
facfcd497f detail 2009-03-02 13:34:23 -03:00
Roberto Ierusalimschy
b403317325 error functions search global space for a name for a function when
no other name is available
2009-02-27 15:18:19 -03:00
Roberto Ierusalimschy
9bf05e7364 code section 'Traceback' moved to the beginning of the file 2009-02-27 15:17:13 -03:00
Roberto Ierusalimschy
e39e758a73 closing a "popen" file returns the process exit status 2009-02-20 10:50:27 -03:00
Roberto Ierusalimschy
5438d77221 global array of ctypes renamed to 'luai_ctype_' (extern names must
use a "lua" prefix...)
2009-02-20 10:11:15 -03:00
Roberto Ierusalimschy
6905ae900b Lua now uses "homemade" lctype (instead of ctype.h from ANSI C) 2009-02-19 14:33:51 -03:00
Roberto Ierusalimschy
ada82930fd "homemade" version of ctype.h 2009-02-19 14:18:25 -03:00
Roberto Ierusalimschy
f36e319658 'fputs' changed to 'luai_writestring' + use of 'lua_checkversion' 2009-02-19 14:15:35 -03:00
Roberto Ierusalimschy
0cea28a785 better error messages for 'lua_checkversion' 2009-02-19 14:15:13 -03:00
Roberto Ierusalimschy
d2ebdc045b new macro 'lua_checkversion' to check whether core and application are
compatible
2009-02-18 14:20:56 -03:00
Roberto Ierusalimschy
81ede6bfce using light userdata to represent "remote" states 2009-02-18 11:52:51 -03:00
Roberto Ierusalimschy
2b579b4b83 panic mode does not reset stack (so that panic function can gather
debug information from it)
2009-02-18 11:52:03 -03:00
Roberto Ierusalimschy
a1d0e1a11a 'log10' is deprecated now 2009-02-18 10:17:10 -03:00
Roberto Ierusalimschy
8975739839 better precision for log(x, 10) 2009-02-18 10:06:05 -03:00
Roberto Ierusalimschy
d07abcc6c7 finalizers always called protected 2009-02-17 16:47:58 -03:00
Roberto Ierusalimschy
189378142a buffer creation ensures buffer space plus MINSTACK in the stack 2009-02-17 11:31:16 -03:00
Roberto Ierusalimschy
82749b765e 'db_errorfb' changed to 'db_traceback' for consistency 2009-02-17 10:21:28 -03:00
Roberto Ierusalimschy
2b590aea40 no more '__len' metamethod for strings 2009-02-16 17:09:28 -03:00
Roberto Ierusalimschy
547e47649f 'luaL_typeerror' spelled right 2009-02-13 17:39:34 -02:00
Roberto Ierusalimschy
41dd32e18e comment (should not use 'go trhough' when simply using multiple labels) 2009-02-11 16:25:20 -02:00
Roberto Ierusalimschy
5d3cc5def8 'writestring' changed into a configurable macro 2009-02-07 10:23:15 -02:00
Roberto Ierusalimschy
53db607963 avoid using 'fputs' in 'print' to avoid problems with embedded zeros 2009-02-06 16:38:47 -02:00
Roberto Ierusalimschy
cbf0c7a103 check for invalid use of '%' in replacement string in 'string.gsub' 2009-02-03 17:39:19 -02:00
Roberto Ierusalimschy
4c399c5dfb detail (MAXSRC changed to LUA_IDSIZE) 2008-12-26 09:55:57 -02:00
Roberto Ierusalimschy
b472098493 concat TM can yield 2008-11-06 10:43:51 -02:00
Roberto Ierusalimschy
84b3daebbd generic for coded as two dedicated instructions to simplify resumption 2008-10-30 13:39:30 -02:00
Roberto Ierusalimschy
f6978173e0 yields accross metamethods and for iterators (except for __concat) 2008-10-28 14:53:16 -02:00
Roberto Ierusalimschy
e02483dbc0 whole build depends on 'makefile' itself + better format for warning
options
2008-10-28 14:52:00 -02:00
Roberto Ierusalimschy
9e58e0df8f some cleaning 2008-10-28 10:55:00 -02:00
Roberto Ierusalimschy
690efef3de detail (added 'UNUSED' to unused argument) 2008-10-28 10:54:25 -02:00
Roberto Ierusalimschy
b9e92c8b0d updating header dependencies 2008-10-03 13:40:56 -03:00
Roberto Ierusalimschy
4376c9bc5f more specific test to avoid calling luaF_close when function returns 2008-09-09 10:53:02 -03:00
Roberto Ierusalimschy
f94cd2201c better control of call status through CallInfo 2008-08-26 10:27:42 -03:00
Roberto Ierusalimschy
fdbb243ff9 first steps towards yielding through longjump 2008-08-13 14:02:42 -03:00
Roberto Ierusalimschy
c1565c16ed small bug: lua_resume returning LUA_YIELD is not an error 2008-08-13 14:02:12 -03:00
Roberto Ierusalimschy
394646891c new field 'status' in CallInfo structure 2008-08-13 14:01:33 -03:00
Roberto Ierusalimschy
d69aa51088 added missing parentheses around function names 2008-08-13 11:08:49 -03:00
Roberto Ierusalimschy
afe849c9b4 change in error message 2008-08-06 10:38:32 -03:00
Roberto Ierusalimschy
ccd678ea3e 'module' may change the environment of a C function +
internal macro 'svalue' is wrong
2008-08-06 10:32:45 -03:00
Roberto Ierusalimschy
bb92ef23cb bug: string at the end of TString must consider the entire TString
entity, not only its 'tsv' part
2008-08-05 16:26:23 -03:00
Roberto Ierusalimschy
bb48f456d9 bug: 'module' now checks that is caller is a Lua function 2008-08-05 16:25:42 -03:00
Roberto Ierusalimschy
df802dc74b larger alignment requirement helps to uncover some kinds of bugs 2008-08-05 16:24:46 -03:00
Roberto Ierusalimschy
e23da9edee GC step does not unblock collector (when it is blocked by "stop") 2008-08-01 14:01:16 -03:00
Roberto Ierusalimschy
4db2cddeee LUA_COMPAT -> LUA_COMPAT_API (more specific) 2008-07-18 16:58:10 -03:00
Roberto Ierusalimschy
f9dec5fc84 do not use compatibility macros in Lua 2008-07-11 14:51:01 -03:00
Roberto Ierusalimschy
6b8725b0ee new macro LUA_COMPAT to control some compatibility macros 2008-07-11 14:50:31 -03:00
Roberto Ierusalimschy
6955666290 'string.byte' gets confused with some out-of-range negative indices +
user-requested GC step may loop forever
2008-07-11 14:27:41 -03:00
Roberto Ierusalimschy
5298392c5a bug: GC step could loop forever under very particular circumstances 2008-07-04 15:27:11 -03:00
Roberto Ierusalimschy
1ceec74370 useless test removed (pointed by lint) 2008-07-03 11:25:05 -03:00
Roberto Ierusalimschy
2a84c29bc3 comment about exported function not used by Lua 2008-07-03 11:24:36 -03:00
Roberto Ierusalimschy
4d8a1103d3 useless #define removed (pointed by lint) 2008-07-03 11:24:11 -03:00
Roberto Ierusalimschy
202de59254 useless #include removed (pointed by lint) 2008-07-03 11:23:35 -03:00
Roberto Ierusalimschy
f858a155c2 identation error (pointed by lint) 2008-07-03 11:21:41 -03:00
Roberto Ierusalimschy
9e7de9473c message from -v option goes to stdout, as it is not an error message 2008-06-26 16:47:51 -03:00
Roberto Ierusalimschy
0c8f5fc2fd simplification in the handling of finalizers: no more 'tmudata' list +
no more GCSsweeptmu collector's state
2008-06-26 16:42:45 -03:00
Roberto Ierusalimschy
1527d8f00d GC called after errors now are called after showing error message (to
avoid problems when there are other errors during GC itself)
2008-06-26 16:40:12 -03:00
Roberto Ierusalimschy
8efaf8af81 added a comment about warnings for __attribute__(visibility) in some
elf targets
2008-06-25 12:27:12 -03:00
Roberto Ierusalimschy
c3525610fe bug: when closing the state, 'luaC_separateudata' might mark
userdata in the wrong phase of collection, therefore avoiding
their traversal
2008-06-23 19:07:44 -03:00
Roberto Ierusalimschy
7ba62e2985 code reorganization (only changed comments and order of functions) 2008-06-23 13:51:28 -03:00
Roberto Ierusalimschy
8fd28611d5 outdated comment 2008-06-23 13:51:08 -03:00
Roberto Ierusalimschy
93869acb2c "test trick" seems more useful with pointers instead of integers 2008-06-23 13:50:34 -03:00
Roberto Ierusalimschy
480a1da34a when error is 'bad self' original message probably makes no sense, so
it is better not to show it.
2008-06-13 15:45:35 -03:00
Roberto Ierusalimschy
59e2973335 removed static variable lua_state (not used) 2008-06-13 14:07:10 -03:00
Roberto Ierusalimschy
5d09be4832 by default, 'os.exit' closes current state 2008-06-13 13:59:00 -03:00
Roberto Ierusalimschy
860e285f31 'luaL_gsub' moved into 'testC' (all auxlib should be tested through 'testC') 2008-06-13 11:15:59 -03:00
Roberto Ierusalimschy
eb8ac6e2a0 'luaL_testudata' does not leave garbage on the stack in case of failure 2008-06-12 11:37:27 -03:00
Roberto Ierusalimschy
b1203e036d 'posrelat' avoids problems with -(-2^31) 2008-06-12 11:21:18 -03:00
Roberto Ierusalimschy
92a0d4c67f extra options in 'testC' for newmetatable and testudata 2008-06-12 11:20:49 -03:00
Roberto Ierusalimschy
5fa55df2ca updated years in some comments/strings 2008-05-09 13:51:44 -03:00
Roberto Ierusalimschy
a3af42de8e patch for "blow stack" bug 2008-05-08 13:55:08 -03:00
Roberto Ierusalimschy
198be23f36 added structure for local-variable information to allow extra
checkings if needed
2008-05-08 12:44:51 -03:00
Roberto Ierusalimschy
24359ae294 'string.find' cannot find things after subject's end 2008-04-14 12:54:59 -03:00
Roberto Ierusalimschy
6c84722afa make default GC behavior a little more agressive
(to avoid falling behind memory consumption)
2008-04-07 15:58:42 -03:00
Roberto Ierusalimschy
facb0519a0 two bugs: invalid boolean values in constant table + too deep recursion
when reading nested functions
2008-04-07 15:44:23 -03:00
Roberto Ierusalimschy
ffdca3522e 'table.sort' detects invalid order function before calling it
for nil elements
2008-04-07 15:43:00 -03:00
Roberto Ierusalimschy
4d7469b610 avoid constant folding for -0 (to avoid it colapsing to 0) 2008-04-07 15:41:47 -03:00
Roberto Ierusalimschy
2b84e36b93 patches for some bugs 2008-04-04 22:31:59 -03:00
Roberto Ierusalimschy
85bda9eef5 bugs: precheck must use check (instead of assert) and ensures that
code size is at least 1
2008-04-02 16:14:16 -03:00
Roberto Ierusalimschy
a4d3080fe3 SETLIST extra argument now is an "instruction" (OP_EXTRAARG) 2008-04-02 14:38:54 -03:00
Roberto Ierusalimschy
5627d51e05 corrected error message ("too many constants" -> "too many functions") 2008-04-02 14:19:22 -03:00
Roberto Ierusalimschy
e64b0cada8 several bugs related to precompiled code 2008-04-01 16:17:48 -03:00
Roberto Ierusalimschy
7316d61a66 'coroutine.running' should work for the main thread too 2008-02-25 11:33:57 -03:00
Roberto Ierusalimschy
e2b366c760 userdata with finalizers are kept in a separated list 2008-02-19 15:55:09 -03:00
Roberto Ierusalimschy
fa19baab7f proxies must be created with a __gc field in their metatables to work
properly with new semantics for finalizers
2008-02-19 15:54:09 -03:00
Roberto Ierusalimschy
2f8351fe48 turn off optimizations when testing 2008-02-15 15:44:34 -02:00
Roberto Ierusalimschy
32d42bdcdc bugs: lua_checkstack may have arithmetic overflow for large 'size' +
unpack with maximum indices may crash due to arithmetic overflow
2008-02-14 14:51:57 -02:00
Roberto Ierusalimschy
843d53aabb 'table.concat' may get confused with too large limits 2008-02-14 14:03:27 -02:00
Roberto Ierusalimschy
5ac3386888 bug: unpack with maximum indices may crash due to arithmetic overflow 2008-02-14 14:03:09 -02:00
Roberto Ierusalimschy
6d182faab6 bug: lua_checkstack may have arithmetic overflow for large 'size' 2008-02-14 14:02:58 -02:00
Roberto Ierusalimschy
f86f4116c8 micro-optimization: avoid one API call in 'read_chars' 2008-02-12 15:05:36 -02:00
Roberto Ierusalimschy
7f69f0efb0 remove of useless test in 'read_chars' (if n == 0 then the resulting
string cannot be empty).
2008-02-12 14:51:03 -02:00
Roberto Ierusalimschy
f6cab9666c corrected name of 'Patrick Donnelly' 2008-02-12 14:42:46 -02:00
Roberto Ierusalimschy
3deb38814d added assertions checking maximum number of upvalues 2008-02-12 11:34:12 -02:00
Roberto Ierusalimschy
3b5b14a085 LUAI_MAXCSTACK must be smaller than -LUA_REGISTRYINDEX +
coroutine.resume pushes element without ensuring stack size
2008-02-11 17:18:21 -02:00
Roberto Ierusalimschy
aec671c126 maximum C stack should reserve some values for pseudo-indices 2008-02-11 17:17:19 -02:00
Roberto Ierusalimschy
dd92af69db bug: pseudo-indices should be linked to maximum C stack size 2008-02-11 17:16:02 -02:00
Roberto Ierusalimschy
015e973899 bug: auxresume should reserve stack space for boolean result 2008-02-11 17:14:52 -02:00
Roberto Ierusalimschy
163f58dac5 in 'testC', booleans should be represented by booean values 2008-02-11 17:04:16 -02:00
Roberto Ierusalimschy
dcee7d2fe0 new instructions 'newtable' and 'checkstack' in 'testC' 2008-02-11 16:04:26 -02:00
Roberto Ierusalimschy
5f0a2f6248 more options for 'kinds' of Garbage Collection + more agressive
shrinking of stacks and string hash
2008-02-11 13:46:03 -02:00
Roberto Ierusalimschy
a73930228a more options for 'kinds' of Garbage Collection 2008-02-11 13:45:30 -02:00
Roberto Ierusalimschy
a76fa25199 'ceillog2' now is exported (other modules may need it) 2008-01-30 16:05:23 -02:00
Roberto Ierusalimschy
dd3519ab89 comment (LUA_GLOBALSINDEX does not need write barrier in lua_replace) 2008-01-25 11:42:12 -02:00
Roberto Ierusalimschy
3a515df086 debug.sethook/gethook may overflow the thread's stack 2008-01-21 12:41:19 -02:00
Roberto Ierusalimschy
74897bc52f bug: debug.sethook/gethook may overflow thread's stack 2008-01-21 11:37:08 -02:00
Roberto Ierusalimschy
e7c989baf1 avoid calling "tail return" hooks if the hook itself turns off the event 2008-01-18 20:36:50 -02:00
Roberto Ierusalimschy
7a3c8314ac small bug (see http://lua-users.org/lists/lua-l/2007-08/msg00350.html) 2008-01-18 15:14:47 -02:00
Roberto Ierusalimschy
6f8257ec5f it seems useless trying to avoid this warning... 2008-01-18 13:37:10 -02:00
Roberto Ierusalimschy
87b0191753 better definition for LUAI_MAXCSTACK 2008-01-17 14:24:38 -02:00
Roberto Ierusalimschy
56c17ba4c7 detail 2008-01-17 14:24:30 -02:00
Roberto Ierusalimschy
daddc57abd luaL_tostring -> luaL_tolstring (more generic) 2008-01-03 15:07:59 -02:00
Roberto Ierusalimschy
f9cdd09191 larger limit for MAXCSTACK (plus removing of some useless definitions) 2008-01-02 14:36:19 -02:00
Roberto Ierusalimschy
47b4858357 detail ('name' of baselib is "_G") 2008-01-02 14:16:28 -02:00
Roberto Ierusalimschy
b8d23d6e07 option to use Sun compiler (on lhf account) 2007-12-27 10:59:43 -02:00
Roberto Ierusalimschy
fdecdd0cec stand-alone interpreter shows incorrect error message when the
'message' is a coroutine (already fixed in 5.2)
2007-12-27 10:58:29 -02:00
Roberto Ierusalimschy
fabdaa37b6 'lua_pushfstring' raises an error if called with invalid format 2007-12-19 15:24:38 -02:00
Roberto Ierusalimschy
bc82b4d78a new function 'package.searchpath' 2007-12-12 12:36:12 -02:00
Roberto Ierusalimschy
dae850e0ee details 2007-12-08 09:54:32 -02:00
Roberto Ierusalimschy
abcc124df0 BUG: lua_setfenv may crash if called over an invalid object 2007-11-28 16:27:38 -02:00
Roberto Ierusalimschy
b4164a9aa7 details 2007-11-28 16:25:17 -02:00
Roberto Ierusalimschy
9f0d62ad9f BUG: table.remove removes last element of a table when given
an out-of-bound index
2007-11-26 14:57:33 -02:00
Roberto Ierusalimschy
64ecf24210 detail 2007-11-26 14:56:11 -02:00
Roberto Ierusalimschy
658e7caf92 use prefix in extern names, even those in test files 2007-11-12 14:28:45 -02:00
Roberto Ierusalimschy
788506dd58 detail 2007-11-12 12:10:09 -02:00
Roberto Ierusalimschy
62790ab15d detail 2007-11-09 16:55:07 -02:00
Roberto Ierusalimschy
ad60b3ead7 avoid the use of "exotic" libc functions 2007-11-09 16:54:25 -02:00
Roberto Ierusalimschy
5e8dd55574 first implementation of ephemerons 2007-10-31 13:41:19 -02:00
Roberto Ierusalimschy
0e961ad47a some changes toward ephemerons 2007-10-29 14:51:20 -02:00
Roberto Ierusalimschy
c06cc60946 BUG: 'gsub' may go wild when wrongly called without its third
> argument and with a large subject.
2007-10-29 13:51:10 -02:00
Roberto Ierusalimschy
2fa476655f detail 2007-10-25 17:31:05 -02:00
Roberto Ierusalimschy
7a78495f31 avoid problems with 'ptrdiff_t' 2007-10-25 17:30:36 -02:00
Roberto Ierusalimschy
3138afbe2e parser should not call 'luaX_lexerror' 2007-10-25 14:45:47 -02:00
Roberto Ierusalimschy
4eef0aaad1 detail 2007-10-18 09:01:52 -02:00
Roberto Ierusalimschy
ab09732986 new metamethods for '__pairs' and '__ipairs' 2007-10-17 15:26:39 -02:00
Roberto Ierusalimschy
b7fa64565a 27 is not a prime number :( 2007-09-30 10:09:43 -03:00
Roberto Ierusalimschy
2622ed2528 better way to handle redefinitions of 'localeconv' 2007-09-14 10:27:04 -03:00
Roberto Ierusalimschy
9cb0607f6f avoid warnings about exit; return 2007-09-14 10:26:28 -03:00
Roberto Ierusalimschy
8998032f66 detail 2007-09-14 10:26:03 -03:00
Roberto Ierusalimschy
80b4753539 better error message for 'concat' 2007-09-12 17:53:24 -03:00
Roberto Ierusalimschy
fe0838cd1c tables and strings respect __len metamethod 2007-09-10 14:59:32 -03:00
Roberto Ierusalimschy
8acaa2ce07 An error in a module loaded through the '-l' option
shows no traceback.
2007-09-05 14:18:27 -03:00
Roberto Ierusalimschy
c676f13e1a stand-alone error-message details 2007-09-05 14:17:39 -03:00
Roberto Ierusalimschy
9b47cee8b2 better to flush all files before starting new process with popen 2007-08-30 13:13:13 -03:00
Roberto Ierusalimschy
47e666c090 no need for ctype.h 2007-08-10 09:56:02 -03:00
Roberto Ierusalimschy
3059579253 detail 2007-08-09 17:29:15 -03:00
Roberto Ierusalimschy
72c2f75648 detail (LUA_COPYRIGHT includes release number) 2007-08-07 13:53:40 -03:00
Roberto Ierusalimschy
ec68ed66ed detail 2007-08-01 09:17:29 -03:00
Roberto Ierusalimschy
f6a81dbe97 BUG: too many variables in an assignment may cause a C stack overflow 2007-07-31 16:39:52 -03:00
Roberto Ierusalimschy
3904a66ab0 'debug' library must be required before being used 2007-06-22 13:59:11 -03:00
Roberto Ierusalimschy
ffc5f78229 detail 2007-06-22 12:39:34 -03:00
Roberto Ierusalimschy
3f78748ef3 traceback function moved to auxlib 2007-06-22 12:33:54 -03:00
Roberto Ierusalimschy
d26bfb5ae4 "spacial" reorganization to keep related functions in groups 2007-06-21 11:09:59 -03:00
Roberto Ierusalimschy
8d3dd04137 clearing some old compatibility code 2007-06-21 10:52:27 -03:00
Roberto Ierusalimschy
791d8d8585 detail 2007-06-21 10:50:53 -03:00
Roberto Ierusalimschy
e85515958b clearing some old compatibility code 2007-06-21 10:48:04 -03:00
Roberto Ierusalimschy
dc59444cd1 strong collision for very small numbers used as table keys 2007-06-19 17:23:29 -03:00
Roberto Ierusalimschy
6c042e17b1 avoid boolean equality (tricky for some compilers) 2007-06-19 16:48:15 -03:00
Roberto Ierusalimschy
18a583306b patch may be a little simpler 2007-05-29 16:05:25 -03:00
Roberto Ierusalimschy
fc8d077612 bug: wrong error message in some concatenations 2007-05-29 15:59:59 -03:00
Roberto Ierusalimschy
e64fcb9d94 bug: recursive coroutines may overflow C stack 2007-05-25 14:13:47 -03:00
Roberto Ierusalimschy
6c0a9a272e assignment of nil to parameter may be optimized away
__concat metamethod converts numbers to strings
loadlib.c should not access Lua internals
code generated for "-nil", "-true", and "-false" is wrong
Count hook may be called without being set
2007-05-16 12:39:08 -03:00
Roberto Ierusalimschy
01fa1bc114 luaL_testudata (a luaL_checkudata that does not raise errors) is
very needed.
2007-05-15 15:46:12 -03:00
Roberto Ierusalimschy
aa003eba8e details 2007-05-11 14:28:56 -03:00
Roberto Ierusalimschy
becf19feef better names for metamethods in debug information 2007-05-09 12:49:36 -03:00
Roberto Ierusalimschy
81fc3c4f45 bug: code generated for "-nil", "-true", and "-false" is wrong 2007-05-04 15:41:49 -03:00
Roberto Ierusalimschy
e7fb0d8a6f 'os.date' checks arguments before passing them to 'strftime' 2007-05-03 17:49:29 -03:00
Roberto Ierusalimschy
4eb49163c6 error handler in 'lua.c' tries '__tostring' metamethod if error
message is not a string
2007-04-26 17:39:38 -03:00
Roberto Ierusalimschy
79cb336d74 does not allow standard files to be closed 2007-04-19 17:22:32 -03:00
Roberto Ierusalimschy
38063345ae several details 2007-04-19 17:21:53 -03:00
Roberto Ierusalimschy
ae00b3a76f another way to normalize -0 that avoids problems with very small
numbers (adding 1 turns them all into 1)
2007-04-18 16:24:35 -03:00
Roberto Ierusalimschy
619be354c8 lua_pushstring/pushlstring return string 2007-04-17 10:19:53 -03:00
Roberto Ierusalimschy
94d40f3980 luaO_log2 can be private to ltable.c 2007-04-10 09:18:17 -03:00
Roberto Ierusalimschy
585b81f91e remove of a non-used test function 2007-04-10 09:17:52 -03:00
Roberto Ierusalimschy
5f4f0d4a63 no more optimization to avoid LOADNIL at function start 2007-03-27 11:11:38 -03:00
Roberto Ierusalimschy
8e36e1fe49 details (randomseed calls rand once to dischard first value) 2007-03-27 09:37:00 -03:00
Roberto Ierusalimschy
97505caa64 detail 2007-03-26 15:35:34 -03:00
Roberto Ierusalimschy
df50c84ee0 BUG: loadlib should not use Lua internals (lobject.h) 2007-03-26 12:57:35 -03:00
Roberto Ierusalimschy
1a455acc81 two small bugs: some metamethods do not accept callable non-function
objects + __concat converts numbers to strings before calling metamethod
2007-03-26 12:56:23 -03:00
Roberto Ierusalimschy
60bc151ed7 patch for last bug 2007-03-09 15:51:32 -03:00
Roberto Ierusalimschy
3b19bd4d57 bug: wrong code when constant is coded after it should be 2007-03-09 15:50:56 -03:00
Roberto Ierusalimschy
08f902cf49 better documentation for auxiliary functions (that should be called only
through specific macros).
2007-02-09 11:04:52 -02:00
Roberto Ierusalimschy
d3c304e92e BUG: setfenv accepts invalid argument 2007-02-09 10:40:21 -02:00
Roberto Ierusalimschy
3bf0292cd5 two new bugs + one new patch 2007-02-09 10:39:52 -02:00
Roberto Ierusalimschy
a7861d9d66 new year... 2007-02-07 15:54:52 -02:00
Roberto Ierusalimschy
d62a21b9d3 when formatting with '%q', all control characters are coded
as \nnn.
2007-02-07 15:53:08 -02:00
Roberto Ierusalimschy
cf86576a83 new function luaL_tostring 2007-02-07 15:51:21 -02:00
Roberto Ierusalimschy
92dc64e121 more regularity in the use of quotes in error messages 2007-02-07 15:49:18 -02:00
Roberto Ierusalimschy
593bfc9668 should not manipulate NULL pointers (even without accessing them) 2007-02-07 15:48:52 -02:00
Roberto Ierusalimschy
850c60e81b detail for windows 2007-02-07 15:46:20 -02:00
Roberto Ierusalimschy
3d480b04a5 more specific ident labels 2007-02-07 12:28:00 -02:00
Roberto Ierusalimschy
c36e2265d9 detail (tab->space) 2006-11-30 09:25:40 -02:00
Roberto Ierusalimschy
a68df3898d detail 2006-11-22 09:43:47 -02:00
Roberto Ierusalimschy
4d7cfff6df comments 2006-11-22 09:02:03 -02:00
Roberto Ierusalimschy
be822a5f1c xpcall now may get arguments to function to be called 2006-10-24 16:46:12 -03:00
Roberto Ierusalimschy
9f5a052c27 error message 2006-10-24 10:31:48 -03:00
Roberto Ierusalimschy
fc875334fd detail 2006-10-20 16:30:53 -03:00
Roberto Ierusalimschy
80a267b130 avoid $URL for ident; it is reserved in subversion 2006-10-17 17:00:07 -03:00
Roberto Ierusalimschy
3182ac69a7 towards 5.2 + detail in authors + avoiding reverse plicks 2006-10-17 16:59:04 -03:00
Roberto Ierusalimschy
dead3858b8 detail 2006-10-16 11:38:38 -03:00
Roberto Ierusalimschy
afa0d0ac0d new constant LUA_OK 2006-10-10 14:40:17 -03:00
Roberto Ierusalimschy
742b8be0c1 detail 2006-10-10 14:39:00 -03:00
Roberto Ierusalimschy
285f926140 avoid using index 0 for free list of references (because it is not
as efficient as index 1...)
2006-09-25 12:35:00 -03:00
Roberto Ierusalimschy
3c8865cf66 detail 2006-09-22 17:24:38 -03:00
Roberto Ierusalimschy
569a326931 small optimization for ""..x 2006-09-19 11:06:45 -03:00
Roberto Ierusalimschy
d1ef7e0ec6 avoid local "pc" in interpreter loop (tricky optimization with no real gain) 2006-09-19 10:57:50 -03:00
Roberto Ierusalimschy
d513c3c66b bug: os.date throws error when result is the empty string 2006-09-19 10:57:08 -03:00
Roberto Ierusalimschy
93d3c8450c bug: string.format("%") reads past the string 2006-09-18 13:33:14 -03:00
Roberto Ierusalimschy
8667f29c3b behavior of 'strchr(x, 0)' is ill defined. 2006-09-18 13:06:41 -03:00
Roberto Ierusalimschy
d22526ec30 'lua_strlen' is for compatibility only 2006-09-18 11:03:18 -03:00
Roberto Ierusalimschy
bd869c7b31 details 2006-09-14 15:42:28 -03:00
Roberto Ierusalimschy
d5a23dde90 little better error messages for internal arrays overflows 2006-09-14 09:59:06 -03:00
Roberto Ierusalimschy
a7c9e45c64 avoid trailing white spaces 2006-09-11 11:07:24 -03:00
Roberto Ierusalimschy
cedd2092eb 'coroutine.running' should return nil (instead of nothing) for main thread 2006-09-11 11:07:24 -03:00
Roberto Ierusalimschy
c473818017 avoid "too complex" conditional expression (some compilers get confused...) 2006-09-11 09:44:56 -03:00
Roberto Ierusalimschy
6087e67771 no more compatibility option for long strings 2006-08-30 10:19:58 -03:00
Roberto Ierusalimschy
93bf618504 BUG: there is only one C stack, so nCcalls must be global 2006-08-15 16:59:20 -03:00
Roberto Ierusalimschy
dfe2f1eeff macros luai_num* take a state L (when available) as argument, to allow
them to generate errors (and other facilities)
2006-08-07 16:14:30 -03:00
Roberto Ierusalimschy
ca7e5b5cb6 wrong message error in some cases involving closures 2006-08-07 16:04:06 -03:00
Roberto Ierusalimschy
5019b2dd20 math.log now accepts an optional base 2006-08-07 16:01:56 -03:00
Roberto Ierusalimschy
33e7bc88f8 comment 2006-08-04 10:34:37 -03:00
Roberto Ierusalimschy
fa0c03aaa6 details 2006-07-14 13:22:24 -03:00
Roberto Ierusalimschy
3fa47c5dc1 bugs now are against 5.1.1 2006-07-13 11:37:36 -03:00
Roberto Ierusalimschy
0782416a74 bug: wrong limit for list constructors 2006-07-12 16:02:50 -03:00
Roberto Ierusalimschy
3ca9af51a4 emergency garbage collector (core forces a GC when allocation fails) 2006-07-11 12:53:29 -03:00
Roberto Ierusalimschy
c7b89dd280 small bug: should not use string after popping it 2006-07-03 17:16:49 -03:00
Roberto Ierusalimschy
74832b2a10 detail 2006-06-23 13:09:15 -03:00
Roberto Ierusalimschy
ee41bc03ab details 2006-06-22 13:12:59 -03:00
Roberto Ierusalimschy
98194db429 details 2006-06-09 14:31:14 -03:00
Roberto Ierusalimschy
fad7582c9a explicit test for common error (due to compatibility issue) 2006-06-07 09:37:17 -03:00
Roberto Ierusalimschy
a62fca1ebb BUG: debug hooks may get wrong when mixed with coroutines 2006-06-05 16:36:45 -03:00
Roberto Ierusalimschy
2b5c1f99e5 small simplifications 2006-06-05 16:35:57 -03:00
Roberto Ierusalimschy
e2dc5f5d15 extra assertion 2006-06-05 12:58:59 -03:00
Roberto Ierusalimschy
ed64346b9d details 2006-06-05 12:57:59 -03:00
Roberto Ierusalimschy
475b0ecbf1 new macro LUA_RELEASE 2006-06-02 12:34:00 -03:00
Roberto Ierusalimschy
414359b2f1 new version number 2006-05-31 13:50:40 -03:00
Roberto Ierusalimschy
0079efc479 bug: collector did not compensate enough for userdata with finalizers 2006-05-24 11:34:06 -03:00
Roberto Ierusalimschy
ad0765b4f0 subtle problem with the garbage collector 2006-05-24 11:33:49 -03:00
Roberto Ierusalimschy
20f4bbdc3a does not accept garbage after options (e.g., -ixxx) 2006-05-24 11:16:39 -03:00
Roberto Ierusalimschy
c408158047 only destroy state after running all finalizers 2006-05-24 11:15:50 -03:00
Roberto Ierusalimschy
55e323190e files should not be operated after fclose, even when fclose fails 2006-05-08 17:14:16 -03:00
Roberto Ierusalimschy
fe8f4c06f1 detail (better error message for invalid format) 2006-04-26 17:41:19 -03:00
Roberto Ierusalimschy
c351392940 details 2006-04-26 15:19:49 -03:00
Roberto Ierusalimschy
18330b6091 lua_dostring/lua_dofile should return any values returned by the chunk 2006-04-12 17:31:15 -03:00
Roberto Ierusalimschy
8487913697 BUG: option '%q' for string.format does not handle '\r' correctly 2006-04-12 17:13:52 -03:00
Roberto Ierusalimschy
672bb67ee6 environment variable names should be configurable 2006-04-10 15:27:23 -03:00
Roberto Ierusalimschy
90df6b7a54 detail 2006-03-23 15:23:32 -03:00
Roberto Ierusalimschy
0238a0b01e BUG: luaL_checkudata may show wrong error message 2006-03-21 16:31:09 -03:00
Roberto Ierusalimschy
1ae0b6c0bf BUG: should copy the union, not (some of) its fields 2006-03-21 16:28:49 -03:00
Roberto Ierusalimschy
e1dda047b2 unused macro 2006-03-21 16:28:03 -03:00
Roberto Ierusalimschy
2c8206d448 bug in Lua 4.0.2: weak tables that survive one collection are never collected 2006-03-20 09:49:30 -03:00
Roberto Ierusalimschy
ae76307847 comment 2006-03-14 16:04:44 -03:00
Roberto Ierusalimschy
3d61c31e5a 'lparser.h' should not include 'ltable.h' 2006-03-09 15:15:48 -03:00
Roberto Ierusalimschy
44a9bd6a8c detail 2006-03-09 15:08:22 -03:00
Roberto Ierusalimschy
69ea087dff small change to strip file names when stripping debug information 2006-02-17 13:51:03 -02:00
Roberto Ierusalimschy
c05aaf3bf0 avoid warning in OS X - ansi 2006-02-10 15:44:06 -02:00
Roberto Ierusalimschy
298ae7e230 complete support for hexadecimal constants 2006-02-10 15:43:52 -02:00
Roberto Ierusalimschy
6316a866a3 compiler warning 2006-02-06 16:28:16 -02:00
Roberto Ierusalimschy
ea2cc2bc47 small improvements for allignments 2006-02-06 16:27:59 -02:00
Roberto Ierusalimschy
64205e91a3 empty string may cause out-of-bound access 2006-01-28 10:59:13 -02:00
Roberto Ierusalimschy
8173688542 detail 2006-01-27 11:54:39 -02:00
Roberto Ierusalimschy
3ef5a6797f detail 2006-01-23 18:06:19 -02:00
Roberto Ierusalimschy
9e6e43984d details 2006-01-23 17:51:43 -02:00
Roberto Ierusalimschy
baffc37f5c detail 2006-01-18 09:49:12 -02:00
Roberto Ierusalimschy
440113bbe8 unused macro removed 2006-01-18 09:37:34 -02:00
Roberto Ierusalimschy
73ebc5d8f6 compat code should keep compatibility 2006-01-16 10:42:21 -02:00
Roberto Ierusalimschy
a666752b1d detail 2006-01-13 17:36:28 -02:00
Roberto Ierusalimschy
f8b7a5581e avoid unnecessary exports 2006-01-10 11:13:06 -02:00
Roberto Ierusalimschy
ffb798e1e2 avoids type punning for table keys 2006-01-10 10:51:53 -02:00
Roberto Ierusalimschy
fa936f8fa9 detail 2006-01-10 10:50:13 -02:00
Roberto Ierusalimschy
dd1221582b details 2006-01-10 10:50:00 -02:00
Roberto Ierusalimschy
bfdcbbcd76 small optimizations (lua_newtable -> lua_createtable) 2005-12-29 14:23:32 -02:00
Roberto Ierusalimschy
30eebb2d1c detail (stop collector while openning libraries) 2005-12-29 10:30:16 -02:00
Roberto Ierusalimschy
0fd6466957 lua_assert is an internal matter, not to be configured 2005-12-27 15:12:00 -02:00
Roberto Ierusalimschy
6a516878e9 collectgarbage"count" returns kilobytes (where K = 1024) 2005-12-27 15:10:11 -02:00
Roberto Ierusalimschy
a486090a5c copyright will be 2006 2005-12-27 15:09:50 -02:00
Roberto Ierusalimschy
0160591998 removal of dead code 2005-12-26 11:35:47 -02:00
Roberto Ierusalimschy
c505f341d6 small changes in casts 2005-12-22 14:19:56 -02:00
Roberto Ierusalimschy
428325baec detail 2005-12-21 10:59:43 -02:00
Roberto Ierusalimschy
0561f71f0f (much) better error messages for 'require' 2005-12-19 18:56:39 -02:00
Roberto Ierusalimschy
9fbefdf69c integer formats in 'string.format' may need to operate with larger-than-int
types
2005-12-15 16:53:34 -02:00
Roberto Ierusalimschy
43c61fc113 details 2005-12-15 16:17:49 -02:00
Roberto Ierusalimschy
ea6b1b42c7 more robust way to test for decimal point separator 2005-12-08 13:50:54 -02:00
Roberto Ierusalimschy
87024e257d details 2005-12-07 13:43:05 -02:00
Roberto Ierusalimschy
6cd461633d clearer error message for uninstalled loadlib 2005-12-07 13:42:32 -02:00
Roberto Ierusalimschy
16fd4abaf6 corrects decimal point to follow current locale 2005-12-07 13:33:27 -02:00
Roberto Ierusalimschy
f26b85c5b7 small detail 2005-12-02 16:42:08 -02:00
Roberto Ierusalimschy
3592c08a2c avoid printing two copyright messages with '-v -i' options 2005-11-28 12:44:48 -02:00
Roberto Ierusalimschy
db724e14e0 new macro luai_numisnan 2005-11-25 11:29:32 -02:00
Roberto Ierusalimschy
1702953293 new macro LUA_WIN + new macro luai_numisnan 2005-11-25 11:29:11 -02:00
Roberto Ierusalimschy
33b4dec1cb no more "auto-detection" 2005-11-16 14:25:08 -02:00
Roberto Ierusalimschy
7dd10a1d7e new macro LUA_USE_POSIX to control POSIX-related macros 2005-11-16 09:56:28 -02:00
Roberto Ierusalimschy
521a452f28 'mod' may also raise an error when applied to zero 2005-11-16 09:55:27 -02:00
Roberto Ierusalimschy
2753134a38 new versions by lhf 2005-11-16 09:55:07 -02:00
Roberto Ierusalimschy
cbbde11a8a better position for lua_number2int (it is related to lua_Number) 2005-11-08 17:45:58 -02:00
Roberto Ierusalimschy
7b89cf3aeb unused include's 2005-11-08 17:45:36 -02:00
Roberto Ierusalimschy
d2811e8097 simpler checking for numbers (strtod does the rest) 2005-11-08 17:45:14 -02:00
Roberto Ierusalimschy
e43e95553f more privacy 2005-11-08 17:44:31 -02:00
Roberto Ierusalimschy
930018e273 lua_getlocal/setlocal work also for C locals and temporaries 2005-11-01 14:08:52 -02:00
Roberto Ierusalimschy
a160266c3d details 2005-11-01 14:08:45 -02:00
Roberto Ierusalimschy
d4c99b2673 new function 'getregistry' 2005-11-01 14:08:32 -02:00
Roberto Ierusalimschy
88f9843eee better error message 2005-10-26 11:28:19 -02:00
Roberto Ierusalimschy
9b5ae6faf9 better control of which values macros use 2005-10-25 11:36:28 -02:00
Roberto Ierusalimschy
caf3cfc6ac try to ensure that macros actually use their arguments 2005-10-24 15:39:21 -02:00
Roberto Ierusalimschy
ff7638b0ed VC warnings 2005-10-24 15:38:47 -02:00
Roberto Ierusalimschy
8e48ebb638 no more L in numer-operator macros (some functions that use those macros
have no access to L)
2005-10-24 15:37:52 -02:00
Roberto Ierusalimschy
c2bd68d2c3 detail 2005-10-24 15:37:33 -02:00
Roberto Ierusalimschy
201288b4df small bug 2005-10-23 15:52:42 -02:00
Roberto Ierusalimschy
62367dda44 string.gsub accepts a table as the replacement value 2005-10-23 15:46:30 -02:00
Roberto Ierusalimschy
056b6a8ef4 more robust implementation for table.insert 2005-10-23 15:38:15 -02:00
Roberto Ierusalimschy
502d8f9a06 comments 2005-10-23 15:37:55 -02:00
Roberto Ierusalimschy
7f376e6ea8 do a complete garbage collection in case of errors 2005-10-21 11:48:31 -02:00
Roberto Ierusalimschy
053e873145 new macro luaL_opt to avoid evaluating defaults when no needed 2005-10-21 11:47:42 -02:00
Roberto Ierusalimschy
9f4211310f more precision for gc count 2005-10-20 09:35:50 -02:00
Roberto Ierusalimschy
515d556832 access to metamethods and metafields should be raw 2005-10-20 09:35:25 -02:00
Roberto Ierusalimschy
ed7039024d avoid some warnings 2005-10-19 11:05:11 -02:00
Roberto Ierusalimschy
5511bf6b9d avoid comparisons between (void *) and (int *) 2005-10-17 16:01:51 -02:00
Roberto Ierusalimschy
86704cffe9 detail in usage message 2005-10-14 15:34:23 -03:00
Roberto Ierusalimschy
fa41fafa6e reorganization of argument handling 2005-10-14 15:15:46 -03:00
Roberto Ierusalimschy
ebf646efb5 detail 2005-10-14 13:24:11 -03:00
Roberto Ierusalimschy
b3f81f1d1d small bug when debugging dead threads 2005-10-14 13:23:33 -03:00
Roberto Ierusalimschy
a24eb3ef17 different organization for platform dependencies 2005-10-13 09:22:53 -03:00
Roberto Ierusalimschy
4385e2ada4 "conceptually", OP_TEST may change reg. A 2005-10-13 09:22:05 -03:00
Roberto Ierusalimschy
e9b06c506f small optimization 2005-10-13 09:21:51 -03:00
Roberto Ierusalimschy
cd12ab2597 details (more uniform coding) 2005-10-13 09:21:26 -03:00
Roberto Ierusalimschy
e251e84e0f constant folding optimizations 2005-10-09 17:05:48 -03:00
Roberto Ierusalimschy
e6bfbc38b5 'luaopen_package' was missing in new states 2005-10-06 17:47:32 -03:00
Roberto Ierusalimschy
d31c04c049 missing macros 'luai_userstate*' 2005-10-06 17:46:25 -03:00
Roberto Ierusalimschy
522481a788 avoid some warnings 2005-10-06 17:46:10 -03:00
Roberto Ierusalimschy
37b49aa451 detail 2005-10-06 17:44:22 -03:00
Roberto Ierusalimschy
0fa9b16148 details 2005-10-06 17:43:44 -03:00
Roberto Ierusalimschy
e41fb9a604 registry._LOADED created "on demand" 2005-10-03 11:36:45 -03:00
Roberto Ierusalimschy
5fc92cce12 registry._LOADED created "on demand" and baselib created as module _G 2005-10-03 11:36:45 -03:00
Roberto Ierusalimschy
6dd0c6ccbc numeral expressions keep their values in struct 'expdesc' 2005-10-03 11:02:40 -03:00
Roberto Ierusalimschy
a77413acd0 include of math.h depends on luaconf 2005-10-03 11:01:26 -03:00
Roberto Ierusalimschy
5dbb870815 small optimization for local declarations without initializations 2005-09-30 11:23:33 -03:00
Roberto Ierusalimschy
ede19c9138 2005-09-30 11:21:56 -03:00
Roberto Ierusalimschy
9e88b336b4 unused assignment 2005-09-30 10:50:05 -03:00
Roberto Ierusalimschy
0fae476ed4 new function 'table.maxn' 2005-09-20 14:56:47 -03:00
Roberto Ierusalimschy
361a9adba7 smaller initial tables (for programs that create many states) 2005-09-20 14:55:53 -03:00
Roberto Ierusalimschy
d8f1cca16e new function 'lua_setallocf' 2005-09-20 14:55:10 -03:00
Roberto Ierusalimschy
bf96d3fdd9 'string.find' as it was in 5.0 2005-09-19 10:49:12 -03:00
Roberto Ierusalimschy
c8c2e06899 'select' accepts negative indices 2005-09-16 15:22:48 -03:00
Roberto Ierusalimschy
8dcc6bc532 avoid the use of global lock 2005-09-14 14:48:57 -03:00
Roberto Ierusalimschy
38f585d271 separated macros for thread creation and state creation 2005-09-14 14:44:48 -03:00
Roberto Ierusalimschy
6887f91799 ":" is not a good mark as it is not valid in Windows file names 2005-09-14 14:23:03 -03:00
Roberto Ierusalimschy
7fbbf1adc6 explicit macro to control use of _longjmp 2005-09-09 15:24:42 -03:00
Roberto Ierusalimschy
6dd3a73ca2 detail (macro evaluates twice its arguments) 2005-09-09 15:23:35 -03:00
Roberto Ierusalimschy
1e6a559b29 does not set isdst when undefined 2005-09-09 15:22:46 -03:00
Roberto Ierusalimschy
2d2f955763 detail 2005-09-09 15:16:28 -03:00
Roberto Ierusalimschy
669f6306be small corrections 2005-09-06 14:21:03 -03:00
Roberto Ierusalimschy
2bcbd3c725 avoid 'PathRemoveFileSpec' (not very portable) 2005-09-06 14:20:25 -03:00
Roberto Ierusalimschy
5fa6604f00 detail 2005-09-06 14:20:11 -03:00
Roberto Ierusalimschy
ce67a9be31 avoid exporting undefined functions 2005-09-06 14:19:51 -03:00
Roberto Ierusalimschy
506c89cef8 just in case, flush all output 2005-09-06 14:19:33 -03:00
Roberto Ierusalimschy
8ead2ec358 wrong syntax for Windows-specific options 2005-09-02 16:53:25 -03:00
Roberto Ierusalimschy
c3cc4de3fd small bug (zero is not error code) 2005-09-01 14:42:22 -03:00
Roberto Ierusalimschy
351f7dad6b default for 'module' is opaque (with option 'seeall') 2005-08-31 20:17:29 -03:00
Roberto Ierusalimschy
3b19af44b0 new method to handle tests without values (negative values) 2005-08-29 17:49:21 -03:00
Roberto Ierusalimschy
3390f9a35a detail 2005-08-26 14:36:32 -03:00
Roberto Ierusalimschy
9273fbd131 no more 'luaL_get/setfield' (replaced by more direct luaL_findtable) 2005-08-26 14:32:05 -03:00
Roberto Ierusalimschy
be666a662b detail 2005-08-25 16:55:38 -03:00
Roberto Ierusalimschy
39cdbce23e no more '-w' option + new way to check module existence 2005-08-25 12:39:16 -03:00
Roberto Ierusalimschy
8974b59e40 no more compatibility for {;} and similar syntax 2005-08-24 14:41:10 -03:00
Roberto Ierusalimschy
4ff1e5b4e1 details 2005-08-24 14:06:36 -03:00
Roberto Ierusalimschy
98296f6b45 some bugs related to stack reallocation 2005-08-24 13:15:49 -03:00
Roberto Ierusalimschy
23b79c5945 small changes to facilitate external C coroutines 2005-08-22 16:58:29 -03:00
Roberto Ierusalimschy
6fcd334ca0 small improvements 2005-08-22 15:54:49 -03:00
Roberto Ierusalimschy
43ad0637ca small optimizations 2005-08-22 15:54:32 -03:00
Roberto Ierusalimschy
027e9e99ca simpler implementation for userdata types 2005-08-18 17:36:26 -03:00
Roberto Ierusalimschy
3b828d9e48 luaL_setfield does a non-raw set 2005-08-18 13:04:05 -03:00
Roberto Ierusalimschy
68548a02d3 fancier code ;) 2005-08-17 17:09:31 -03:00
Roberto Ierusalimschy
2f2b4a42a9 luaL_checkudata raises an error if value is not correct
(like other luaL_check functions)
2005-08-17 16:05:04 -03:00
Roberto Ierusalimschy
074352911f new coding for while and repeat (with new scoping for repeat) 2005-08-17 15:32:09 -03:00
Roberto Ierusalimschy
5e8a9e324c luaL_openlib -> luaL_register, luaL_putchar -> luaL_addchar 2005-08-15 11:12:32 -03:00
Roberto Ierusalimschy
16ddf86168 luaL_openlib -> luaL_register and new function luaL_loadstring 2005-08-15 11:12:32 -03:00
Roberto Ierusalimschy
e4d369c9b7 comments 2005-08-12 10:34:15 -03:00
Roberto Ierusalimschy
42a662334a simpler implementation for unary minus 2005-08-10 17:20:13 -03:00
Roberto Ierusalimschy
39c0f391c6 detail 2005-08-10 15:47:09 -03:00
Roberto Ierusalimschy
c7b4f44772 correct name to open package library 2005-08-10 15:06:58 -03:00
Roberto Ierusalimschy
44b19075c0 small changes (to easy integration with Coco) 2005-08-09 16:49:04 -03:00
Roberto Ierusalimschy
ab3dfa5594 store some configuration information 2005-08-09 14:58:09 -03:00
Roberto Ierusalimschy
62f786e08c new version (and new copyright)... 2005-08-09 14:57:54 -03:00
Roberto Ierusalimschy
bbfd28959d attempt to better control use of _longjmp 2005-08-09 14:57:29 -03:00
Roberto Ierusalimschy
894cd31c52 #string is primitive 2005-08-09 14:42:02 -03:00
Roberto Ierusalimschy
f01a95d4a0 detail 2005-08-09 09:30:19 -03:00
Roberto Ierusalimschy
680fc88cc2 a small bug 2005-08-04 10:37:38 -03:00
Roberto Ierusalimschy
d96f088a26 'lua_lock' and similars should be hard to use 2005-08-04 10:37:10 -03:00
Roberto Ierusalimschy
d8be9a6326 small changes 2005-08-01 12:05:09 -03:00
Roberto Ierusalimschy
95f3eefa5b small optimization 2005-08-01 01:22:23 -03:00
Roberto Ierusalimschy
e82bdb24f3 new loader for "all-in-one" C packages 2005-08-01 01:21:17 -03:00
Roberto Ierusalimschy
1a343814d8 details 2005-07-31 14:12:32 -03:00
Roberto Ierusalimschy
280f7becb8 "%0" stands for the whole pattern (in gsub) 2005-07-31 13:47:34 -03:00
Roberto Ierusalimschy
d6ff5d9f46 searchpath is "private affair" of loadlib 2005-07-13 16:02:42 -03:00
Roberto Ierusalimschy
a05190fa3b elimination of common code + better error message 2005-07-12 18:17:46 -03:00
Roberto Ierusalimschy
a569099b70 no more path for loadfile + function lists sorted 2005-07-12 15:15:11 -03:00
Roberto Ierusalimschy
20131e54d3 no more "getc" when testing if file exists 2005-07-12 11:32:48 -03:00
Roberto Ierusalimschy
80ac5e83fd details (alphabetical order for list of functions) 2005-07-12 11:32:08 -03:00
Roberto Ierusalimschy
289b5dc67a details (function list in alphabetical order) 2005-07-11 20:58:35 -03:00
Roberto Ierusalimschy
c2f065f405 detail 2005-07-11 15:48:02 -03:00
Roberto Ierusalimschy
b261cd110f new macro for conversion double->int + small changes 2005-07-11 14:10:35 -03:00
Roberto Ierusalimschy
e4324f54b9 ';;' in a path is replaced by default path + '!' (in Windows) is
replaced by executable's directory
2005-07-11 13:41:57 -03:00
Roberto Ierusalimschy
3d08aa591d details 2005-07-11 13:41:51 -03:00
Roberto Ierusalimschy
0f30d00c87 warnings from Visual C 2005-07-11 11:01:37 -03:00
Roberto Ierusalimschy
e86dab2dae details 2005-07-11 11:01:28 -03:00
Roberto Ierusalimschy
64b57db377 new test function for conversion from num to int 2005-07-11 11:00:59 -03:00
Roberto Ierusalimschy
575637319e better recovery at panic 2005-07-11 11:00:31 -03:00
Roberto Ierusalimschy
87be01598b warnings Visual C 2005-07-11 10:59:03 -03:00
Roberto Ierusalimschy
e84b11a494 avoid names starting with '_' 2005-07-09 10:22:34 -03:00
Roberto Ierusalimschy
bbf2cea9a1 more "polite" way to change a thread's environment 2005-07-07 12:48:29 -03:00
Roberto Ierusalimschy
b3f7a43019 lua_setfenv/lua_getfenv should also manipulate threads 2005-07-06 15:07:30 -03:00
Roberto Ierusalimschy
7f97ec286e parent modules are also imported toghether with the module itself 2005-07-05 16:29:03 -03:00
Roberto Ierusalimschy
e82b41aac2 several small improvements 2005-07-05 11:31:45 -03:00
Roberto Ierusalimschy
ee1edd5734 detail 2005-07-05 11:31:20 -03:00
Roberto Ierusalimschy
8efb44b5e0 changes in 'string.find' and 'string.gfind' (new 'string.match' and
'string.gmatch')
2005-07-05 11:30:38 -03:00
Roberto Ierusalimschy
f7720bebe3 more precise way to check incomplete lines 2005-06-28 10:01:50 -03:00
Roberto Ierusalimschy
69cc0a12fe small bug 2005-06-28 10:01:31 -03:00
Roberto Ierusalimschy
2f0955b99b detail 2005-06-27 14:24:40 -03:00
Roberto Ierusalimschy
999d55d887 several updates 2005-06-13 18:20:28 -03:00
Roberto Ierusalimschy
1f9f97e3cf 'math.mod' -> 'math.fmod' 2005-06-13 18:20:14 -03:00
Roberto Ierusalimschy
34aac33c15 detail 2005-06-13 18:17:59 -03:00
Roberto Ierusalimschy
3c2cf9db67 some extra consistency checks 2005-06-13 11:39:19 -03:00
Roberto Ierusalimschy
0b71bfd6af syntax for length changed from '*' to '#' 2005-06-13 11:25:29 -03:00
Roberto Ierusalimschy
0d1685d751 bug: last tag is not the number of tags... 2005-06-13 11:19:00 -03:00
Roberto Ierusalimschy
bf2b342ac1 better control for compatibility code for varargs 2005-06-13 11:15:54 -03:00
Roberto Ierusalimschy
5fa2bec1f0 bug: current line should work for call hook 2005-06-13 11:15:22 -03:00
Roberto Ierusalimschy
746a1d612b small bug (type error) 2005-06-07 15:53:45 -03:00
Roberto Ierusalimschy
3ad03b331d optional size for 'setvbuf' 2005-06-06 15:42:21 -03:00
Roberto Ierusalimschy
86add535d8 'popen' is back 2005-06-06 10:30:52 -03:00
Roberto Ierusalimschy
d987cf1f81 new mark LUAI_DATA for extern data 2005-06-06 10:30:25 -03:00
Roberto Ierusalimschy
eca9fa02d2 small improvement 2005-06-03 17:16:16 -03:00
Roberto Ierusalimschy
e33d7bae45 __STRICT_ANSI__ -> LUA_ANSI (definition is independent of gcc) 2005-06-01 14:07:45 -03:00
Roberto Ierusalimschy
d628795940 lua_objsize -> lua_objlen (more compatible with use of `len´ in other
places [opcode name, metamethod index, etc.])
2005-05-31 11:34:02 -03:00
Roberto Ierusalimschy
05348d834b better error message 2005-05-31 11:31:50 -03:00
Roberto Ierusalimschy
90de38bf1f warnings in VS .Net 2005-05-31 11:25:18 -03:00
Roberto Ierusalimschy
e8a7ecb982 luaL_findstring -> luaL_checkoption 2005-05-25 10:21:26 -03:00
Roberto Ierusalimschy
38da9d568a better use defined/undefined as flag values for macros 2005-05-20 16:09:05 -03:00
Roberto Ierusalimschy
f21e9c172f details 2005-05-20 12:53:42 -03:00
Roberto Ierusalimschy
67578ec51f several small details 2005-05-17 16:49:15 -03:00
Roberto Ierusalimschy
c2bb9abcec better quotes for strings in error messages 2005-05-16 18:19:00 -03:00
Roberto Ierusalimschy
da32450c3d new API function `lua_tolstring' 2005-05-16 16:21:11 -03:00
Roberto Ierusalimschy
a2b78aad49 debug information for active lines 2005-05-16 15:45:15 -03:00
Roberto Ierusalimschy
c6293a76cc LUA_DL_DLOPEN is for internal use; makefile should use LUA_USE_DLOPEN 2005-05-09 10:14:14 -03:00
Roberto Ierusalimschy
1ab2b93462 debug information for last line of a function definition 2005-05-05 17:47:02 -03:00
Roberto Ierusalimschy
6cf85dcc90 metatables for all types 2005-05-05 12:34:03 -03:00
Roberto Ierusalimschy
65f4a0f636 no more compatibility code for traversing tables 2005-05-04 17:42:28 -03:00
Roberto Ierusalimschy
12acca7bd8 comments 2005-05-04 13:36:23 -03:00
Roberto Ierusalimschy
d5fd44d747 corrected definition of lua_number2int for Windows 2005-05-03 16:30:17 -03:00
Roberto Ierusalimschy
b0abc2ca03 better control of local variables in luaV_execute 2005-05-03 16:01:17 -03:00
Roberto Ierusalimschy
b320d37a80 better tests for correctness of `savedpc' 2005-05-03 16:01:17 -03:00
Roberto Ierusalimschy
9b8d136e1c `*' operator is primitive only for tables 2005-05-02 14:49:43 -03:00
Roberto Ierusalimschy
9832f6b186 small bug 2005-04-29 10:54:05 -03:00
Roberto Ierusalimschy
8e696dd14a detail 2005-04-29 10:53:59 -03:00
Roberto Ierusalimschy
c3939f5786 comment 2005-04-29 09:43:47 -03:00
Roberto Ierusalimschy
bcc4089a7d comment 2005-04-27 15:53:53 -03:00
Roberto Ierusalimschy
cf5d1bdd76 nesting of long strings only in compatibility mode 2005-04-27 15:37:51 -03:00
Roberto Ierusalimschy
8718fda9b2 added LUAI_FUNC to functions not in the API 2005-04-25 16:24:10 -03:00
Roberto Ierusalimschy
8c3c3e7691 small bug for tail-recursive debugging 2005-04-14 10:30:47 -03:00
Roberto Ierusalimschy
04f657c7f8 new protocol to open standard libraries 2005-04-13 14:24:20 -03:00
Roberto Ierusalimschy
2873d4efff stack could overflow with too many command-line arguments 2005-04-11 15:01:35 -03:00
Roberto Ierusalimschy
a7ea0c71e8 detail 2005-04-11 15:01:29 -03:00
Roberto Ierusalimschy
b1957b1e8e detail for Windows (untested) 2005-04-07 10:52:45 -03:00
Roberto Ierusalimschy
a17e1fe124 new organization using only one library 2005-04-07 10:52:19 -03:00
Roberto Ierusalimschy
fabf5db237 C stack is the same for the parser and the interpreter, so depth
control should be unified in both parts.
2005-04-07 10:09:07 -03:00
Roberto Ierusalimschy
de0bfe33b7 new definition for `lua_number2int' for Windows (not tested yet!) 2005-04-06 14:30:13 -03:00
Roberto Ierusalimschy
9768e2f681 detail 2005-04-05 12:57:59 -03:00
Roberto Ierusalimschy
71eb824036 details 2005-04-05 12:35:15 -03:00
Roberto Ierusalimschy
7b6c3b463e small optimizations 2005-04-05 10:41:29 -03:00
Roberto Ierusalimschy
0316308c0d removed dirt optimizations that gave small gains 2005-04-04 15:12:51 -03:00
Roberto Ierusalimschy
409ee99900 detail 2005-04-01 10:51:37 -03:00
Roberto Ierusalimschy
445eda7ead details 2005-03-30 16:50:29 -03:00
Roberto Ierusalimschy
092dc95b06 using require' to implement -l' 2005-03-29 13:47:48 -03:00
Roberto Ierusalimschy
e6e543a534 better control for compatibility code 2005-03-29 13:20:48 -03:00
Roberto Ierusalimschy
1c9c886974 standard configuration should run out-of-the-box in "any" system 2005-03-29 11:30:16 -03:00
Roberto Ierusalimschy
ade585bdf9 no more LUA_FIRSTINDEX 2005-03-28 14:17:53 -03:00
Roberto Ierusalimschy
04c41444e2 wrong comment corrected 2005-03-28 09:53:40 -03:00
Roberto Ierusalimschy
03fb3c39d4 change #ifdef' for #if defined' 2005-03-23 14:51:11 -03:00
Roberto Ierusalimschy
8af1ca02e0 LUA_USERCONFIG is no longer necessary 2005-03-23 14:50:49 -03:00
Roberto Ierusalimschy
f1eb79fdf4 some line-edit facilities must free the line after its use 2005-03-22 13:55:35 -03:00
Roberto Ierusalimschy
408cb71795 avoid name conflict with some spurious included header files 2005-03-22 13:54:29 -03:00
Roberto Ierusalimschy
390256edf7 better name for GC pause 2005-03-22 13:04:29 -03:00
Roberto Ierusalimschy
ad24cff0f1 lua_gc(STEP) returns whether collection cycle finished 2005-03-21 15:12:21 -03:00
Roberto Ierusalimschy
6d475731ca cleaner configuration for lua.c 2005-03-21 15:12:07 -03:00
Roberto Ierusalimschy
f41fc0eb0e small bug: a GC step was not proportional to its "size" 2005-03-18 17:11:28 -03:00
Roberto Ierusalimschy
d872090248 small errors in previous `ci' of luaconf.h. 2005-03-18 15:55:45 -03:00
Roberto Ierusalimschy
fb0f95a2b7 call limit may be larger than shorts 2005-03-18 15:55:09 -03:00
Roberto Ierusalimschy
d3a6d95b9a more cleaning on configurations 2005-03-18 15:02:04 -03:00
Roberto Ierusalimschy
47984a0cc2 internal definitions have prefix `luai_' 2005-03-18 15:01:37 -03:00
Roberto Ierusalimschy
086d6b09ce avoid name colision with `close' function 2005-03-18 15:01:14 -03:00
Roberto Ierusalimschy
bfe2905618 avoid too much configuration options 2005-03-18 13:38:43 -03:00
Roberto Ierusalimschy
2cbd9eecfb try to avoid warnings 2005-03-18 13:38:02 -03:00
Roberto Ierusalimschy
4494094031 detail 2005-03-16 17:02:48 -03:00
Roberto Ierusalimschy
04bbd01171 new operation *t (for size of t) (may yet be removed...) 2005-03-16 13:59:21 -03:00
Roberto Ierusalimschy
9ffae705ee new "primitive" getn 2005-03-16 13:58:41 -03:00
Roberto Ierusalimschy
6bfef60e77 bug: rawset/rawget do not ignore extra arguments 2005-03-11 12:51:08 -03:00
Roberto Ierusalimschy
370d31a559 luac´ -> luai' (to avoid confusion with other luac stuff) 2005-03-09 13:28:07 -03:00
Roberto Ierusalimschy
f8df21bd20 `luaconf.h´ exports all its definitions always (so all of them
must have a lua/LUA prefix).
2005-03-08 17:10:05 -03:00
Roberto Ierusalimschy
d3902cfa81 entries `{[...] = ...}' need space too. 2005-03-08 15:16:45 -03:00
Roberto Ierusalimschy
b5b230d95c fewer #include's in luaconf.h 2005-03-08 15:09:16 -03:00
Roberto Ierusalimschy
7d57ea70bc new mod' (%') operator 2005-03-08 15:00:16 -03:00
Roberto Ierusalimschy
2d5b923759 details 2005-03-08 10:37:55 -03:00
Roberto Ierusalimschy
192d185492 C module names may have an optional `l' prefix 2005-03-08 10:27:36 -03:00
Roberto Ierusalimschy
e010ef8948 detail 2005-03-07 15:27:34 -03:00
Roberto Ierusalimschy
1e48b20ce0 loadlib' not global anymore (packaged inside package') 2005-03-07 15:07:34 -03:00
Roberto Ierusalimschy
d1ed6e4c07 small bug: must use original (previous) base 2005-03-07 13:59:01 -03:00
Roberto Ierusalimschy
b6a7983b65 USHRT_MAX may not fit in a (16-bit) int 2005-03-07 13:58:27 -03:00
Roberto Ierusalimschy
49f90ffdeb new functions (to complete math.h) 2005-03-04 15:57:03 -03:00
Roberto Ierusalimschy
dcabf721f8 "coroutine.current" -> "running" (compatible with "running" status) 2005-02-28 14:24:41 -03:00
Roberto Ierusalimschy
5eeff89f32 comments 2005-02-28 12:59:11 -03:00
Roberto Ierusalimschy
d6143b1d7b avoid access to undefined global variables 2005-02-28 12:58:48 -03:00
Roberto Ierusalimschy
d55bb795fa details 2005-02-23 14:30:22 -03:00
Roberto Ierusalimschy
d84cc9d2db small bug 2005-02-18 10:50:08 -02:00
Roberto Ierusalimschy
7d45a5f48f C functions and userdata also have environments 2005-02-18 10:40:02 -02:00
Roberto Ierusalimschy
73d7640244 more secure way to stop GC cycles during finalizers 2005-02-14 11:19:50 -02:00
Roberto Ierusalimschy
a9af455b32 detail 2005-02-14 11:19:44 -02:00
Roberto Ierusalimschy
678d2fb2ac all collected userdata must go to the end of the list of finalizers 2005-02-11 18:03:35 -02:00
Roberto Ierusalimschy
af39352632 LUA_PATH_SEP -> LUA_PATHSEP 2005-02-10 15:12:02 -02:00
Roberto Ierusalimschy
4df8800a01 cleaner way to free all objects 2005-02-10 11:25:02 -02:00
Roberto Ierusalimschy
0e60572606 values holded in open upvalues of suspended threads may be
incorrectly collected
2005-01-19 15:03:47 -02:00
Roberto Ierusalimschy
621ef9f767 better control over GC collors of upvalues 2005-01-19 13:54:26 -02:00
Roberto Ierusalimschy
d89a56f869 small warning in C++ 2005-01-18 15:23:25 -02:00
Roberto Ierusalimschy
334ba8132b cleaner way to remark open upvalues 2005-01-18 15:18:09 -02:00
Roberto Ierusalimschy
ac71a0891d detail 2005-01-17 21:50:55 -02:00
Roberto Ierusalimschy
8e346d875a auxiliar patch to monitor garbage collection 2005-01-14 12:21:16 -02:00
Roberto Ierusalimschy
5be517602e no more generational collector (and no more `noinc' mode) 2005-01-14 12:19:42 -02:00
Roberto Ierusalimschy
d2bda8046c new implementation for loaders 2005-01-14 12:17:18 -02:00
Roberto Ierusalimschy
a72fbf794d detail 2005-01-10 17:16:29 -02:00
Roberto Ierusalimschy
8ddfe3df29 macros for all arithmetic operations over lua_Numbers 2005-01-10 16:17:39 -02:00
Roberto Ierusalimschy
6eb68ba57a all function declarations surround name with parentheses 2005-01-10 15:31:50 -02:00
Roberto Ierusalimschy
a27497aa03 debug.traceback' gets an optional initial level' parameter 2005-01-10 15:21:10 -02:00
Roberto Ierusalimschy
0480ea0886 gets `debug.traceback' current when error occurs 2005-01-10 15:21:10 -02:00
Roberto Ierusalimschy
162b66624d no more `lua_userinit' macro 2005-01-10 14:31:30 -02:00
Roberto Ierusalimschy
e791f025c0 no more `_TRACEBACK' variable 2005-01-10 14:30:59 -02:00
Roberto Ierusalimschy
f61d435a7d a^b calls `pow´ (from math.h) directly 2005-01-07 18:00:33 -02:00
Roberto Ierusalimschy
071b2ae0e1 details 2005-01-07 17:53:32 -02:00
Roberto Ierusalimschy
e2498e079e change in hash algorithm so that it does not need empty slot
(tables can be 100% full)
2005-01-05 16:20:51 -02:00
Roberto Ierusalimschy
65726f3e2e cleaner interface to `ltable' 2005-01-04 13:55:12 -02:00
Roberto Ierusalimschy
9fe2d0266a better configuration for Windows 2005-01-04 10:46:04 -02:00
Roberto Ierusalimschy
e22cdf7752 better error messages when require fails for C module 2004-12-29 16:56:34 -02:00
Roberto Ierusalimschy
a5eb48a3e6 redesigned loadlib (Windows version not tested yet) 2004-12-27 13:58:15 -02:00
Roberto Ierusalimschy
49fe79e9fd small change 2004-12-27 13:58:15 -02:00
Roberto Ierusalimschy
96727c61b8 several improvements/corrections 2004-12-22 15:43:27 -02:00
Roberto Ierusalimschy
d5ebc3ff6d small changes 2004-12-22 11:05:33 -02:00
Roberto Ierusalimschy
3d19aee78f `luac' may generate code without upvalue names 2004-12-20 13:50:00 -02:00
Roberto Ierusalimschy
4194de70e7 details 2004-12-20 11:47:29 -02:00
Roberto Ierusalimschy
c6254dceff a different option for the GC 2004-12-13 10:15:11 -02:00
Roberto Ierusalimschy
a56d889f72 corrections for `absent' implementation 2004-12-13 10:14:21 -02:00
Roberto Ierusalimschy
2ec4fc4295 simpler code for `print' 2004-12-07 16:31:34 -02:00
Roberto Ierusalimschy
70751dd27c details 2004-12-07 16:31:16 -02:00
Roberto Ierusalimschy
39a8082f50 more options for controling the GC 2004-12-06 15:53:42 -02:00
Roberto Ierusalimschy
531874f6ce better (correct?) way to handle `next' over removed keys 2004-12-04 16:10:22 -02:00
Roberto Ierusalimschy
61a888518f details 2004-12-03 18:54:12 -02:00
Roberto Ierusalimschy
c78940f21a static names do not need `luaX_' prefix 2004-12-03 18:50:25 -02:00
Roberto Ierusalimschy
8b239eeba1 details 2004-12-03 18:44:19 -02:00
Roberto Ierusalimschy
a5330b77f3 static names do not need `luaX_' prefix 2004-12-03 18:35:33 -02:00
Roberto Ierusalimschy
e1c2fb6eed details 2004-12-02 10:59:10 -02:00
Roberto Ierusalimschy
12dacd3c0e added an `L' parameter to macros L_TRY & L_THROW (someone may need it). 2004-12-01 13:52:54 -02:00
Roberto Ierusalimschy
23b38176a7 `LUA_FIRSTINDEX' should not be configurable 2004-12-01 13:50:18 -02:00
Roberto Ierusalimschy
97e2dab1fb better control of overflows in size computations 2004-12-01 13:46:18 -02:00
Roberto Ierusalimschy
0ed8519127 detail 2004-12-01 13:46:06 -02:00
Roberto Ierusalimschy
0e002005b1 better names for `luaM_free...' macros 2004-11-24 17:20:21 -02:00
Roberto Ierusalimschy
1d99a7360b details 2004-11-24 17:16:03 -02:00
Roberto Ierusalimschy
2f82bf6fe9 better support for 64-bit machines 2004-11-24 16:55:56 -02:00
Roberto Ierusalimschy
087df82a61 detail 2004-11-24 16:55:42 -02:00
Roberto Ierusalimschy
10e48b9160 details 2004-11-19 14:59:08 -02:00
Roberto Ierusalimschy
6f1ea817f5 better control over memory-size overflows 2004-11-19 13:52:40 -02:00
Roberto Ierusalimschy
cdcb236747 needs to include stdlib.h' to access getenv' 2004-11-19 13:52:12 -02:00
Roberto Ierusalimschy
9be5844713 first full implementation of new package system 2004-11-18 17:53:49 -02:00
Roberto Ierusalimschy
497f042fad detail 2004-11-17 10:02:41 -02:00
Roberto Ierusalimschy
2ed07ea8c1 towards "requiring" C libraries 2004-11-11 13:42:57 -02:00
Roberto Ierusalimschy
cfd7bc478f better patch for buffer overflow error 2004-11-03 10:22:39 -02:00
Roberto Ierusalimschy
737ec947d3 better implementation for `floating-point bytes' 2004-11-01 12:06:50 -03:00
Roberto Ierusalimschy
45d566f676 small corrections (thanks to Mike Pall) 2004-11-01 11:33:33 -03:00
Roberto Ierusalimschy
cfb79b1751 more secure way to compute final string length 2004-10-28 14:45:51 -03:00
Roberto Ierusalimschy
3e1a1f2836 better configuration for loadlib + tested Mac OS X version 2004-10-18 15:07:31 -03:00
Roberto Ierusalimschy
b32e9a46d2 better configuration for loadlib 2004-10-18 15:07:31 -03:00
Roberto Ierusalimschy
e5cfa7a367 use of parentheses around macro parameters in call lists, to avoid
problems with comma expressions
2004-10-18 09:51:44 -03:00
Roberto Ierusalimschy
aae1612747 avoid name chash in `all.c' 2004-10-08 15:57:16 -03:00
Roberto Ierusalimschy
8050e75f9d bug: gc metamethod must disable GC steps (to avoid nested calls) 2004-10-08 13:00:34 -03:00
Roberto Ierusalimschy
3bec76abe3 first version of loadlib for Mac OS X (not tested yet!!) 2004-10-07 14:27:20 -03:00
Roberto Ierusalimschy
5cb6037d49 cannot jump to a setlist count 2004-10-07 14:27:00 -03:00
Roberto Ierusalimschy
f1c2dd3aed detail 2004-10-06 15:34:47 -03:00
Roberto Ierusalimschy
bd38017ddf small optimization for table size in machines with double allignment 2004-10-06 15:34:16 -03:00
Roberto Ierusalimschy
652f885c30 detail 2004-10-04 16:07:42 -03:00
Roberto Ierusalimschy
f7e9465a0c new format for SETLIST opcode 2004-10-04 16:04:34 -03:00
Roberto Ierusalimschy
5ee87acd6b small optimization for boolean constants + new format for SETLIST opcode 2004-10-04 16:01:53 -03:00
Roberto Ierusalimschy
5d834bdf57 function constants may include boolean values 2004-10-04 16:01:12 -03:00
Roberto Ierusalimschy
67391a35da details 2004-09-29 18:03:42 -03:00
Roberto Ierusalimschy
36541dec9b towards new package system 2004-09-29 18:03:14 -03:00
Roberto Ierusalimschy
cf2a194edc better API for luaL_getfield/setfield 2004-09-29 18:00:25 -03:00
Roberto Ierusalimschy
66845f415f small optimizations 2004-09-27 15:54:45 -03:00
Roberto Ierusalimschy
b2820f39a2 long string delimiter changed from [*[' to [=[' 2004-09-22 11:02:00 -03:00
Roberto Ierusalimschy
8b5bb6056b removal of unused variable 2004-09-22 09:37:52 -03:00
Roberto Ierusalimschy
4973682294 small bug with coroutine tracebacks 2004-09-21 14:58:06 -03:00
Roberto Ierusalimschy
6acfb91c8d new auxiliary functions to implement new package system 2004-09-21 13:54:32 -03:00
Roberto Ierusalimschy
2419f2bf02 cleaner API for coroutines 2004-09-15 17:39:42 -03:00
Roberto Ierusalimschy
0e54d2be36 bug: barrier was wrong for generational phase 2004-09-15 17:38:15 -03:00
Roberto Ierusalimschy
226c57fec0 simpler configuration to turn on all asserts 2004-09-10 14:30:46 -03:00
Roberto Ierusalimschy
0de2065f4e tighter tests for stack overflow 2004-09-08 11:23:09 -03:00
Roberto Ierusalimschy
ee165043ef two bugs related to varargs 2004-09-03 12:48:56 -03:00
Roberto Ierusalimschy
3c394b12f9 detail 2004-09-03 10:17:14 -03:00
Roberto Ierusalimschy
79fc7dea43 simpler implementation for generic reader 2004-09-03 10:16:48 -03:00
Roberto Ierusalimschy
9c34e23214 new libs loslib´ and linit´ 2004-09-01 10:49:20 -03:00
Roberto Ierusalimschy
2aba14b623 details 2004-09-01 10:47:31 -03:00
Roberto Ierusalimschy
1dd8c9b6b6 detail 2004-08-31 14:57:33 -03:00
Roberto Ierusalimschy
7d309480dd new way to handle _PATH (old LUA_PATH) 2004-08-30 15:35:14 -03:00
Roberto Ierusalimschy
bcb2cb59ac select' returns all values after given n' 2004-08-30 12:28:32 -03:00
Roberto Ierusalimschy
0b06241483 better control for GC cycles 2004-08-30 10:44:44 -03:00
Roberto Ierusalimschy
857253cdfc detail 2004-08-30 10:44:04 -03:00
Roberto Ierusalimschy
5dcd908add detail 2004-08-26 11:19:55 -03:00
Roberto Ierusalimschy
32d4f304db first implementation of generational GC 2004-08-24 17:12:06 -03:00
Roberto Ierusalimschy
4b12eff801 small correction (less conservative write barrier for tables) 2004-08-24 17:09:11 -03:00
Roberto Ierusalimschy
271e05917f bug: lua_getupvalue and setupvalue do not check for index too small. 2004-08-17 14:45:45 -03:00
Roberto Ierusalimschy
fe8c365281 default state (created by `luaL_newstate´) has a default panic function 2004-08-13 16:52:53 -03:00
Roberto Ierusalimschy
2d8b099274 better checking for read errors (with `ferror´) 2004-08-13 16:52:13 -03:00
Roberto Ierusalimschy
ff4f8fe59a small bug: calls to upvalues were not correctly traced 2004-08-13 15:02:36 -03:00
Roberto Ierusalimschy
a7c74c06b9 small bug: lua_gc(count) was falling through to next option 2004-08-12 14:02:51 -03:00
Roberto Ierusalimschy
c7dda42c2f bug (due to new handling of varargs) 2004-08-12 11:19:51 -03:00
Roberto Ierusalimschy
26ae992129 less conservative write barrier for tables 2004-08-10 16:17:23 -03:00
Roberto Ierusalimschy
f87057690b `io.lines' also can give the file name in its error message 2004-08-09 11:35:59 -03:00
Roberto Ierusalimschy
9e6aa878c9 string.byte truncates indices out of range 2004-08-09 10:30:33 -03:00
Roberto Ierusalimschy
c0fdaf5842 string.byte may return multiple values 2004-08-06 14:35:38 -03:00
Roberto Ierusalimschy
2430d3cb28 small changes (due to Rici Lake) to allow testing non-supported OS functions 2004-08-05 16:30:37 -03:00
Roberto Ierusalimschy
6bddbbde7a details (opcode may not be the first field) 2004-08-04 17:18:13 -03:00
Roberto Ierusalimschy
31e48f26ed small bug 2004-07-16 10:30:53 -03:00
Roberto Ierusalimschy
0d9007b642 no more LUA_OPNAMES 2004-07-16 10:17:00 -03:00
Roberto Ierusalimschy
9609236fbb no more LUA_OPNAMES; it is simpler to "waste" 400 bytes 2004-07-16 10:15:32 -03:00
Roberto Ierusalimschy
942496d767 small bug 2004-07-13 17:11:32 -03:00
Roberto Ierusalimschy
a535ad6fee several small changes (mainly function names) 2004-07-13 16:56:44 -03:00
Roberto Ierusalimschy
4206d7ed60 `lua_Chunkwriter' returns 0 in case of success 2004-07-09 15:24:41 -03:00
Roberto Ierusalimschy
7a796a0682 new macro `luaL_typename' 2004-07-09 15:23:17 -03:00
Roberto Ierusalimschy
76d8b8db06 lua_pushfstring' now supports %p' option too 2004-07-09 13:01:38 -03:00
Roberto Ierusalimschy
ce455481ab separation between io lib and os lib 2004-07-09 12:47:48 -03:00
Roberto Ierusalimschy
85f1d70e68 OS lib (finally separated from io lib) 2004-07-09 12:47:48 -03:00
Roberto Ierusalimschy
31f6540fba back with an "open all libs" function 2004-07-09 11:29:29 -03:00
Roberto Ierusalimschy
eab1965c05 bug: `lua_setfenv' needs a write barrier 2004-07-09 11:20:22 -03:00
Roberto Ierusalimschy
3d5187f6e5 require' uses its private reference to _LOADED' table 2004-07-02 15:09:11 -03:00
Roberto Ierusalimschy
80ec81926c `lua.c' also needs the default path, so auxlib should provide it 2004-07-01 11:26:28 -03:00
Roberto Ierusalimschy
96917ff42a "step" option in lua_gc also need to lock Lua. 2004-06-30 11:15:23 -03:00
Roberto Ierusalimschy
a6179adf12 detail 2004-06-30 09:58:44 -03:00
Roberto Ierusalimschy
02a2c01ccd new way to code RK values 2004-06-29 15:49:02 -03:00
Roberto Ierusalimschy
23e08a68f5 detail 2004-06-29 14:05:00 -03:00
Roberto Ierusalimschy
0f5a497ed9 new interface for search-path function + small changes in require 2004-06-29 13:58:17 -03:00
Roberto Ierusalimschy
753625c3f3 new interface for search-path function 2004-06-29 13:57:56 -03:00
Roberto Ierusalimschy
42b74ccf1d libraries may want to use `lua_assert' too... 2004-06-23 12:57:29 -03:00
Roberto Ierusalimschy
0c49857c1a new scheme to search paths 2004-06-21 17:05:29 -03:00
Roberto Ierusalimschy
6b41e84da5 `assert' returns all its parameters (not only the first) 2004-06-21 13:45:09 -03:00
Roberto Ierusalimschy
359840c2f8 new coroutines inherit hook from creator 2004-06-17 11:25:31 -03:00
Roberto Ierusalimschy
dba17070ac optional error for accesss to undefined variables/fields 2004-06-17 11:06:52 -03:00
Roberto Ierusalimschy
569eefbf73 detail 2004-06-16 17:22:43 -03:00
Roberto Ierusalimschy
5e4ea9a831 `setn' returns its "self" (the table) 2004-06-15 10:37:21 -03:00
Roberto Ierusalimschy
6311e3109f `setfenv' returns "self" 2004-06-15 10:31:30 -03:00
Roberto Ierusalimschy
9b854e6dbc BUG: string concatenation may cause arithmetic overflow, leading
to a buffer overflow.
2004-06-08 13:23:58 -03:00
Roberto Ierusalimschy
2b2d8ecd7a details 2004-06-08 11:31:15 -03:00
Roberto Ierusalimschy
75057dfced 2004-06-08 11:31:00 -03:00
Roberto Ierusalimschy
345379b5ff option for garbage-collector `step' 2004-06-04 12:30:53 -03:00
Roberto Ierusalimschy
118e471fa0 details 2004-06-02 16:09:36 -03:00
Roberto Ierusalimschy
ba9878fcb8 lock stuff defined in `luaconf.h' 2004-06-02 16:09:21 -03:00
Roberto Ierusalimschy
fa38421cea `testC' can operate on other states 2004-06-02 16:08:52 -03:00
Roberto Ierusalimschy
e8d4fe7236 new macro lua_threadyield' + lock stuff in luaconf.h' + details 2004-06-02 16:07:55 -03:00
Roberto Ierusalimschy
b8691f13a8 `getn' uses binary search if it has to count elements 2004-06-02 16:06:14 -03:00
Roberto Ierusalimschy
f4718544de what is provided by lauxlib.c should be defined at lauxlib.h 2004-06-02 14:37:03 -03:00
Roberto Ierusalimschy
50f9cd201e no more `__fenv' 2004-06-02 11:20:08 -03:00
Roberto Ierusalimschy
9d8426bab4 better error messages for `loadfile' 2004-06-02 10:50:46 -03:00
Roberto Ierusalimschy
557f0009c4 clear definition for `lua_number2int' 2004-06-02 10:24:43 -03:00
Roberto Ierusalimschy
0dfd04eb60 lua_strlen' upgraded to lua_objsize' (which also works with userdata) 2004-05-31 16:41:52 -03:00
Roberto Ierusalimschy
1e0aaf2156 luaL_dofile' and luaL_dostring' are deprecated 2004-05-31 16:27:14 -03:00
Roberto Ierusalimschy
616438fe9a new way to use vararg' parameters (with ...') 2004-05-31 15:51:50 -03:00
Roberto Ierusalimschy
47eda6ebd8 main must return status from original main! 2004-05-31 15:50:48 -03:00
Roberto Ierusalimschy
0f49b3e62d new function `select' 2004-05-31 15:50:30 -03:00
Roberto Ierusalimschy
0733c83b8c other modules may need FILEHANDLE definition 2004-05-28 15:35:05 -03:00
Roberto Ierusalimschy
e9844a4f1d `popen' is not ANSI and therefore was removed from the basic library 2004-05-28 15:32:51 -03:00
Roberto Ierusalimschy
c61bb89dba details 2004-05-17 09:34:00 -03:00
Roberto Ierusalimschy
0bda88e6cd small steps towards yields in iterators and tag methods 2004-05-14 16:25:09 -03:00
Roberto Ierusalimschy
7966a4acae avoid name clashes among different files 2004-05-11 13:52:08 -03:00
Roberto Ierusalimschy
37cd986532 in time', uses default if isdst' is absent 2004-05-10 17:26:37 -03:00
Roberto Ierusalimschy
a17dd24b34 no more USE_DEGREES option 2004-05-10 15:11:32 -03:00
Roberto Ierusalimschy
b072e4ea0b tinsert' and tremove' also use LUA_FIRSTINDEX 2004-05-10 15:06:14 -03:00
Roberto Ierusalimschy
7e41612eb2 code parameterized by LUA_FIRSTINDEX (first index of an array) 2004-05-10 14:50:51 -03:00
Roberto Ierusalimschy
b0f341ee52 LUAL_BUFFERSIZE is used in `lauxlib.h' and so everybody may need it 2004-05-10 10:58:26 -03:00
Roberto Ierusalimschy
1c459b881f accept `\r' as newline when looking for line end 2004-05-03 09:30:41 -03:00
Roberto Ierusalimschy
9629508a98 configuration file for Lua project 2004-05-03 09:28:43 -03:00
Roberto Ierusalimschy
763b8fba1b more stuff goes to configuration file 2004-05-03 09:28:43 -03:00
Roberto Ierusalimschy
b4cd38ba6c new scheme for configuration through `luaconf.h' 2004-04-30 17:13:38 -03:00
Roberto Ierusalimschy
079facab40 ensures own top is corrected after calling function with multiple results 2004-04-05 11:43:17 -03:00
Roberto Ierusalimschy
4c5d7b2ddd small optimization for {f()} 2004-03-26 11:02:41 -03:00
Roberto Ierusalimschy
d7cb622866 `unpack' has two optional arguments (to give a range) 2004-03-26 10:25:17 -03:00
Roberto Ierusalimschy
26a9b249db details 2004-03-24 12:46:49 -03:00
Roberto Ierusalimschy
227bddafe8 new copyright year 2004-03-24 10:55:46 -03:00
Roberto Ierusalimschy
5008e3d7d1 new states must use controlled malloc, too 2004-03-23 14:07:53 -03:00
Roberto Ierusalimschy
21bc05c920 write barrier for C upvalues 2004-03-23 14:07:34 -03:00
Roberto Ierusalimschy
29a13b4128 detail 2004-03-23 13:38:43 -03:00
Roberto Ierusalimschy
ef8c0d7d90 better message for errors with upvalues 2004-03-23 10:10:16 -03:00
Roberto Ierusalimschy
178246062c reuse `sweeplist' for all lists 2004-03-23 09:57:12 -03:00
Roberto Ierusalimschy
24f2d1183c detail 2004-03-16 09:31:40 -03:00
Roberto Ierusalimschy
8e1f25e3f8 bug in `dofile' 2004-03-15 18:09:55 -03:00
Roberto Ierusalimschy
48a8d78102 new tests to check memory consistency (for incremental GC) 2004-03-15 18:04:54 -03:00
Roberto Ierusalimschy
a4e1230f95 better way to control open upvalues 2004-03-15 18:04:33 -03:00
Roberto Ierusalimschy
9804467eeb detail 2004-03-13 10:32:09 -03:00
Roberto Ierusalimschy
a003e89125 better error messages for some limits 2004-03-12 16:53:56 -03:00
Roberto Ierusalimschy
b876ec61c0 new (temporary?) API for garbage collector 2004-03-09 14:34:35 -03:00
Roberto Ierusalimschy
898e8a6794 added include to stdarg.h (as it uses vararg facilities) 2004-02-20 13:01:05 -03:00
Roberto Ierusalimschy
1edea34666 details 2004-02-18 10:40:03 -03:00
Roberto Ierusalimschy
2aaf7394ad more and better tools (assertions & inspectors) to check incremental GC 2004-02-16 16:09:52 -03:00
Roberto Ierusalimschy
b3ce450529 avoid calling `memcmp' with a NULL argument 2004-01-15 10:40:26 -02:00
Roberto Ierusalimschy
24434b59f7 '%' must be '%%' to avoid formatting problems 2004-01-02 09:54:14 -02:00
Roberto Ierusalimschy
beb2aa5a46 atomic operations are not GC "states" 2003-12-12 16:29:34 -02:00
Roberto Ierusalimschy
47fc57a252 TObject' renamed to TValue' + other name changes and better assertions
for incremental garbage collection
2003-12-10 10:13:36 -02:00
Roberto Ierusalimschy
4d5fe1f54b detail 2003-12-10 09:04:54 -02:00
Roberto Ierusalimschy
df429f163a First version of incremental GC 2003-12-09 14:56:11 -02:00
Roberto Ierusalimschy
fe595a45c2 `grayagain' list 2003-12-04 16:52:23 -02:00
Roberto Ierusalimschy
9db1942bac sweep of strings also incremental 2003-12-04 15:22:42 -02:00
Roberto Ierusalimschy
c6eac44a94 two different white flags (to distinguish dead elements from new ones) 2003-12-03 18:03:07 -02:00
Roberto Ierusalimschy
8878554b85 single list for all collectible objects, with udata separated at the
end of the list
2003-12-03 10:30:41 -02:00
Roberto Ierusalimschy
af850484a9 default metatable can be NULL 2003-12-01 16:22:56 -02:00
Roberto Ierusalimschy
1d10acb355 incremental GC phases 2003-12-01 14:33:30 -02:00
Roberto Ierusalimschy
da61624756 avoid overflow when doubling size 2003-11-27 16:18:37 -02:00
Roberto Ierusalimschy
8b97b072cd details 2003-11-27 16:05:14 -02:00
Roberto Ierusalimschy
5ee63257f9 macros for closure sizes are global 2003-11-24 16:50:36 -02:00
Roberto Ierusalimschy
8bc6c68021 details 2003-11-19 17:59:18 -02:00
Roberto Ierusalimschy
57b6ed6815 initial implementation of white/gray/black coloring 2003-11-19 17:41:57 -02:00
Roberto Ierusalimschy
9b9cdfee8b gclist for upvalues must be available even when upvalue is still open 2003-11-19 17:41:30 -02:00
Roberto Ierusalimschy
366e4af3c9 towards incremental GC 2003-11-18 12:55:11 -02:00
Roberto Ierusalimschy
53c7f86194 details 2003-11-18 08:44:53 -02:00
Roberto Ierusalimschy
ab7d9bfd0c cleaner code for manipulation of `marked' field 2003-11-17 17:50:05 -02:00
Roberto Ierusalimschy
921b1723e2 comments 2003-11-11 14:34:17 -02:00
Roberto Ierusalimschy
fa198197a0 lua_(set)getglobal are ok to use 2003-11-05 09:59:14 -02:00
Roberto Ierusalimschy
1e944de6cb towards a "stackless" call of metamethods (?) 2003-10-27 17:14:31 -02:00
Roberto Ierusalimschy
275c150b17 error()' (and error(nil)') generates errors with no error messages 2003-10-23 16:06:22 -02:00
Roberto Ierusalimschy
d6d896b953 lua_set(get)global may use lua_set(get)field 2003-10-21 08:58:58 -02:00
Roberto Ierusalimschy
07201066bd core does not look for function name in globals (too particular) 2003-10-20 16:42:28 -02:00
Roberto Ierusalimschy
97b838d9ab new semantics for setn/getn (no more changes to `n') 2003-10-20 16:32:55 -02:00
Roberto Ierusalimschy
c51bcf4796 it's ok to dump functions with upvalues 2003-10-20 15:42:41 -02:00
Roberto Ierusalimschy
03bab90303 new function `lua_getallocf' to retrieve allocation function and data 2003-10-20 10:25:23 -02:00
Roberto Ierusalimschy
8502331f69 `luaX_errorline' was used only in one place 2003-10-20 10:24:34 -02:00
Roberto Ierusalimschy
9914e1bcdd detail 2003-10-20 10:24:26 -02:00
Roberto Ierusalimschy
10de467c79 new function `lua_createtable' 2003-10-10 10:29:28 -03:00
Roberto Ierusalimschy
533737f26e new functions lua_getfield' and lua_setfield' 2003-10-10 09:57:55 -03:00
Roberto Ierusalimschy
a41d60e1d1 debugger can only see `local function' after it has a meaningful value 2003-10-09 14:56:23 -03:00
Roberto Ierusalimschy
f04fe526cd new functions `lua_tointeger' and lua_pushinteger' 2003-10-07 17:13:41 -03:00
Roberto Ierusalimschy
21947deddc new bug + correction in path for coroutine bug 2003-10-07 09:34:21 -03:00
Roberto Ierusalimschy
3087636c76 detail 2003-10-03 13:07:44 -03:00
Roberto Ierusalimschy
7b8504840f buffer should better use `size_t' for its size 2003-10-03 13:05:34 -03:00
Roberto Ierusalimschy
3a508b8bd7 avoid the use of `strlen' (strings are literals) 2003-10-03 13:04:24 -03:00
Roberto Ierusalimschy
6becdb3e70 details 2003-10-03 13:04:11 -03:00
Roberto Ierusalimschy
b97fb932ec Lua kernel does not use malloc/free functions. 2003-10-02 17:31:17 -03:00
Roberto Ierusalimschy
c7cf92e6f3 avoid unecessary includes of `stdlib' 2003-10-02 16:21:09 -03:00
Roberto Ierusalimschy
a62d39aa1c detail: `luaL_where' does not use the name information 2003-10-01 13:50:53 -03:00
Roberto Ierusalimschy
5d4bf35ec9 bug: syntax `local function' does not increment stack size 2003-09-29 13:41:35 -03:00
Roberto Ierusalimschy
6063c5c61f bug: cannot invalidate a running coroutine 2003-09-05 11:30:59 -03:00
Roberto Ierusalimschy
2a70107581 detail 2003-09-05 11:00:27 -03:00
Roberto Ierusalimschy
7dae7899b1 main thread and global state are allocated in a single block 2003-09-04 17:19:07 -03:00
Roberto Ierusalimschy
30e51f09b9 some changes in error reporting 2003-09-04 17:00:28 -03:00
Roberto Ierusalimschy
994a37c8e8 IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
up to 60 characters in a `printf'. That causes a buffer overflow in
`tostring'..
2003-08-29 13:50:02 -03:00
Roberto Ierusalimschy
0ff1596476 new form of long strings: `[***[...]***]' 2003-08-29 13:48:14 -03:00
Roberto Ierusalimschy
b27664e0db simpler manipulation of buffer count in scanner 2003-08-28 11:38:46 -03:00
Roberto Ierusalimschy
beb896b082 new function (generic) `load' 2003-08-27 18:02:08 -03:00
Roberto Ierusalimschy
8332d5c8a5 parser fully reentrant(!) 2003-08-27 18:01:44 -03:00
Roberto Ierusalimschy
885961be1d reader runs outside core Lua 2003-08-27 17:57:52 -03:00
Roberto Ierusalimschy
b114142799 new auxiliary function `luaH_setstr' 2003-08-26 09:04:13 -03:00
Roberto Ierusalimschy
4b2e71ddb6 ZIO passes Lua state to chunk reader 2003-08-25 17:00:50 -03:00
Roberto Ierusalimschy
9fcc485176 zio does not keep "source" name (nobody uses it) 2003-08-25 16:51:54 -03:00
Roberto Ierusalimschy
64066359dd bug: IBM AS400 (OS400) has sizeof(void *)==16, and a `%p' may generate
up to 60 characters in a `printf'. That causes a buffer overflow in
`tostring'..
2003-08-25 16:49:47 -03:00
Roberto Ierusalimschy
97af24ea32 newlines can be \n', \r', \r\n', or \n\r' 2003-08-21 11:16:43 -03:00
Roberto Ierusalimschy
433cb1d13a no more checks for non-default compilation options + luaU_dump has
new option to strip debug info
2003-08-15 10:48:53 -03:00
Roberto Ierusalimschy
d66198719d several bugs for Lua 5.0 + new format for bug entries 2003-07-29 16:27:46 -03:00
Roberto Ierusalimschy
91bf77534c no need for a maximum number of parameters (maximum number of locals
take care of that).
2003-07-29 16:26:34 -03:00
Roberto Ierusalimschy
a0a384a6b1 bug: userdata to be collected still counts into new GC threshold,
increasing memory consumption
2003-07-29 16:25:37 -03:00
Roberto Ierusalimschy
e89945aaa1 syntax ...=var' changed to var=...' 2003-07-29 15:51:00 -03:00
Roberto Ierusalimschy
d407d3fe0e details 2003-07-28 15:31:20 -03:00
Roberto Ierusalimschy
522407e23a we do not need a default panic (that does nothing anyway...) 2003-07-16 17:51:47 -03:00
Roberto Ierusalimschy
fa26d294ae new way to control `pc' of running functions 2003-07-16 17:49:02 -03:00
Roberto Ierusalimschy
5a761e3a15 opcode number may be invalid 2003-07-10 08:59:06 -03:00
Roberto Ierusalimschy
265530478b more changes to reduce stack usage by the parser 2003-07-09 17:11:30 -03:00
Roberto Ierusalimschy
00180bb133 small changes to reduce stack usage by the parser 2003-07-09 12:36:38 -03:00
Roberto Ierusalimschy
66ed154c89 details 2003-07-09 09:08:43 -03:00
Roberto Ierusalimschy
f52f357a55 correct handling when a thread turns on line hooks in another thread 2003-07-07 10:37:56 -03:00
Roberto Ierusalimschy
79fee99024 `debug' library can operate over other threads 2003-07-07 10:37:08 -03:00
Roberto Ierusalimschy
a73ded2153 Move nothing when there is nothing to move 2003-07-07 10:34:25 -03:00
Roberto Ierusalimschy
0ec4c473df bug: file:close cannot be called without a file. 2003-07-07 10:32:52 -03:00
Roberto Ierusalimschy
9e05503ffa bug: C functions also may have stacks larger than current top 2003-07-07 10:32:19 -03:00
Roberto Ierusalimschy
17f695157c define a `lua_isthread' for completeness 2003-07-07 10:30:57 -03:00
Roberto Ierusalimschy
b93f67f2ce detail 2003-06-10 09:36:26 -03:00
Roberto Ierusalimschy
60aa01d8f7 fully-weak tables are more efficient 2003-05-16 15:59:08 -03:00
Roberto Ierusalimschy
ecf5730c0c (much) smarter way to clear weak tables 2003-05-16 15:58:39 -03:00
Roberto Ierusalimschy
b10bfd4934 comments 2003-05-15 16:46:03 -03:00
Roberto Ierusalimschy
176cd7d1a3 `#!' is detected by loadfile, not by the lexer 2003-05-15 09:20:24 -03:00
Roberto Ierusalimschy
859c7f7ce0 LUA_SIGNATURE is public 2003-05-15 09:20:04 -03:00
Roberto Ierusalimschy
56c5e749cc no more compatibility code (`lua_pushupvalues') 2003-05-14 18:10:07 -03:00
Roberto Ierusalimschy
9ec9a012e7 details 2003-05-14 18:09:53 -03:00
Roberto Ierusalimschy
dae99205cf no more compatibility code 2003-05-14 18:06:56 -03:00
Roberto Ierusalimschy
9eb0f25a29 no more compatibility code for 4.0 2003-05-14 18:02:39 -03:00
Roberto Ierusalimschy
f93051155c ok to use #elif' and #if defined()' 2003-05-14 18:01:53 -03:00
Roberto Ierusalimschy
524ae9fc3d new function `setvbuf' 2003-05-14 16:03:43 -03:00
Roberto Ierusalimschy
0ddedaee92 new function `string.reverse' 2003-05-14 11:35:54 -03:00
Roberto Ierusalimschy
5cc448386a new syntax: `... [= name]' 2003-05-14 09:32:46 -03:00
Roberto Ierusalimschy
c116dcb92b better information about instruction behavior (use of arguments) 2003-05-14 09:09:12 -03:00
Roberto Ierusalimschy
6d268b0b00 new semantics for "for" local variables 2003-05-13 17:15:59 -03:00
Roberto Ierusalimschy
c767747191 new (internal) macros for error handling 2003-05-13 16:22:19 -03:00
Roberto Ierusalimschy
f966404ed6 simpler implementation for valid/acceptable indices 2003-05-09 17:16:54 -03:00
Roberto Ierusalimschy
ee07ad346d `getn' doesn't need this field (values cannot be nil) 2003-05-07 13:02:16 -03:00
Roberto Ierusalimschy
fee9e473f2 inlining of `luaV_gettable' were too complex (dirty) 2003-05-05 15:39:57 -03:00
Roberto Ierusalimschy
82dfacbcf7 detail 2003-04-30 17:24:38 -03:00
Roberto Ierusalimschy
26097b6c4b uses integers as keys to standard i/o files 2003-04-30 17:15:55 -03:00
Roberto Ierusalimschy
f1f8f0ca22 simpler way to check maximum gc threshold 2003-04-28 16:58:06 -03:00
Roberto Ierusalimschy
bcc5f1406b test function for lua_setgcthreshold 2003-04-28 16:58:06 -03:00
Roberto Ierusalimschy
b1b752fb2b comments 2003-04-28 16:57:50 -03:00
Roberto Ierusalimschy
572a69df78 Lua does not need all those different types... 2003-04-28 16:26:16 -03:00
Roberto Ierusalimschy
943c82b376 avoid unnecessary call to log2 on too large indices 2003-04-28 10:31:46 -03:00
Roberto Ierusalimschy
17149b7d43 avoid warnings (Instruction' may not fit into an int') 2003-04-28 10:31:06 -03:00
Roberto Ierusalimschy
01b303c87e simpler log2 implementation 2003-04-28 10:30:14 -03:00
Roberto Ierusalimschy
762c737037 last changes by lhf 2003-04-10 14:39:41 -03:00
Roberto Ierusalimschy
de57dc2653 new scheme to control `loadlib' configuration (default for dlopen
implementation is not to include it)
2003-04-07 17:11:53 -03:00
Roberto Ierusalimschy
d1df829f8d lua_getmetatable must accept any acceptable index 2003-04-07 11:36:08 -03:00
Roberto Ierusalimschy
2ad947fe03 new test options for luaL_getn/setn 2003-04-07 11:35:00 -03:00
Roberto Ierusalimschy
f0cc013afa luaL_getn/setn must operate correctly over negative indices 2003-04-07 11:35:00 -03:00
Roberto Ierusalimschy
0d88545b82 warnings from several compilers (mainly typecasts when lua_Number is float) 2003-04-03 10:35:34 -03:00
Roberto Ierusalimschy
f84c5a5fc6 avoid conflicts in (re)definition of `isatty' 2003-04-03 10:34:42 -03:00
Roberto Ierusalimschy
05d35d8f3c comments 2003-04-02 10:09:14 -03:00
Roberto Ierusalimschy
3a6230ef7c error-message format 2003-04-01 14:52:31 -03:00
Roberto Ierusalimschy
a424a112b5 clearance of debuging code (left by mistake) 2003-03-31 10:00:25 -03:00
Roberto Ierusalimschy
b858161fbc new hash method for lua_Number (double) (due to a performance problem) 2003-03-24 11:18:42 -03:00
Roberto Ierusalimschy
80bac182db do not mix --help' with --' 2003-03-24 09:40:01 -03:00
Roberto Ierusalimschy
30a411ab3c chars from zio are always unsigned 2003-03-24 09:39:34 -03:00
Roberto Ierusalimschy
5bb5a1831d details 2003-03-20 17:26:33 -03:00
Roberto Ierusalimschy
b518d14071 bug: zio mixes a 255 as first char in a buffer with EOZ 2003-03-20 13:00:56 -03:00
Roberto Ierusalimschy
15dbb53461 towards 5.0 final 2003-03-19 18:27:30 -03:00
Roberto Ierusalimschy
abc304f9da avoid name colision (for alllua.c) 2003-03-19 18:24:04 -03:00
Roberto Ierusalimschy
1a553f9199 better error messages 2003-03-19 18:16:12 -03:00
Roberto Ierusalimschy
0ca225d33a better error message 2003-03-19 18:15:18 -03:00
Roberto Ierusalimschy
70e2b7ab86 name changes to avoid name collision between macros and variables 2003-03-19 18:14:53 -03:00
Roberto Ierusalimschy
5a144e891a __globals' -> __fenv' 2003-03-19 18:14:34 -03:00
Roberto Ierusalimschy
b12776f29c `luaL_getmetafield' was leaving extra value on the stack 2003-03-18 15:48:31 -03:00
Roberto Ierusalimschy
ab9e062928 name changes to avoid name collision between macros and variables 2003-03-18 09:50:04 -03:00
Roberto Ierusalimschy
81cdbabf09 detail (change place of a prototype) 2003-03-18 09:31:39 -03:00
Roberto Ierusalimschy
40cfb0691e new auxiliary functions for `type' manipulation 2003-03-18 09:25:32 -03:00
Roberto Ierusalimschy
9b7af7e45b tests for Windows version 2003-03-18 09:25:01 -03:00
Roberto Ierusalimschy
2e66248f8a unused argument 2003-03-18 09:24:38 -03:00
Roberto Ierusalimschy
79db75101e detail 2003-03-18 09:24:26 -03:00
Roberto Ierusalimschy
b0c40e2405 first version of `loadlib' 2003-03-17 10:04:58 -03:00
Roberto Ierusalimschy
4734e2de05 `loadlib' now an official library 2003-03-17 10:01:48 -03:00
Roberto Ierusalimschy
7ea180af6e detail 2003-03-14 16:08:11 -03:00
Roberto Ierusalimschy
05d567d52e io.input'/io.output' always return current file 2003-03-14 16:00:16 -03:00
Roberto Ierusalimschy
d8a3a00d84 `string.find' also accepts out-of-range indices 2003-03-14 15:59:53 -03:00
Roberto Ierusalimschy
c9ea94ec92 out-of-bound upvalues (in C) are acceptable indices 2003-03-14 15:59:21 -03:00
Roberto Ierusalimschy
fa4b4c1100 loadstring/loadfile use global environment + setfenv(0) changes
global environment
2003-03-11 15:17:43 -03:00
Roberto Ierusalimschy
4039bf457d ^ operator is defined by global `__pow' 2003-03-11 09:30:37 -03:00
Roberto Ierusalimschy
034de1fe73 new names for functions that open C libraries 2003-03-11 09:24:34 -03:00
Roberto Ierusalimschy
430d6db928 LUA_PATH components may have multiple interrogation marks 2003-03-11 09:08:13 -03:00
Roberto Ierusalimschy
7c3857cded comments 2003-03-07 10:21:31 -03:00
Roberto Ierusalimschy
8ce6f0b418 avoid including system headers after program headers 2003-03-06 16:37:42 -03:00
Roberto Ierusalimschy
572bddc0b0 LUA_USETMPNAME -> USE_TMPNAME 2003-03-06 16:36:44 -03:00
Roberto Ierusalimschy
3684f67771 details (text of an error message) 2003-03-06 16:36:16 -03:00
Roberto Ierusalimschy
69dd9461e5 bug: GC metamethod calls could mess C/Lua stack syncronization 2003-02-28 16:45:15 -03:00
Roberto Ierusalimschy
6b6bc532a4 better error message for (deprecated) "%global" 2003-02-28 14:19:47 -03:00
Roberto Ierusalimschy
ea16ee41a8 no more attempt to optimize GC when parsing new modules (too complex) 2003-02-28 12:42:08 -03:00
Roberto Ierusalimschy
60d11ec316 by default, gcc does not get tmpname 2003-02-27 09:39:05 -03:00
Roberto Ierusalimschy
e1a424e8a3 avoid the identifier index' (clashes with BSD index' function) 2003-02-27 09:33:07 -03:00
Roberto Ierusalimschy
59ce42dbd5 detail 2003-02-27 09:32:30 -03:00
Roberto Ierusalimschy
92f6e0c1bf no-nonsense debug information about tail calls 2003-02-27 08:52:30 -03:00
Roberto Ierusalimschy
5cd99b82b7 set/getenvtable' -> set/getfenv' 2003-02-24 13:54:20 -03:00
Roberto Ierusalimschy
07e210e655 `require' returns value returned by package 2003-02-24 13:50:41 -03:00
Roberto Ierusalimschy
feb724c122 ULONG_MAX>>10 may not fit into an int (old bug) 2003-02-21 16:00:14 -03:00
Roberto Ierusalimschy
67f9a2a98f details 2003-02-20 17:12:39 -03:00
Roberto Ierusalimschy
c4f9c887fc expressions too complex for an ARM compiler... 2003-02-19 07:28:58 -03:00
Roberto Ierusalimschy
9866fb0ef1 set/getglobals' -> set/getenvtable' 2003-02-18 13:13:15 -03:00
Roberto Ierusalimschy
60c83ded30 small optimization for sizes of array constructors 2003-02-18 13:02:56 -03:00
Roberto Ierusalimschy
07948c3181 restore _REQUIREDNAME after requiring a file 2003-02-18 13:02:13 -03:00
Roberto Ierusalimschy
dce9a49a08 final version 2003-02-18 13:01:57 -03:00
Roberto Ierusalimschy
15db58a2f5 create arg table with correct size 2003-02-13 14:08:47 -02:00
Roberto Ierusalimschy
d6826dbc80 simpler way to count uses 2003-02-13 14:08:32 -02:00
Roberto Ierusalimschy
e75a6ae9ee `defaultmeta' is always empty, but registry needs some space for
names and numbers (references)
2003-02-13 14:07:57 -02:00
Roberto Ierusalimschy
2866fb2dd0 reset _REQUIREDNAME after loading module 2003-02-13 14:07:37 -02:00
Roberto Ierusalimschy
4b6f436d67 unpack' uses getn' to get table size 2003-02-12 07:11:01 -02:00
Roberto Ierusalimschy
8f105d6b59 string.byte returns nil if index is out-of-range 2003-02-12 07:10:41 -02:00
Roberto Ierusalimschy
2fef8c772b auxiliary function to check userdata with types 2003-02-11 13:32:31 -02:00
Roberto Ierusalimschy
7285fa393b use C names for C types 2003-02-11 13:31:50 -02:00
Roberto Ierusalimschy
5085f09ce5 small optimizations 2003-02-11 13:24:52 -02:00
Roberto Ierusalimschy
d674626392 compatibility with '%' syntax is optional 2003-02-11 08:49:53 -02:00
Roberto Ierusalimschy
7a40cdbda0 different variables for number of upvalues and size of upvalue array
(makes code clearer)
2003-02-11 08:46:24 -02:00
Roberto Ierusalimschy
3cdeacbbfb reference system also uses getn/setn (plus small corrections) 2003-02-11 07:44:38 -02:00
Roberto Ierusalimschy
6f207b15fb resist errors in finalizers during lua_close 2003-02-10 15:32:50 -02:00
Roberto Ierusalimschy
3184314bf3 warning 2003-02-10 15:31:13 -02:00
Roberto Ierusalimschy
7964f7cbbd more complete information for coroutine errors 2003-02-10 08:21:31 -02:00
Roberto Ierusalimschy
383a6e88f9 argv[0] may be NULL 2003-01-29 11:23:45 -02:00
Roberto Ierusalimschy
871166d7db test for panic function 2003-01-29 08:27:53 -02:00
Roberto Ierusalimschy
592cf2334e "panic" cannot happen in lua.c, with lua_cpcall +
argv[0] may be empty
2003-01-29 08:27:07 -02:00
Roberto Ierusalimschy
0175f8d5d1 dump/undump of upvalue names 2003-01-27 13:52:57 -02:00
Roberto Ierusalimschy
e79bf02f33 correct semantics for comparison metamethods (they are only valid
when both operands have the same metamethod).
2003-01-27 13:12:52 -02:00
Roberto Ierusalimschy
41ed3c4771 getn/setn in C moved to lauxlib 2003-01-27 11:46:16 -02:00
Roberto Ierusalimschy
635b7c707d details 2003-01-27 11:00:43 -02:00
Roberto Ierusalimschy
83f0d6ef1a DEPRECATED (new manual uses an independent format instead of LaTeX) 2003-01-24 14:38:18 -02:00
Roberto Ierusalimschy
3088ebd95b last changes before leaving Latex 2003-01-24 07:14:54 -02:00
Roberto Ierusalimschy
797d964df9 detail 2003-01-23 09:34:18 -02:00
Roberto Ierusalimschy
e44e579dc1 bug: luaD_protectedparser must protect its garbage collection too 2003-01-23 09:31:38 -02:00
Roberto Ierusalimschy
a153cafd8d starting translation to new format (@comand{...}). 2003-01-22 14:29:38 -02:00
Roberto Ierusalimschy
3b5158f2a1 corrections from Asko Kauppi 2003-01-21 15:45:11 -02:00
Roberto Ierusalimschy
60a8b94fd0 corrections/suggestions by Ed Ferguson 2003-01-20 09:03:05 -02:00
Roberto Ierusalimschy
c499442e5f compatibility macros must be available by default 2003-01-17 13:28:09 -02:00
Roberto Ierusalimschy
9a5bab82ff use the more modern _POSIX_C_SOURCE instead of older _POSIX_SOURCE 2003-01-17 13:27:28 -02:00
Roberto Ierusalimschy
32fd039bb5 `openlib' functions return new module 2002-12-20 08:26:33 -02:00
Roberto Ierusalimschy
75f73172c4 bug: `resume' was checking the wrong value for stack overflow 2002-12-20 07:55:56 -02:00
Roberto Ierusalimschy
754c630754 details 2002-12-19 11:21:08 -02:00
Roberto Ierusalimschy
dd8edecae1 new functions to manipulate upvales (get/setupvalue) 2002-12-19 09:11:55 -02:00
Roberto Ierusalimschy
28021c5c66 better explanation (+ example) for coroutines 2002-12-11 11:43:15 -02:00
Roberto Ierusalimschy
73517e86b0 OP_TFORLOOP uses extra stack space 2002-12-11 10:34:22 -02:00
Roberto Ierusalimschy
9e8face8d8 must move call results in the last iteration, too 2002-12-11 10:34:22 -02:00
Roberto Ierusalimschy
64864f094b new options for debugging Lua (HARDSTACKTESTS & EXTERNMEMCHECK) 2002-12-06 15:20:45 -02:00
Roberto Ierusalimschy
9bd3fc1039 TFORLOOP makes a call that affects all values above it on the stack 2002-12-06 15:15:35 -02:00
Roberto Ierusalimschy
cc4a22ebe2 bug: scope of generic for variables is not sound 2002-12-06 15:09:00 -02:00
Roberto Ierusalimschy
acf62ddfbe "load*" creates chunk with same global table than caller 2002-12-06 15:05:15 -02:00
Roberto Ierusalimschy
04f95ce879 hook counts are integers now 2002-12-05 15:50:10 -02:00
Roberto Ierusalimschy
27c6b4d422 each .c file defines its own name 2002-12-04 15:38:31 -02:00
Roberto Ierusalimschy
0bb8eb5151 new function `lua_cpcall' 2002-12-04 15:29:32 -02:00
Roberto Ierusalimschy
38da8c0d7d new facilities to test memory overflow in main.c 2002-12-04 15:29:05 -02:00
Roberto Ierusalimschy
76de732745 avoid non-raw accesses to globals when variable may not exist 2002-12-04 13:38:25 -02:00
Roberto Ierusalimschy
90d7892007 new function `io.type' 2002-12-04 13:27:17 -02:00
Roberto Ierusalimschy
041cb96992 small bug: `write' must return three values in case of errors 2002-12-04 13:17:36 -02:00
Roberto Ierusalimschy
c75c3cfd19 avoid names `str...' (may conflict with string.h) 2002-12-02 10:06:10 -02:00
Roberto Ierusalimschy
24471525d7 details 2002-12-02 10:06:10 -02:00
Roberto Ierusalimschy
1f55dbc699 details 2002-11-26 10:53:29 -02:00
Roberto Ierusalimschy
c194a46bc5 detail 2002-11-26 06:59:48 -02:00
Roberto Ierusalimschy
8954bdc706 new `coroutine.status' function 2002-11-26 06:45:36 -02:00
Roberto Ierusalimschy
5a228bb1d8 new function `lua_version' 2002-11-25 15:50:14 -02:00
Roberto Ierusalimschy
5f698f8b6f simpler interface to hooks + use of `int' to count hooks 2002-11-25 15:47:13 -02:00
Roberto Ierusalimschy
9b1c586b2f renaming stringdump' -> string.dump' 2002-11-25 15:33:33 -02:00
Roberto Ierusalimschy
d9340154ac `__tostring' for files + small bug (could do invalid read inside
a userdata when it was not a file)
2002-11-25 13:05:39 -02:00
Roberto Ierusalimschy
e47baca75a warnings from Visual C++ 2002-11-25 10:38:47 -02:00
Roberto Ierusalimschy
b8a680c114 resets hook count even in case of errors 2002-11-25 09:20:29 -02:00
Roberto Ierusalimschy
709b27b456 ULONG_MAX>>10 may not fit into an int 2002-11-25 09:16:48 -02:00
Roberto Ierusalimschy
dbc5451bea comments 2002-11-22 16:01:46 -02:00
Roberto Ierusalimschy
2d2d45976c separated control over C recursion level 2002-11-22 15:16:52 -02:00
Roberto Ierusalimschy
0050d983fc make more clear "primitive" recursive definitions 2002-11-22 14:42:53 -02:00
Roberto Ierusalimschy
04b143ddf9 avoid C stack overflow during parsing 2002-11-22 14:35:20 -02:00
Roberto Ierusalimschy
007f229568 detail 2002-11-22 11:59:04 -02:00
Roberto Ierusalimschy
84488c5670 small bug: previous call may change `base' 2002-11-21 15:19:42 -02:00
Roberto Ierusalimschy
5142e630bf new macro `condhardstacktests' to control hard stack tests 2002-11-21 15:19:11 -02:00
Roberto Ierusalimschy
010bbd9d9c simpler definition for incr_top 2002-11-21 14:46:16 -02:00
Roberto Ierusalimschy
be00cd2a6b easier way to keep `base' correct 2002-11-21 13:46:44 -02:00
Roberto Ierusalimschy
2e4e888de0 Lua functions must have a frame or a saved pc. 2002-11-21 13:46:20 -02:00
Roberto Ierusalimschy
ddc144e4d2 keep L->ci->base in L->base for faster access 2002-11-21 13:16:04 -02:00
Roberto Ierusalimschy
b48c6e7680 no problem keeping some dead meat while doing collection 2002-11-21 12:18:01 -02:00
Roberto Ierusalimschy
aff97fffc4 C functions cannot increase its top without filling the stack 2002-11-21 12:17:15 -02:00
Roberto Ierusalimschy
1648674653 must check GC every time it can create new objects 2002-11-21 12:16:52 -02:00
Roberto Ierusalimschy
d404f0c276 global_State must be deallocated (and so allocated) with NULL also
(otherwise it trys to decrement inside itself after its own free)
2002-11-21 12:14:42 -02:00
Roberto Ierusalimschy
48e42261ac details 2002-11-19 15:42:32 -02:00
Roberto Ierusalimschy
be762f38bd better organization of "malloc responsabilities" 2002-11-19 12:12:13 -02:00
Roberto Ierusalimschy
c8a79057f7 option -l does a require', instead of dofile' 2002-11-19 11:49:43 -02:00
Roberto Ierusalimschy
642af82e81 small bugs (state could keep its CI_HASFRAME attribute after returning) 2002-11-19 06:50:56 -02:00
Roberto Ierusalimschy
636c629e56 new assertions 2002-11-18 16:45:38 -02:00
Roberto Ierusalimschy
96ba5d0bc2 include file name in error messages 2002-11-18 14:53:19 -02:00
Roberto Ierusalimschy
f0185f7628 support for tests of yield inside hooks + better support for tests
with valgrind and other memory checkers
2002-11-18 13:24:27 -02:00
Roberto Ierusalimschy
9bab2cf55d support for yield inside hooks 2002-11-18 13:24:11 -02:00
Roberto Ierusalimschy
c4ae00a3d1 details 2002-11-18 13:23:43 -02:00
Roberto Ierusalimschy
f4d3bc52f4 towards 5.0 beta 2002-11-18 12:39:34 -02:00
Roberto Ierusalimschy
18765d900e messages 2002-11-18 09:20:01 -02:00
Roberto Ierusalimschy
43013b39cc new representation for hooks (to allow asynchronous calls to sethook) 2002-11-18 09:01:55 -02:00
Roberto Ierusalimschy
94912d99fc details 2002-11-14 14:59:16 -02:00
Roberto Ierusalimschy
b40c9f7a3c better code to signal write barriers 2002-11-14 14:16:21 -02:00
Roberto Ierusalimschy
41fd639cab documentation for write barriers 2002-11-14 14:15:53 -02:00
Roberto Ierusalimschy
a845a46cc8 C function may leave garbage on the stack (besides return values) 2002-11-14 13:42:05 -02:00
Roberto Ierusalimschy
097edd3884 better names for auxiliar functions 2002-11-14 13:41:38 -02:00
Roberto Ierusalimschy
5c5d9b2703 back to `__mode' metafield to specify weakness 2002-11-14 10:01:35 -02:00
Roberto Ierusalimschy
43d1a6af12 detail 2002-11-14 09:51:23 -02:00
Roberto Ierusalimschy
3010eb0536 all objects with several children (tables, closures, stacks, prototypes)
go to `gray' queue
2002-11-13 09:49:19 -02:00
Roberto Ierusalimschy
2f91f95d94 better control over GCObjects 2002-11-13 09:32:26 -02:00
Roberto Ierusalimschy
42dd080a2e details 2002-11-12 12:34:18 -02:00
Roberto Ierusalimschy
9957f7d598 better way to open libraries 2002-11-11 11:28:06 -02:00
Roberto Ierusalimschy
ac27b7a842 avoid traversing extra elements when cleaning weak tables 2002-11-11 09:52:43 -02:00
Roberto Ierusalimschy
81e142fc14 detail (`key' is always on stack) 2002-11-07 14:03:33 -02:00
Roberto Ierusalimschy
63633c5b5f better name for `lua_movethread' 2002-11-07 13:39:23 -02:00
Roberto Ierusalimschy
dff9be4224 new macros to distinguish different types of object moves (for future GC
evolution).
2002-11-07 13:37:10 -02:00
Roberto Ierusalimschy
118347d8c3 new API for coroutines 2002-11-06 17:08:00 -02:00
Roberto Ierusalimschy
6820da5096 detail 2002-11-04 10:31:44 -02:00
Roberto Ierusalimschy
c3eb4675b9 new module, ldump.c 2002-10-25 18:38:17 -03:00
Roberto Ierusalimschy
7e0f880bc5 C++ demands cast from void to specific types 2002-10-25 18:36:54 -03:00
Roberto Ierusalimschy
118e9cd843 new facility for dumping chunks 2002-10-25 18:31:28 -03:00
Roberto Ierusalimschy
de00d0d0ad module for dumping chunks 2002-10-25 18:31:28 -03:00
Roberto Ierusalimschy
1713b64065 Writer type must be public (so, in lua.h) 2002-10-25 18:30:49 -03:00
Roberto Ierusalimschy
671dc6eec2 new version (from lhf) 2002-10-25 18:30:41 -03:00
Roberto Ierusalimschy
e356a43dc0 C needs "union" (unlike C++) 2002-10-25 18:30:00 -03:00
Roberto Ierusalimschy
f36038e42a assertion must be always valid (not only in debug mode) 2002-10-25 18:29:20 -03:00
Roberto Ierusalimschy
96e15b8501 threads now are real Lua objects, subject to garbage collection 2002-10-25 17:05:28 -03:00
Roberto Ierusalimschy
0fd91b1b08 optional limits for table.concat 2002-10-23 16:08:23 -03:00
Roberto Ierusalimschy
a2b353e044 details 2002-10-23 16:08:13 -03:00
Roberto Ierusalimschy
92a2ef9dca field `__globals' protect global tables 2002-10-22 16:41:08 -03:00
Roberto Ierusalimschy
4fb9110a6e tests for compatibility functions lua_dostring/lua_dofile 2002-10-22 15:07:55 -03:00
Roberto Ierusalimschy
11886dc7b0 print error on stderr when _ALERT is not defined 2002-10-22 15:07:55 -03:00
Roberto Ierusalimschy
81bc5711a8 only one instance of registry and default metatable per global state 2002-10-22 14:58:14 -03:00
Roberto Ierusalimschy
6a77a6b73f avoid too much precision when printing numbers 2002-10-22 14:21:25 -03:00
Roberto Ierusalimschy
84e0b1bc97 small changes in type configuration facilities 2002-10-22 14:18:28 -03:00
Roberto Ierusalimschy
6823a2f57f better tokens for error messages 2002-10-22 13:45:52 -03:00
Roberto Ierusalimschy
313b2fe902 detail 2002-10-21 17:43:38 -03:00
Roberto Ierusalimschy
425e5813b0 free prototype in (more or less) the same order it is created by
`undump'
2002-10-21 17:41:46 -03:00
Roberto Ierusalimschy
6505503b49 do not pretend that file is closed when close fails 2002-10-21 17:41:24 -03:00
Roberto Ierusalimschy
ec748fcb0a correct handling of opened files in presence of memory allocation
errors
2002-10-16 17:41:35 -03:00
Roberto Ierusalimschy
c196348717 in case of memory allocation errors, sizecode and sizelineinfo can
be different
2002-10-16 17:40:58 -03:00
Roberto Ierusalimschy
669129a6d8 io.lines() iterate over the standard input file 2002-10-11 17:40:32 -03:00
Roberto Ierusalimschy
46b063ef59 `undump' also uses private buffer 2002-10-09 10:42:01 -03:00
Roberto Ierusalimschy
e1d5153a33 details 2002-10-09 10:00:08 -03:00
Roberto Ierusalimschy
b3d0682fb9 use of different buffers for scanner and concatenation 2002-10-08 15:46:08 -03:00
Roberto Ierusalimschy
02afc892d5 new ANSI C does not assure that realloc(p,0) == free(p) 2002-10-08 15:45:07 -03:00
Roberto Ierusalimschy
fa2f1ec7ba to avoid `strerror', define itself to something else;
nil has a special, fixed reference
2002-10-04 11:31:40 -03:00
Roberto Ierusalimschy
829befcc41 small optimization for object comparison 2002-10-04 11:31:03 -03:00
Roberto Ierusalimschy
d477e4ffd6 detail 2002-10-04 11:30:31 -03:00
Roberto Ierusalimschy
ce09af1e25 easier to define api_check' using assert' 2002-09-20 14:01:24 -03:00
Roberto Ierusalimschy
98d0b79613 EXIT_SUCCESS may be different from 0 2002-09-20 10:32:56 -03:00
Roberto Ierusalimschy
e8f35fc4ff unification of __index & __gettable (and __newindex & __settable) 2002-09-19 17:12:47 -03:00
Roberto Ierusalimschy
6fb0fd5063 avoid `reclearing' weak tables 2002-09-19 16:54:22 -03:00
Roberto Ierusalimschy
565e6d74e1 state's buffer is used only for chars 2002-09-19 10:03:53 -03:00
Roberto Ierusalimschy
f6bc7884be new generators for reading a file line by line 2002-09-17 17:35:54 -03:00
Roberto Ierusalimschy
32a5d96dfc `setmetatable' cannot change protected objects 2002-09-16 16:49:45 -03:00
Roberto Ierusalimschy
8dae071f42 details 2002-09-16 16:18:01 -03:00
Roberto Ierusalimschy
afe1305b1a avoid luaS_resize (which may need extra memory) during `main' activities 2002-09-05 16:57:40 -03:00
Roberto Ierusalimschy
728fa167d2 cannot raise memory error when realloc to smaller block 2002-09-05 16:57:08 -03:00
Roberto Ierusalimschy
1bdde38bd2 no more newlines at the end of error messages 2002-09-05 16:45:42 -03:00
Roberto Ierusalimschy
b2bc3b44b6 no more reserved word "global" 2002-09-03 08:57:38 -03:00
Roberto Ierusalimschy
7c0ccdfd61 avoid the use of "enum" in the API, as they do not have a fixed representation 2002-09-02 17:00:41 -03:00
Roberto Ierusalimschy
4964e7c8a0 details 2002-09-02 16:54:49 -03:00
Roberto Ierusalimschy
2c670baf24 avoid the use of "obvious" names in header files to avoid conflicts 2002-08-30 17:00:59 -03:00
Roberto Ierusalimschy
fdafd4f4a8 new structure for collectable objects, sharing a common header 2002-08-30 16:09:21 -03:00
Roberto Ierusalimschy
beeff4ccaf GC metamethod stored in a weak metatable being collected together with
userdata may not be cleared properly
2002-08-30 16:08:30 -03:00
Roberto Ierusalimschy
12c4e48506 `frontier' patterns 2002-08-23 16:45:24 -03:00
Roberto Ierusalimschy
c78aaa9a70 better line number for function definitions 2002-08-22 16:51:08 -03:00
Roberto Ierusalimschy
4d7a554921 style for switch statements 2002-08-21 16:39:31 -03:00
Roberto Ierusalimschy
fbc23d0245 details 2002-08-21 15:56:33 -03:00
Roberto Ierusalimschy
81a8845e4f detail 2002-08-21 11:57:48 -03:00
Roberto Ierusalimschy
6c283b2f4f new simetric format for ABC instructions, to avoid exchanging operands
for `commutative' operators
2002-08-20 17:03:05 -03:00
Roberto Ierusalimschy
576bded513 details 2002-08-16 17:02:13 -03:00
Roberto Ierusalimschy
ecc7769de2 names... 2002-08-16 17:00:28 -03:00
Roberto Ierusalimschy
da19c436cc cleaning the stage for generational collection 2002-08-16 11:45:55 -03:00
Roberto Ierusalimschy
0039feb9da warning from Visual C 2002-08-16 11:45:18 -03:00
Roberto Ierusalimschy
aa5b15f271 detail 2002-08-14 17:10:33 -03:00
Roberto Ierusalimschy
653416d5c0 angles in radians(!) 2002-08-14 17:07:43 -03:00
Roberto Ierusalimschy
82a3be0671 some corrections + angles in radians 2002-08-14 17:07:25 -03:00
Roberto Ierusalimschy
94b5ad31f4 details 2002-08-13 17:00:51 -03:00
Roberto Ierusalimschy
90d26b9266 update of `debug' library (Lua binding) 2002-08-13 16:44:47 -03:00
Roberto Ierusalimschy
a048d71ef3 new LUA_USERCONFIG to include user options 2002-08-13 12:04:59 -03:00
Roberto Ierusalimschy
27f8a4a69e towards 5.0 (one more step)... 2002-08-12 14:43:35 -03:00
Roberto Ierusalimschy
8e4ac679ff use a linear count for count hook 2002-08-12 14:23:12 -03:00
Roberto Ierusalimschy
221b5be7b7 use of `LoadState' struct (instead of several separate arguments) 2002-08-12 10:37:19 -03:00
Roberto Ierusalimschy
b6791f5fa5 details 2002-08-12 10:37:19 -03:00
Roberto Ierusalimschy
3b058177af towards 5.0 alpha... 2002-08-09 18:03:19 -03:00
Roberto Ierusalimschy
586e510577 details 2002-08-08 17:08:41 -03:00
Roberto Ierusalimschy
9998082839 external messages add their own extra information 2002-08-08 17:08:41 -03:00
Roberto Ierusalimschy
08da48a73c detail 2002-08-07 17:55:00 -03:00
Roberto Ierusalimschy
00a40f4d6a ensure proper rounding 2002-08-07 17:54:38 -03:00
Roberto Ierusalimschy
3bb5079dd4 ensure fixed order for library initialization 2002-08-07 17:54:17 -03:00
Roberto Ierusalimschy
5016f43aa4 (much) cleaner way to control function states 2002-08-07 16:22:39 -03:00
Roberto Ierusalimschy
c1c100a0c0 warnings in other compilers 2002-08-07 11:35:55 -03:00
Roberto Ierusalimschy
b6e2f1a86e small bugs when stack is reallocated 2002-08-07 11:24:24 -03:00
Roberto Ierusalimschy
260e35f576 the usual... 2002-08-06 16:12:54 -03:00
Roberto Ierusalimschy
a56e01a9a0 towards 5.0 alpha... 2002-08-06 16:10:44 -03:00
Roberto Ierusalimschy
4664f2e927 any Lua closure has a table of globals (not only active functions) 2002-08-06 15:54:18 -03:00
Roberto Ierusalimschy
2e38c6ae5a luadebug.h' content now is included in lua.h' 2002-08-06 15:01:50 -03:00
Roberto Ierusalimschy
d3dd337fca lua_Chunkreader gets a lua_State, to avoid future incompatibilities 2002-08-06 14:26:45 -03:00
Roberto Ierusalimschy
634344d61f new API for weak mode 2002-08-06 14:06:56 -03:00
Roberto Ierusalimschy
a2fa48a570 new (old?) error handling scheme 2002-08-06 12:32:22 -03:00
Roberto Ierusalimschy
8b2b8790b5 small bug: basic `ci' must have a valid func (base - 1) 2002-08-05 15:45:45 -03:00
Roberto Ierusalimschy
0b3d380f9f internal names 2002-08-05 15:45:02 -03:00
Roberto Ierusalimschy
4e23699aa6 new implementation for error handling 2002-08-05 14:36:24 -03:00
Roberto Ierusalimschy
1c0ac3c0f5 new implementation for tailcall 2002-08-05 14:35:45 -03:00
Roberto Ierusalimschy
4a4f243795 new API for error handling 2002-08-05 11:51:47 -03:00
Roberto Ierusalimschy
0417a4bb0b new implementation for tailcalls and error handling 2002-08-05 11:51:21 -03:00
Roberto Ierusalimschy
5037196f6f new macros `ttis*' 2002-08-05 11:50:39 -03:00
Roberto Ierusalimschy
9fb80bde3c tailcall is executed together with call 2002-08-05 11:46:43 -03:00
Roberto Ierusalimschy
2dcc31574f new function xpcall 2002-08-05 11:46:02 -03:00
Roberto Ierusalimschy
390fc99a5c xpcall now is builtin + new macros `ttis*' 2002-08-05 11:10:10 -03:00
Roberto Ierusalimschy
79c8edb6c4 new names for light userdata operations 2002-07-17 13:25:13 -03:00
Roberto Ierusalimschy
e5146fb01f CallInfo has different fields for C functions and Lua functions 2002-07-16 11:26:56 -03:00
Roberto Ierusalimschy
ce6b930464 `isdst' should be a boolean (and not 0/1!!) 2002-07-12 15:54:53 -03:00
Roberto Ierusalimschy
ac7006d374 ^D in interactive mode finish interaction (no questions asked) 2002-07-10 17:49:01 -03:00
Roberto Ierusalimschy
12bee999dd new way to handle macros read_line/save_line 2002-07-10 17:44:34 -03:00
Roberto Ierusalimschy
a8c9eec426 bug: chunk can end just after a '\' in a string 2002-07-10 17:43:53 -03:00
Roberto Ierusalimschy
a885b826b3 LUA_ALERT is no longer used 2002-07-09 15:49:13 -03:00
Roberto Ierusalimschy
a960e62c3e new options; no more _ALERT; no more getargs 2002-07-09 15:19:44 -03:00
Roberto Ierusalimschy
c51aa6ee33 details 2002-07-09 15:19:19 -03:00
Roberto Ierusalimschy
d88860131a new macro `lua_isudataval' (for completude) 2002-07-09 11:58:28 -03:00
Roberto Ierusalimschy
44752fc9ce hook count is quadratic 2002-07-08 17:22:08 -03:00
Roberto Ierusalimschy
39b2d58c39 new interface for debug hooks 2002-07-08 15:21:33 -03:00
Roberto Ierusalimschy
d2d24f0971 details to allow compilation of Lua as a single file 2002-07-08 15:14:36 -03:00
Roberto Ierusalimschy
0436c96866 C++ warning 2002-07-08 13:51:20 -03:00
Roberto Ierusalimschy
f8279f6cd8 optimizations for gettable (temporary) 2002-07-05 15:27:39 -03:00
Roberto Ierusalimschy
1fe280df72 new priority for and/or 2002-07-04 15:23:42 -03:00
Roberto Ierusalimschy
1ede98157d strings are always `strong' in weaktables 2002-07-04 14:58:02 -03:00
Roberto Ierusalimschy
3e52573c72 details (error messages) 2002-07-04 09:29:32 -03:00
Roberto Ierusalimschy
84ad1eea81 use of NaN as key breaks some invariants 2002-07-02 14:54:23 -03:00
Roberto Ierusalimschy
b30ec2532c details 2002-07-02 13:43:28 -03:00
Roberto Ierusalimschy
68ee518e81 only tables need `lua_number2int' 2002-07-01 16:31:10 -03:00
Roberto Ierusalimschy
76a73cb2ee new getn' (and setn') 2002-07-01 16:25:28 -03:00
Roberto Ierusalimschy
aa3da1605c `newproxy' uses its own weaktable 2002-07-01 16:23:58 -03:00
Roberto Ierusalimschy
9f4b5b5232 weak keys are removed only after finalization 2002-07-01 14:06:58 -03:00
Roberto Ierusalimschy
5fabed21a1 getglobals(0) is the C global table 2002-06-26 17:36:17 -03:00
Roberto Ierusalimschy
f67ccfbdeb no more `lua_getn' function 2002-06-26 16:28:44 -03:00
Roberto Ierusalimschy
cfcf200806 concat' goes to table' library 2002-06-26 16:28:08 -03:00
Roberto Ierusalimschy
f32a8c0477 details (temporary?) 2002-06-26 13:37:39 -03:00
Roberto Ierusalimschy
88607acc2c details 2002-06-26 13:37:23 -03:00
Roberto Ierusalimschy
6de93e2932 two new bugs in 4.0 :-( (both were already corrected in 5.0 :-) 2002-06-25 16:23:55 -03:00
Roberto Ierusalimschy
25dc9b7faf new functions dofile' and pairs'; correct way to check proxies 2002-06-25 16:19:33 -03:00
Roberto Ierusalimschy
78c507b7b8 lua_upcall' -> lua_call' 2002-06-25 16:18:49 -03:00
Roberto Ierusalimschy
69906cb56f error message ends with `\n' (is already formatted) 2002-06-25 16:18:20 -03:00
Roberto Ierusalimschy
9d6556fd87 userdata are removed from weaktables before invoking their GC fallbacks 2002-06-25 16:17:42 -03:00
Roberto Ierusalimschy
35707e94f3 __weakmode' -> __mode' 2002-06-25 16:17:22 -03:00
Roberto Ierusalimschy
89b102bd1d new `luaL_weakregistry' function 2002-06-25 16:15:21 -03:00
Roberto Ierusalimschy
fdfd5b44ee TM_GETTABLE/TM_SETTABLE don't need fast access anymore 2002-06-24 17:18:38 -03:00
Roberto Ierusalimschy
1a4c428d6d new function `newproxy' 2002-06-24 14:23:16 -03:00
Roberto Ierusalimschy
2394604d10 assertion may fail when closing a state 2002-06-24 14:19:43 -03:00
Roberto Ierusalimschy
922f36a05b details 2002-06-24 12:07:21 -03:00
Roberto Ierusalimschy
ad41fc11eb details in arithmetic implementation 2002-06-24 11:11:14 -03:00
Roberto Ierusalimschy
e182cf452f `^' operator is defined in registry.__pow 2002-06-24 10:54:13 -03:00
Roberto Ierusalimschy
e34f282365 `luaV_gettable' returns element position 2002-06-24 10:08:45 -03:00
Roberto Ierusalimschy
3941af53ad first implementation of independent global table per function 2002-06-20 17:41:46 -03:00
Roberto Ierusalimschy
5610fdd776 avoid using obsolete lua_dostring 2002-06-20 17:40:38 -03:00
Roberto Ierusalimschy
b449a5e574 more robust when printing error messages 2002-06-20 17:40:09 -03:00
Roberto Ierusalimschy
e572dffa15 small bug building error messages 2002-06-20 17:39:44 -03:00
Roberto Ierusalimschy
5893fcb71a accept option arguments without spaces (e.g. "-eprint(a)") 2002-06-18 14:43:49 -03:00
Roberto Ierusalimschy
eec0905173 better tests (assertions) for debug hooks 2002-06-18 14:42:52 -03:00
Roberto Ierusalimschy
a44f37513b better treatment for error messages 2002-06-18 14:12:05 -03:00
Roberto Ierusalimschy
6ee2dbdfe9 traceback stops at first protected call 2002-06-18 14:10:43 -03:00
Roberto Ierusalimschy
1dbe708aa8 new protocol for error handling 2002-06-18 12:19:27 -03:00
Roberto Ierusalimschy
8f080fd683 `traceback' returns only the traceback 2002-06-18 12:17:58 -03:00
Roberto Ierusalimschy
d8678edddc luaL_verror -> luaL_error 2002-06-18 12:16:18 -03:00
Roberto Ierusalimschy
e812aa2002 avoid assignments to TObject access macros 2002-06-17 10:51:01 -03:00
Roberto Ierusalimschy
c31494df26 avoid gotos when possible 2002-06-14 14:21:32 -03:00
Roberto Ierusalimschy
8fd0f6a82b new macro to check conditions on expression macros 2002-06-13 10:45:31 -03:00
Roberto Ierusalimschy
eb3de8768a rawcall' -> upcall' (unprotected call) 2002-06-13 10:44:50 -03:00
Roberto Ierusalimschy
864c96f36c new fallback for equality `__eq' 2002-06-13 10:39:55 -03:00
Roberto Ierusalimschy
0052930ffe details 2002-06-12 16:16:00 -03:00
Roberto Ierusalimschy
eeab473fc8 new fallback __le (less equal), for partial order 2002-06-12 11:56:22 -03:00
Roberto Ierusalimschy
6b8cdc9cdd Lua now uses only `realloc' for all its memory management 2002-06-11 13:26:12 -03:00
Roberto Ierusalimschy
000d081fd0 warnings from other compilers 2002-06-06 15:17:33 -03:00
Roberto Ierusalimschy
65d66ba275 new "local function" 2002-06-06 14:29:53 -03:00
Roberto Ierusalimschy
cff22f57dd some refactoring 2002-06-06 10:52:37 -03:00
Roberto Ierusalimschy
168ea16acb details 2002-06-06 10:16:02 -03:00
Roberto Ierusalimschy
dc6e6c48bb on the way to 5.0 2002-06-06 09:49:28 -03:00
Roberto Ierusalimschy
e3cddc950c C is not C++... 2002-06-06 09:43:08 -03:00
Roberto Ierusalimschy
630acb2048 _ERRORMESSAGE `accepts' non-string arguments (at least for now...) 2002-06-06 09:40:36 -03:00
Roberto Ierusalimschy
16f4723398 names & names 2002-06-06 09:40:22 -03:00
Roberto Ierusalimschy
f1c43bbe19 new function `xpcall' (at least for now...) 2002-06-06 09:39:48 -03:00
Roberto Ierusalimschy
5a8f383e60 io.close() closes standard output file; `close' now is method 2002-06-05 14:42:03 -03:00
Roberto Ierusalimschy
711b936849 new versions from lhf 2002-06-05 14:26:23 -03:00
Roberto Ierusalimschy
5b8ee9fa8d new names for standard libraries 2002-06-05 14:24:04 -03:00
Roberto Ierusalimschy
2cd6161060 don't need stdio 2002-06-05 13:59:52 -03:00
Roberto Ierusalimschy
a102221a0b better error messages 2002-06-05 13:59:37 -03:00
Roberto Ierusalimschy
6dd0b6c62b details 2002-06-05 13:59:21 -03:00
Roberto Ierusalimschy
fa23301251 defintions for lua_number2str and lua_str2number don't need to be public 2002-06-05 09:34:19 -03:00
Roberto Ierusalimschy
94c2449d25 undump may return LUA_ERRRUN 2002-06-03 17:12:50 -03:00
Roberto Ierusalimschy
c398a02110 uses `isspace' to recognize space characters 2002-06-03 17:12:21 -03:00
Roberto Ierusalimschy
ad7103ea3a lua_load* defined in auxlib (and so renamed to luaL_load*) 2002-06-03 17:11:41 -03:00
Roberto Ierusalimschy
0079e0f57c core tests whether file is binary 2002-06-03 17:11:07 -03:00
Roberto Ierusalimschy
cfff013586 detail 2002-06-03 14:47:18 -03:00
Roberto Ierusalimschy
35a22ed1ab lua_load* replaced by a simple lua_load 2002-06-03 14:46:34 -03:00
Roberto Ierusalimschy
ff91b355f4 no more use of stdio inside the core (except for `tostring'...) 2002-06-03 11:09:57 -03:00
Roberto Ierusalimschy
5094c37988 strconc' -> concat' 2002-06-03 11:08:43 -03:00
Roberto Ierusalimschy
46c471d7e9 new `__newindex' eventfield 2002-05-27 17:35:40 -03:00
Roberto Ierusalimschy
859ecf36b6 new copyright notice 2002-05-23 17:29:05 -03:00
Roberto Ierusalimschy
a1700bbc50 details 2002-05-23 16:43:04 -03:00
Roberto Ierusalimschy
8876a1bf92 details 2002-05-20 16:51:06 -03:00
Roberto Ierusalimschy
f53fd8d5f5 _ALERT is a private afair of lua.c 2002-05-16 16:09:19 -03:00
Roberto Ierusalimschy
955def0348 new names for string formating functions 2002-05-16 15:39:46 -03:00
Roberto Ierusalimschy
9c3b3f82fe new commands to test `load' 2002-05-16 11:59:49 -03:00
Roberto Ierusalimschy
b7a0503c1d new format for error messages 2002-05-15 15:57:44 -03:00
Roberto Ierusalimschy
1c328a191a no more `global' declarations 2002-05-14 14:52:22 -03:00
Roberto Ierusalimschy
58bf77bc7f no more extra space when growing hash 2002-05-13 10:38:59 -03:00
Roberto Ierusalimschy
8da6fe62d8 `nexti' returns correct indices 2002-05-13 10:10:58 -03:00
Roberto Ierusalimschy
c18fe57e54 quick-and-dirty function to print code (for debugging Lua) 2002-05-13 10:10:04 -03:00
Roberto Ierusalimschy
af19d55635 generic for also coded to make test at the end of the loop 2002-05-13 10:09:00 -03:00
Roberto Ierusalimschy
b55fded18c details about jump optimization 2002-05-13 10:07:48 -03:00
Roberto Ierusalimschy
2dadc81822 cleaner implementation of code generation for jumps 2002-05-10 16:22:11 -03:00
Roberto Ierusalimschy
b487975344 optimization for `while' (first version) 2002-05-10 14:02:32 -03:00
Roberto Ierusalimschy
94e5545806 comment 2002-05-09 15:00:38 -03:00
Roberto Ierusalimschy
78b40bf57d `skip' instructions must be followed by a jump 2002-05-09 11:14:34 -03:00
Roberto Ierusalimschy
01f1ac36b1 `global' tables (registry, etc.) stored in proper place, not in the stack 2002-05-08 14:34:23 -03:00
Roberto Ierusalimschy
a4d06736d4 correct implementation for arrays of size 1 2002-05-08 14:34:00 -03:00
Roberto Ierusalimschy
dea6b6da94 new function lua_vpushstr' to replace uses of sprintf' 2002-05-07 14:36:56 -03:00
Roberto Ierusalimschy
71144e3ff0 errors `return' int, to avoid warnings
+ home-made `sprintf' (first version)
2002-05-06 16:05:10 -03:00
Roberto Ierusalimschy
0dbf0c5953 new format for test intructions (handle NaN correctly) 2002-05-06 12:51:41 -03:00
Roberto Ierusalimschy
85dcb411a8 all textual errors go through `luaL_verror' 2002-05-02 14:12:27 -03:00
Roberto Ierusalimschy
3c6a383d62 avoid limits in filename size 2002-05-02 13:55:55 -03:00
Roberto Ierusalimschy
9a0f0dcc77 precompiler may create functions without `lineinfo' 2002-05-02 10:06:20 -03:00
Roberto Ierusalimschy
751cd867d3 new way to handle errors 2002-05-01 17:48:12 -03:00
Roberto Ierusalimschy
b36b2a061c new way to handle errors 2002-05-01 17:40:42 -03:00
Roberto Ierusalimschy
ab52fc6097 new macro to `fix' strings 2002-04-30 10:01:48 -03:00
Roberto Ierusalimschy
e68d0df1c6 function `zsopen' is not used 2002-04-29 09:37:41 -03:00
Roberto Ierusalimschy
9b38a696d5 avoid names that differ only in capitalization 2002-04-24 17:07:46 -03:00
Roberto Ierusalimschy
383e8b9e77 use of a common `dummynode' for all empty tables 2002-04-23 12:04:39 -03:00
Roberto Ierusalimschy
f1a1bb23fe good stack limit to compute ack(8,3) 2002-04-23 11:59:35 -03:00
Roberto Ierusalimschy
151ba1cc7b details 2002-04-23 11:59:22 -03:00
Roberto Ierusalimschy
ee4859b3e3 new way to handle errors (temporary version) 2002-04-22 11:40:50 -03:00
Roberto Ierusalimschy
f388ee4a82 new way to handle errors 2002-04-22 11:40:23 -03:00
Roberto Ierusalimschy
30ad4c75db bug: 'local a,b; a,b = 1,f()' did not close f() 2002-04-22 11:38:52 -03:00
Roberto Ierusalimschy
3ee1efa7b2 some simplifications 2002-04-22 11:37:09 -03:00
Roberto Ierusalimschy
c11d374c59 `panic' function configurable via API 2002-04-16 14:08:28 -03:00
Roberto Ierusalimschy
13230c451b details 2002-04-16 09:00:02 -03:00
Roberto Ierusalimschy
391c5459cb new implementation for `require' (with templates) 2002-04-15 17:54:41 -03:00
Roberto Ierusalimschy
62dd4cbe91 check for errors while loading file 2002-04-15 16:34:42 -03:00
Roberto Ierusalimschy
ae5283dc36 co' library goes with basic library (and not with tab') 2002-04-12 16:57:29 -03:00
Roberto Ierusalimschy
1ce6cb6032 no more option `*u' in read (too complex) 2002-04-12 16:56:25 -03:00
Roberto Ierusalimschy
11c63bc3af error in calls signalled in first line (instead of last) 2002-04-10 16:14:45 -03:00
Roberto Ierusalimschy
f1f271ae76 details 2002-04-10 15:05:08 -03:00
Roberto Ierusalimschy
6c7334a9ac line trace uses savedpc' to save last pc' seen 2002-04-10 09:11:07 -03:00
Roberto Ierusalimschy
8e1e618606 baselib' splited in baselib' and `tablib' 2002-04-09 17:19:06 -03:00
Roberto Ierusalimschy
af4721f7a3 library with table manipulation functions 2002-04-09 17:19:06 -03:00
Roberto Ierusalimschy
018e50ad7f use addresses as keys to hooks 2002-04-09 16:48:08 -03:00
Roberto Ierusalimschy
7b65328c8e new semantics for `generic for' (with state) 2002-04-09 16:47:44 -03:00
Roberto Ierusalimschy
d2e05589d7 bug: `resume' was returning its arguments, too 2002-04-09 16:46:56 -03:00
Roberto Ierusalimschy
237969724f support for light' userdata + simpler support for boxed' udata 2002-04-05 15:54:31 -03:00
Roberto Ierusalimschy
f438d00ef3 correct #args for calls with self (a:foo(...)) 2002-04-04 17:25:55 -03:00
Roberto Ierusalimschy
c3b90061ea new design for iolib (object style) 2002-04-04 17:24:56 -03:00
Roberto Ierusalimschy
a2e414d679 `pow' must be global (as the implementation of '^') 2002-04-04 17:20:49 -03:00
Roberto Ierusalimschy
93bcb65a9b debug interface uses method' to describe calls like a:foo()' 2002-04-04 14:21:31 -03:00
Roberto Ierusalimschy
49c95648a0 getmetatable doesn't push nil when there is no metatable 2002-04-02 17:43:18 -03:00
Roberto Ierusalimschy
13ab5a6bb1 details 2002-04-02 17:43:08 -03:00
Roberto Ierusalimschy
cd99bbcd0d better support for new libraries 2002-04-02 17:42:49 -03:00
Roberto Ierusalimschy
2cbbf7e95a tostring' uses __tostring' when available 2002-04-02 17:42:20 -03:00
Roberto Ierusalimschy
e5919be1a7 bug: end of block may not be end of stat 2002-04-02 17:34:15 -03:00
Roberto Ierusalimschy
b795d4b561 details 2002-04-01 11:42:33 -03:00
Roberto Ierusalimschy
c371413530 small bug if LUA_USERINIT leaves garbage on the stack 2002-03-27 15:00:13 -03:00
Roberto Ierusalimschy
d1f220217b when possible, library functions accept nil as none 2002-03-27 12:30:41 -03:00
Roberto Ierusalimschy
405e3a4597 metatable always return some value 2002-03-27 09:49:53 -03:00
Roberto Ierusalimschy
81215cd59f simpler way to control stack overflow 2002-03-26 17:46:10 -03:00
Roberto Ierusalimschy
0b9b53e21c details 2002-03-26 15:55:50 -03:00
Roberto Ierusalimschy
44a5484d73 small bug (L->ci->top may be larger than L->top...) 2002-03-25 16:45:06 -03:00
Roberto Ierusalimschy
801aaf37b1 simpler implementation for line information 2002-03-25 14:47:14 -03:00
Roberto Ierusalimschy
00af2faae7 first implementation of proper tail call 2002-03-22 13:54:31 -03:00
Roberto Ierusalimschy
e9ef7ed2d3 first implementation for tail call 2002-03-21 17:32:22 -03:00
Roberto Ierusalimschy
2626708b72 details 2002-03-21 17:31:43 -03:00
Roberto Ierusalimschy
19ac0fadc9 don't need to mark the stacks twice ;-) 2002-03-20 15:54:29 -03:00
Roberto Ierusalimschy
ca2ceef659 simpler solution for finalizing udata 2002-03-20 15:37:28 -03:00
Roberto Ierusalimschy
5023aaee0a reserve one more bit for GC 2002-03-20 15:37:13 -03:00
Roberto Ierusalimschy
88c9bf99de standard libraries in packages 2002-03-20 09:54:08 -03:00
Roberto Ierusalimschy
63a614e145 some improvements in stack control 2002-03-20 09:52:32 -03:00
Roberto Ierusalimschy
48e732e07d improvements in stack control 2002-03-20 09:51:29 -03:00
Roberto Ierusalimschy
938092489b erroneous objects may not live in the stack 2002-03-19 09:45:25 -03:00
Roberto Ierusalimschy
578d1da00d new names for tag methods 2002-03-18 17:24:14 -03:00
Roberto Ierusalimschy
24d6d0528d api.c only needs to check pushes when api_check is defined 2002-03-18 17:11:52 -03:00
Roberto Ierusalimschy
0b00e7f1a2 new macro to convert double->int 2002-03-18 15:18:35 -03:00
Roberto Ierusalimschy
b7ed502dea configurable macros should live in llimits.h 2002-03-18 15:16:16 -03:00
Roberto Ierusalimschy
58badbab99 special treatment for 'global in nil' 2002-03-18 11:49:46 -03:00
Roberto Ierusalimschy
da81845cd5 an error may call GC and find an incomplete `ci' 2002-03-15 14:17:16 -03:00
Roberto Ierusalimschy
9681ff09db small optimization when returning a single local value 2002-03-14 15:32:37 -03:00
Roberto Ierusalimschy
7ff21273d6 implementation of `global' statement 2002-03-14 15:01:52 -03:00
Roberto Ierusalimschy
207dad8606 comments 2002-03-14 13:50:06 -03:00
Roberto Ierusalimschy
c97dc294a9 first implementation of `gfind' 2002-03-11 10:29:40 -03:00
Roberto Ierusalimschy
71c716e5a8 avoid C identifiers beginning with '_' 2002-03-11 09:45:00 -03:00
Roberto Ierusalimschy
51ad2f1162 error message 2002-03-08 16:25:24 -03:00
Roberto Ierusalimschy
ecda9c1972 details 2002-03-08 16:17:59 -03:00
Roberto Ierusalimschy
e19eba7219 cannot store `top' in local variables... 2002-03-08 16:11:03 -03:00
Roberto Ierusalimschy
bd8b9c94b3 generic for (with any number of control variables) 2002-03-08 16:10:32 -03:00
Roberto Ierusalimschy
4db04555f0 implementation of long comments 2002-03-08 16:07:01 -03:00
Roberto Ierusalimschy
c16a35d669 lua_stackspace' replaced by lua_checkstack' 2002-03-07 15:15:10 -03:00
Roberto Ierusalimschy
8f837e83b2 using `ci->top' to control acceptable indices in C calls 2002-03-07 15:14:29 -03:00
Roberto Ierusalimschy
6658b9588f details 2002-03-07 15:11:51 -03:00
Roberto Ierusalimschy
457d88eaaa configurable minimum size for the string table 2002-03-05 13:22:54 -03:00
Roberto Ierusalimschy
8a1a512c64 lu_byte is enough for those fields (maxstack < 256) 2002-03-05 09:42:47 -03:00
Roberto Ierusalimschy
6b0c38c2e7 `inline' of tonumber 2002-03-04 18:33:09 -03:00
Roberto Ierusalimschy
1a3f175640 small optimization 2002-03-04 18:32:34 -03:00
Roberto Ierusalimschy
88c7b574cb `luaA_index' is a local macro now 2002-03-04 18:29:41 -03:00
Roberto Ierusalimschy
51bf91a970 detail 2002-03-04 12:40:04 -03:00
Roberto Ierusalimschy
1b6315ba10 not all unfinished strings with "..." end in EOF 2002-03-04 12:27:14 -03:00
Roberto Ierusalimschy
3b001d9a9d more tests for boolean API 2002-03-04 12:26:56 -03:00
Roberto Ierusalimschy
c36b5cc726 detail 2002-02-15 13:15:10 -02:00
Roberto Ierusalimschy
2c1eb62a08 get error messages from luaL_errstr 2002-02-14 20:23:43 -02:00
Roberto Ierusalimschy
63e2d92123 no more -DOLD_ANSI option + details 2002-02-14 19:49:33 -02:00
Roberto Ierusalimschy
e966dd93be towards next version... 2002-02-14 19:48:32 -02:00
Roberto Ierusalimschy
2f8e3c5543 prints any results returned by chunk 2002-02-14 19:47:50 -02:00
Roberto Ierusalimschy
b0a5e156b8 no more maximum stack size 2002-02-14 19:47:29 -02:00
Roberto Ierusalimschy
ac178ee478 new constructor syntax + new generic `for' 2002-02-14 19:46:58 -02:00
Roberto Ierusalimschy
1e602a61b3 new generic `for' 2002-02-14 19:46:43 -02:00
Roberto Ierusalimschy
57fb51f975 luaH_next' works like next' 2002-02-14 19:46:13 -02:00
Roberto Ierusalimschy
1c423d2661 LFIELDS_PER_FLUSH is an opcode detail 2002-02-14 19:43:01 -02:00
Roberto Ierusalimschy
b3ffaca638 details 2002-02-14 19:41:53 -02:00
Roberto Ierusalimschy
bee86e23be luaH_next' works like next' + better hash for pointers 2002-02-14 19:41:08 -02:00
Roberto Ierusalimschy
0056ed4135 better(?) order for types (nil == 0) 2002-02-14 19:40:29 -02:00
Roberto Ierusalimschy
e01f5e6809 better order of record fields for 64-bit machines 2002-02-08 20:42:41 -02:00
Roberto Ierusalimschy
cbfc581990 details. 2002-02-08 20:41:50 -02:00
Roberto Ierusalimschy
d3651c1d88 `getstr' now gives const char * 2002-02-08 20:41:09 -02:00
Roberto Ierusalimschy
57a7baafb9 error message compatible with incomplete lines of lua.c 2002-02-08 20:40:27 -02:00
Roberto Ierusalimschy
252e01e398 `setlocale' may be used to query the current locale 2002-02-08 20:39:56 -02:00
Roberto Ierusalimschy
87b0e3d477 no more `lua_istrue' function 2002-02-08 20:39:36 -02:00
Roberto Ierusalimschy
cb50fcf42d incomplete lines (by lhf) 2002-02-07 15:27:12 -02:00
Roberto Ierusalimschy
c6a108e012 test for lua_pushbool 2002-02-07 15:26:33 -02:00
Roberto Ierusalimschy
d5ceb369b1 boolean type must be 0 or 1 2002-02-07 15:26:10 -02:00
Roberto Ierusalimschy
86a4de256e no more lua_[gs]etstr 2002-02-07 15:25:36 -02:00
Roberto Ierusalimschy
53aaee6ee6 comments 2002-02-07 15:25:12 -02:00
Roberto Ierusalimschy
67bda7e136 details. 2002-02-07 15:24:05 -02:00
Roberto Ierusalimschy
7c8f1823e7 bug: true 1 != true 2 + no more lua_getstr + some new macros 2002-02-07 15:22:53 -02:00
Roberto Ierusalimschy
ca181f31e4 line number in listcode (and tests for replace) 2002-02-05 20:40:05 -02:00
Roberto Ierusalimschy
38b0e6128d simpler implementation for `for' loops 2002-02-05 20:39:12 -02:00
Roberto Ierusalimschy
addbe8c8b0 protected execution of `resume' 2002-02-05 20:38:37 -02:00
Roberto Ierusalimschy
6bb5cb1cbd comments 2002-02-05 20:37:26 -02:00
Roberto Ierusalimschy
d070506a25 new function luaL_errstr 2002-02-05 20:36:52 -02:00
Roberto Ierusalimschy
0a87d9d334 new function `lua_replace' 2002-02-05 20:35:58 -02:00
Roberto Ierusalimschy
f856fdeabd details 2002-01-30 15:28:05 -02:00
Roberto Ierusalimschy
653977a0ac callhook can be static 2002-01-30 15:27:53 -02:00
Roberto Ierusalimschy
d6fd33e76f eventtable' renamed to metatable' 2002-01-30 15:26:44 -02:00
Roberto Ierusalimschy
50e2952593 first version of dynamic stack 2002-01-25 20:14:54 -02:00
Roberto Ierusalimschy
b217ae644e details 2002-01-25 20:14:09 -02:00
Roberto Ierusalimschy
a048cc9676 nil is a `valid' eventtable 2002-01-25 19:55:41 -02:00
Roberto Ierusalimschy
eb262bc617 2^15 does not fit in a 16-bit int 2002-01-25 19:51:33 -02:00
Roberto Ierusalimschy
74907fb71e OP_LOADINT can be done by OP_LOADK 2002-01-25 19:50:39 -02:00
Roberto Ierusalimschy
b38e594ed7 small improvements 2002-01-18 15:39:40 -02:00
Roberto Ierusalimschy
448517e47e no more linehook field in CallInfo 2002-01-18 15:39:06 -02:00
Roberto Ierusalimschy
931ee346e3 legacy declaration 2002-01-18 15:38:13 -02:00
Roberto Ierusalimschy
dea98702c9 preparations for stack reallocation 2002-01-16 20:04:50 -02:00
Roberto Ierusalimschy
7ab7703b53 cleaner semantics for test instructions (skips) 2002-01-16 20:03:57 -02:00
Roberto Ierusalimschy
566310fa04 small optimization 2002-01-16 20:02:46 -02:00
Roberto Ierusalimschy
6272c843de yield' passes its arguments to resume' 2002-01-11 18:27:41 -02:00
Roberto Ierusalimschy
5d14ce612b details 2002-01-11 18:27:11 -02:00
Roberto Ierusalimschy
d56d4cf776 distinct functions to create/destroy states and threads 2002-01-11 18:26:52 -02:00
Roberto Ierusalimschy
b7ae43d457 detail 2002-01-11 18:23:01 -02:00
Roberto Ierusalimschy
f083812c02 first implementation of coroutines 2002-01-09 20:02:47 -02:00
Roberto Ierusalimschy
3533382a1e dependencies updated 2002-01-09 19:59:24 -02:00
Roberto Ierusalimschy
ea2a75d19e new macro lua_userstateopen 2002-01-09 19:51:06 -02:00
Roberto Ierusalimschy
b3bb0f132b new interface for weak modes 2002-01-09 19:50:35 -02:00
Roberto Ierusalimschy
facfec0687 small optimizations 2002-01-03 15:42:57 -02:00
Roberto Ierusalimschy
34df9976a9 some compatibility macros 2002-01-03 15:28:58 -02:00
Roberto Ierusalimschy
cfaa8fbf1d better check for option in `strfind' 2002-01-03 15:27:43 -02:00
Roberto Ierusalimschy
f42cc90d2d some warnings 2001-12-21 15:31:35 -02:00
Roberto Ierusalimschy
9d2e454d6f BUG: seg. fault when rawget/rawset get extra arguments 2001-12-21 15:30:31 -02:00
Roberto Ierusalimschy
09e15692f3 rename of lua_isnull to lua_isnone 2001-12-20 19:27:12 -02:00
Roberto Ierusalimschy
42754c0f15 small optimizations 2001-12-20 19:26:52 -02:00
Roberto Ierusalimschy
18afb90349 first version of stackless Lua 2001-12-20 13:13:38 -02:00
Roberto Ierusalimschy
22dd271cbb another bug in next (when n is a power of 2) 2001-12-19 16:11:00 -02:00
Roberto Ierusalimschy
e04f7ed450 first version of Lua "stackless" 2001-12-18 18:52:30 -02:00
Roberto Ierusalimschy
101cee3032 LUA_ERRERR also cannot generate error message 2001-12-13 16:11:02 -02:00
Roberto Ierusalimschy
eb7312d9be comments 2001-12-13 16:10:55 -02:00
Roberto Ierusalimschy
21259a50e1 run GC tag methods in protected mod 2001-12-12 15:47:33 -02:00
Roberto Ierusalimschy
9aff171f3b new type `boolean' 2001-12-11 20:48:44 -02:00
Roberto Ierusalimschy
ed9be5e1f0 reentrant implementation of garbage collection 2001-12-11 14:52:57 -02:00
Roberto Ierusalimschy
9d801f43d4 details 2001-12-10 20:12:08 -02:00
Roberto Ierusalimschy
e043b72a55 simpler way to collect userdata 2001-12-10 20:11:23 -02:00
Roberto Ierusalimschy
a4c35a3269 it doesn't pay to optimize absence when it is an error 2001-12-10 20:10:30 -02:00
Roberto Ierusalimschy
9cd36059ad new API functions lua_getstr/lua_setstr 2001-12-10 20:09:51 -02:00
Roberto Ierusalimschy
592a309177 tag system replaced by event tables 2001-12-05 18:15:18 -02:00
Roberto Ierusalimschy
413fc7334b new implementation for lua upvalues (sugested by E.T.): simpler and solves
a bug for multi-stacks
2001-11-29 18:22:22 -02:00
Roberto Ierusalimschy
fca0a12e23 avoid clashing names between macros and fields 2001-11-29 18:21:46 -02:00
Roberto Ierusalimschy
72659a0605 no more explicit support for wide-chars; too much troble... 2001-11-28 18:13:13 -02:00
Roberto Ierusalimschy
dfaf8c5291 details 2001-11-27 18:56:47 -02:00
Roberto Ierusalimschy
657f65211a bug: `next' did not work for numeric indices 2001-11-16 14:29:51 -02:00
Roberto Ierusalimschy
39395e1211 `luaX_syntaxerror' does not need to be public 2001-11-16 14:29:10 -02:00
Roberto Ierusalimschy
26bf2adace optimizations for space in LClosures and time cleanning weak tables 2001-11-06 19:41:53 -02:00
Roberto Ierusalimschy
fd48dcc7c8 details. 2001-11-06 19:41:43 -02:00
Roberto Ierusalimschy
617008f552 field G renamed to _G to avoid problemas with bugged macro-systems
(there is a macro named G too)
2001-11-06 19:40:51 -02:00
Roberto Ierusalimschy
ec9d8308b4 global table is also pseudo-index 2001-10-31 18:31:38 -02:00
Roberto Ierusalimschy
af59848219 tables of globals accessible through pseudo-index in C API 2001-10-31 17:58:11 -02:00
Roberto Ierusalimschy
46347d768e `ref' support goes to auxlib 2001-10-31 17:40:14 -02:00
Roberto Ierusalimschy
36eb665859 no more refs, upvalues; lexical scoping;pseudo-indices 2001-10-31 16:06:05 -02:00
Roberto Ierusalimschy
070204300c more consistent names for auxlib functions 2001-10-26 15:33:30 -02:00
Roberto Ierusalimschy
21aa7e55f2 optimization for array part of a Table 2001-10-25 17:14:14 -02:00
Roberto Ierusalimschy
fffb6f3814 no more MINPOWER2 2001-10-25 17:13:33 -02:00
Roberto Ierusalimschy
0b551a24f8 Hash' -> Table' 2001-10-25 17:12:21 -02:00
Roberto Ierusalimschy
8069f77ca4 C++ warning 2001-10-17 19:17:45 -02:00
Roberto Ierusalimschy
1e81da51ba new API for registry and C upvalues + new implementation for references 2001-10-17 19:12:57 -02:00
Roberto Ierusalimschy
7cd37142f4 details 2001-10-17 19:06:56 -02:00
Roberto Ierusalimschy
e7c2eebd87 new function `concat' 2001-10-16 15:41:43 -02:00
Roberto Ierusalimschy
0c3ea96541 no more copytagmethod function 2001-10-11 18:41:21 -03:00
Roberto Ierusalimschy
babaa96eab URL in indentification 2001-10-11 18:40:56 -03:00
Roberto Ierusalimschy
15462edb0f new definitions for closure structures 2001-10-02 13:45:03 -03:00
Roberto Ierusalimschy
6f936bc793 "compatibility module" no longer exists 2001-10-02 13:43:54 -03:00
Roberto Ierusalimschy
b840a7518d details 2001-10-02 13:43:29 -03:00
Roberto Ierusalimschy
f54cdb33a5 small bug in close x return 2001-09-28 13:48:16 -03:00
Roberto Ierusalimschy
8e9b1e4ae9 details 2001-09-25 14:08:46 -03:00
Roberto Ierusalimschy
328d53e77b restricted syntax for function call/table accesses prefixes 2001-09-25 14:06:48 -03:00
Roberto Ierusalimschy
c04d9b9ecb small bug when closing closures in error conditions 2001-09-25 14:05:49 -03:00
Roberto Ierusalimschy
c44c68450a changes by lhf 2001-09-24 12:54:36 -03:00
Roberto Ierusalimschy
abdbe883a8 first implementation of unrestricted static scoping 2001-09-07 14:39:10 -03:00
Roberto Ierusalimschy
4d0935ec0f better definition for `luaM_freelem' 2001-09-07 14:30:16 -03:00
Roberto Ierusalimschy
e1d072571e better syntax for type casts 2001-08-31 16:46:07 -03:00
Roberto Ierusalimschy
7651a5c6b2 start of new version 2001-08-31 16:46:07 -03:00
Roberto Ierusalimschy
8c8ad5f3ff better locality of assignment of table values 2001-08-30 17:56:43 -03:00
Roberto Ierusalimschy
34a09b65f3 some changes of arguments from char to int 2001-08-30 17:55:58 -03:00
Roberto Ierusalimschy
29d883b9bd avoid augmenting alignment of pointers 2001-08-30 17:55:22 -03:00
Roberto Ierusalimschy
b0d5bd8c70 tinsert gets 3d argument instead of last one 2001-08-30 17:54:51 -03:00
Roberto Ierusalimschy
9fca43f5b0 details 2001-08-30 17:54:36 -03:00
Roberto Ierusalimschy
33d820d41d new syntax "= exp" to rpint exp + simplifications 2001-08-30 17:54:02 -03:00
Roberto Ierusalimschy
c3d72096c4 use a table to find (and reuse) constants when parsing 2001-08-27 12:16:28 -03:00
Roberto Ierusalimschy
7afc74ff07 avoid some warnings from strange compilers 2001-08-27 12:14:57 -03:00
Roberto Ierusalimschy
022bf27202 extra parenteses to avoid warnings 2001-08-27 12:13:59 -03:00
Roberto Ierusalimschy
fd40af92e4 the parser is not LL(1) 2001-08-10 17:53:03 -03:00
Roberto Ierusalimschy
0171543704 better optimization options 2001-07-24 19:40:08 -03:00
Roberto Ierusalimschy
ebd1d1f82c no more deprecated code 2001-07-24 19:39:34 -03:00
Roberto Ierusalimschy
04320e04bf warnings from Visual C++ (plus small details) 2001-07-24 18:57:19 -03:00
Roberto Ierusalimschy
5d2d2b1752 the usual stuff 2001-07-24 14:25:30 -03:00
Roberto Ierusalimschy
f34001faa9 details 2001-07-24 14:25:03 -03:00
Roberto Ierusalimschy
95988676d8 small bug when creating AsBc instructions in 16-bit machines 2001-07-24 14:19:07 -03:00
Roberto Ierusalimschy
767abdfdc0 `newtype' returns old tag when given an old name 2001-07-23 16:56:00 -03:00
Roberto Ierusalimschy
45b173cbf8 warnings/details 2001-07-21 21:59:36 -03:00
Roberto Ierusalimschy
a94cba4b88 ready for 4.1 alpha? 2001-07-19 10:36:18 -03:00
Roberto Ierusalimschy
f9f355221f version -> 4.1 alpha 2001-07-19 10:24:18 -03:00
Roberto Ierusalimschy
b3dd9b1bb1 `format' can handle \0 in format string (why not?) 2001-07-17 15:46:49 -03:00
Roberto Ierusalimschy
d8f37bf42a weakregistry has its keys weak, too 2001-07-17 14:54:46 -03:00
Roberto Ierusalimschy
a598804a04 small bug in luaK_self (side effects) 2001-07-17 11:30:44 -03:00
Roberto Ierusalimschy
6c8e652aa6 use macros for 'getc' 2001-07-16 17:24:48 -03:00
Roberto Ierusalimschy
9f25df02d5 new definition for headers of binary files 2001-07-12 16:34:03 -03:00
Roberto Ierusalimschy
ae1cf64348 better names for type-related functions 2001-07-12 15:11:58 -03:00
Roberto Ierusalimschy
a264fd089e small bug in read_chars (fread x eof) 2001-07-12 11:59:14 -03:00
Roberto Ierusalimschy
a3d03ff6b6 bug: error message for `%a' gave wrong line number 2001-07-10 17:02:22 -03:00
Roberto Ierusalimschy
654b16e83a better performance for table operations (mainly for integer indices) 2001-07-05 17:31:14 -03:00
Roberto Ierusalimschy
dc4e0ecdaf new versions by lhf 2001-07-05 17:29:15 -03:00
Roberto Ierusalimschy
9924668931 LUA_MINSTACK has a fixed value 2001-07-05 16:32:42 -03:00
Roberto Ierusalimschy
89ef91a7fe `opmodes' table also generated automatically by mkprint 2001-07-03 14:02:02 -03:00
Roberto Ierusalimschy
00aaee0ae7 details 2001-07-03 14:01:34 -03:00
Roberto Ierusalimschy
18d3e82cfe check C is independent from check B 2001-07-03 14:01:34 -03:00
Roberto Ierusalimschy
2a4afb97c8 new module lopcodes.c for tables describing opcodes 2001-06-28 16:58:57 -03:00
Roberto Ierusalimschy
87a5fae453 tables describing opcodes 2001-06-28 16:58:57 -03:00
Roberto Ierusalimschy
afed6c6864 missing an opcode name 2001-06-28 12:06:20 -03:00
Roberto Ierusalimschy
770954510f rename of kproto' to p' 2001-06-28 11:57:17 -03:00
Roberto Ierusalimschy
b346834a09 new macros for changing numbers 2001-06-28 11:48:44 -03:00
Roberto Ierusalimschy
61a036eaa5 new macro to control format for `read"*n"' 2001-06-28 11:45:44 -03:00
Roberto Ierusalimschy
37f3a1c045 too much optimization to "break" keys in tables; keep them as TObjects... 2001-06-26 10:20:45 -03:00
Roberto Ierusalimschy
9559c111a3 new read' option *u' (read-until) + simpler implementation for `read' 2001-06-22 10:49:42 -03:00
Roberto Ierusalimschy
777061e441 resurect userdata before calling its GC tag method 2001-06-21 13:41:34 -03:00
Roberto Ierusalimschy
fccadba4b5 new reserved words in' and global' 2001-06-20 18:07:57 -03:00
Roberto Ierusalimschy
b940f09984 no more "compat mode" with 3.2 (deprecated functions) 2001-06-20 14:25:30 -03:00
Roberto Ierusalimschy
878979cef7 no more opnames in binary tag methods 2001-06-20 14:22:46 -03:00
Roberto Ierusalimschy
8e586c13fc cleaner way to ensure alignment for strings and userdata 2001-06-15 17:36:57 -03:00
Roberto Ierusalimschy
eadf2aaaff small optimizations 2001-06-15 16:17:33 -03:00
Roberto Ierusalimschy
ae19b2f51e more relaxed rules for syncronized access 2001-06-15 16:16:41 -03:00
Roberto Ierusalimschy
a3fbf5f5fd details 2001-06-13 15:51:20 -03:00
Roberto Ierusalimschy
7fae1c17b1 detail 2001-06-13 11:25:49 -03:00
Roberto Ierusalimschy
89e8303f4e more robust treatment of GC tag methods (now they can create new
objects while running...)
2001-06-12 15:43:13 -03:00
Roberto Ierusalimschy
89c301d180 `(exp)' adjusts exp to 1 result 2001-06-12 11:36:48 -03:00
Roberto Ierusalimschy
186111dc01 unused definition 2001-06-11 11:57:17 -03:00
Roberto Ierusalimschy
0a1b1acdd3 details about opcode parameters 2001-06-11 11:56:42 -03:00
Roberto Ierusalimschy
79acf5ea60 details 2001-06-08 16:20:02 -03:00
Roberto Ierusalimschy
cbc59592ff new definition for luaD_call' and luaD_adjusttop' 2001-06-08 16:01:38 -03:00
Roberto Ierusalimschy
4905fdd135 C++ warning 2001-06-08 13:48:32 -03:00
Roberto Ierusalimschy
0267168675 details. 2001-06-08 09:29:27 -03:00
Roberto Ierusalimschy
ba11831d35 smaller structs for udata and for strings 2001-06-07 12:01:21 -03:00
Roberto Ierusalimschy
190ddd431d details (rests of debug code) 2001-06-07 11:44:51 -03:00
Roberto Ierusalimschy
65c289b046 details 2001-06-07 10:46:29 -03:00
Roberto Ierusalimschy
d5b83ead90 new implementation for userdatas, without `keys' 2001-06-06 15:00:19 -03:00
Roberto Ierusalimschy
da673d31aa user can define extra alignment requirements 2001-06-05 17:01:09 -03:00
Roberto Ierusalimschy
323da72577 weakmode' queries must have an explicit ?' 2001-06-05 16:41:31 -03:00
Roberto Ierusalimschy
943b8f5b18 details 2001-06-05 16:41:24 -03:00
Roberto Ierusalimschy
762d059a13 new implementation for the Virtual Machine 2001-06-05 15:17:01 -03:00
Roberto Ierusalimschy
572a69b6af name changes 2001-04-23 13:35:45 -03:00
Roberto Ierusalimschy
beee01b170 re-implementation of refs through weak tables 2001-04-17 14:35:54 -03:00
Roberto Ierusalimschy
6473f965ca new API functions to load (parse?) a chunk without running it. 2001-04-11 15:39:37 -03:00
Roberto Ierusalimschy
0e0e4a480e first implementation for weak tables 2001-04-11 11:42:41 -03:00
Roberto Ierusalimschy
2a50188269 avoid use of l_char outside INTERNALs (use lua_char instead) 2001-04-06 18:17:37 -03:00
Roberto Ierusalimschy
9aedea6ec8 small bug (when parser fails, there is no function on the stack...) 2001-04-06 16:26:06 -03:00
Roberto Ierusalimschy
a68635a919 list constructors do not adjust last expression 2001-04-06 15:25:00 -03:00
Roberto Ierusalimschy
2112142680 allow syntax << function (x) ... end (...) >> as a statement 2001-04-05 13:49:14 -03:00
Roberto Ierusalimschy
dd3a63c205 new way to handle `profiles' 2001-03-26 11:31:49 -03:00
Roberto Ierusalimschy
cb49b088b6 old signature for lua_open 2001-03-09 15:05:05 -03:00
Roberto Ierusalimschy
c5a23cf01a details 2001-03-07 15:16:22 -03:00
Roberto Ierusalimschy
6048c4f74d better way to link callinfo's and stack 2001-03-07 15:09:25 -03:00
Roberto Ierusalimschy
5e870f86a2 optimization for tailcall does not seem to pay itself 2001-03-07 10:22:55 -03:00
Roberto Ierusalimschy
f81b8adb3f string [[...]] ignores initial \n 2001-03-07 09:49:37 -03:00
Roberto Ierusalimschy
2b2267069b new functions pack' and unpack' 2001-03-07 09:43:52 -03:00
Roberto Ierusalimschy
72d3d155b0 detail 2001-03-07 09:27:06 -03:00
Roberto Ierusalimschy
6d4db86888 open functions are lua_Cfunctions 2001-03-06 17:09:38 -03:00
Roberto Ierusalimschy
e9a3820370 sizeof(string) != strlen(string)+1 when sizeof(char) != 1 2001-03-06 11:46:54 -03:00
Roberto Ierusalimschy
9e8a46daa2 details (identation) 2001-03-02 14:40:08 -03:00
Roberto Ierusalimschy
7b84f9e65c lower-case for macros with arguments 2001-03-02 14:27:50 -03:00
Roberto Ierusalimschy
1e40b4dc61 buffer should be void *, as char now is not that neutral...
+ little bug in pointer arithmetic
2001-02-23 17:32:32 -03:00
Roberto Ierusalimschy
dfd7ce74cf buffer should be void *, as char now is not that neutral... 2001-02-23 17:32:16 -03:00
Roberto Ierusalimschy
8399df5dcf detail 2001-02-23 17:31:37 -03:00
Roberto Ierusalimschy
d2a64bb6d4 `llimits' may need definitions from LUA_USER_H 2001-02-23 17:28:56 -03:00
Roberto Ierusalimschy
a90f06dcd8 `atoi' does not have a wide-char equivalent 2001-02-23 17:28:26 -03:00
Roberto Ierusalimschy
35023355f2 details for wchar 2001-02-23 14:28:12 -03:00
Roberto Ierusalimschy
39b7978329 first (big) step to support wide chars 2001-02-23 14:17:25 -03:00
Roberto Ierusalimschy
d164e2294f _ERRORMESSAGE called through get global tag method 2001-02-23 10:38:56 -03:00
Roberto Ierusalimschy
2cc94ac81b avoid name clash with `sys/stat' 2001-02-23 10:38:56 -03:00
Roberto Ierusalimschy
5f37134e64 avoid '...' and "..." inside comments 2001-02-22 15:59:59 -03:00
Roberto Ierusalimschy
52ee91dd73 better encapsulation of some types 2001-02-22 14:15:18 -03:00
Roberto Ierusalimschy
191fd35f0a warnings from Visual C++ 2001-02-21 13:52:09 -03:00
Roberto Ierusalimschy
d6978d03e1 small bug in testing (pushuserdata needs some memory to work...) 2001-02-21 13:51:25 -03:00
Roberto Ierusalimschy
68b08848d4 `dostring' now is safe to run binary code. 2001-02-20 15:29:54 -03:00
Roberto Ierusalimschy
888f91fa24 code check for upvalues 2001-02-20 15:28:11 -03:00
Roberto Ierusalimschy
c1db0b2bf1 detail 2001-02-20 15:18:00 -03:00
Roberto Ierusalimschy
099442c41f better separation between basic types 2001-02-20 15:15:33 -03:00
Roberto Ierusalimschy
27600fe87a better strucuture for code checker 2001-02-16 15:58:27 -02:00
Roberto Ierusalimschy
f8509668dc details. 2001-02-14 15:38:45 -02:00
Roberto Ierusalimschy
40f4e931f3 more liberal syntax for expressions 2001-02-14 15:19:28 -02:00
Roberto Ierusalimschy
29371ecfe8 better way to handle multi-line input (with concat) 2001-02-14 15:19:01 -02:00
Roberto Ierusalimschy
5d9b8b7cdc more secure definition for lua_concat 2001-02-14 15:04:11 -02:00
Roberto Ierusalimschy
1c2501fad4 tests for string alignment 2001-02-13 14:52:01 -02:00
Roberto Ierusalimschy
a4ae1475e3 details (smaller code) 2001-02-13 14:17:53 -02:00
Roberto Ierusalimschy
b3da4ee907 checking consistency of jumps. 2001-02-12 17:54:50 -02:00
Roberto Ierusalimschy
3c649ce123 checking consistency of jumps (and some other details) 2001-02-12 17:54:28 -02:00
Roberto Ierusalimschy
95da574dbc some compilers (wrongly) complain about that 2001-02-12 17:21:19 -02:00
Roberto Ierusalimschy
255052b6c6 better API checks 2001-02-12 13:42:44 -02:00
Roberto Ierusalimschy
1bdc156b52 details 2001-02-12 11:04:19 -02:00
Roberto Ierusalimschy
03d8a9bf0d details 2001-02-09 18:29:33 -02:00
Roberto Ierusalimschy
d2e340f467 string pointers are always fully aligned 2001-02-09 18:22:29 -02:00
Roberto Ierusalimschy
6875fdc8be new semantics for pushuserdata (no more different userdatas with same value) 2001-02-09 17:53:16 -02:00
Roberto Ierusalimschy
dc17a9cc24 new semantics for pushuserdata 2001-02-09 17:52:54 -02:00
Roberto Ierusalimschy
81e63f75c0 `tostring' uses type names (when available) 2001-02-09 17:52:24 -02:00
Roberto Ierusalimschy
c81404cae5 first version of code verification 2001-02-09 16:37:33 -02:00
Roberto Ierusalimschy
b6ce590433 details 2001-02-09 16:07:47 -02:00
Roberto Ierusalimschy
e70e6a3b7a <read(0)> tests for EOF 2001-02-09 14:25:50 -02:00
Roberto Ierusalimschy
6548bf7462 warnings from Visual C 2001-02-08 09:19:10 -02:00
Roberto Ierusalimschy
7178a5e34a new way to handle top x L->top 2001-02-07 16:13:49 -02:00
Roberto Ierusalimschy
322b7b5fc5 easier to add new initialization functions 2001-02-06 16:18:58 -02:00
Roberto Ierusalimschy
1f917e709c better use of extra include files (both for tests and for old_ansi) 2001-02-06 14:01:29 -02:00
Roberto Ierusalimschy
d444153dbe ESC (which starts precompiled code) in C is \33, not \27 2001-02-06 11:59:29 -02:00
Roberto Ierusalimschy
a894499566 details 2001-02-05 17:08:01 -02:00
Roberto Ierusalimschy
d1fc6244f0 extended syntax to allow function a.b.c (x) 2001-02-05 15:48:52 -02:00
Roberto Ierusalimschy
7e3d3e1f70 details 2001-02-02 17:02:40 -02:00
Roberto Ierusalimschy
1f9e3731d1 back to the basics (well-behaved variant record...) 2001-02-02 14:32:00 -02:00
Roberto Ierusalimschy
42224ca553 loop of 'dostring' may never reclaim memory 2001-02-02 14:23:20 -02:00
Roberto Ierusalimschy
426d3e43bd lock/unlock may use L + better structure for internal debug stuff 2001-02-02 13:13:05 -02:00
Roberto Ierusalimschy
8823f371a2 new header to put together debug-related declarations 2001-02-02 13:12:25 -02:00
Roberto Ierusalimschy
e506b864cd no need for tags in boxed values :-( 2001-02-01 15:40:48 -02:00
Roberto Ierusalimschy
9a231afa97 top must be updated when there is any error 2001-02-01 15:39:55 -02:00
Roberto Ierusalimschy
4ab6acacdf better control of relationship top x L->top 2001-02-01 14:03:38 -02:00
Roberto Ierusalimschy
6858763994 bug in lua_pushuserdata(L, NULL) 2001-02-01 11:56:49 -02:00
Roberto Ierusalimschy
b68fb7f62e `assert' returns its first argument 2001-01-31 17:53:01 -02:00
Roberto Ierusalimschy
60ff79451c detail in error message 2001-01-31 11:13:17 -02:00
Roberto Ierusalimschy
44a53df688 better to avoid dirty tricks 2001-01-30 17:48:37 -02:00
Roberto Ierusalimschy
63a822c8e1 all boxed types start with their tags 2001-01-29 17:34:02 -02:00
Roberto Ierusalimschy
09def5da44 small corrections 2001-01-29 17:33:55 -02:00
Roberto Ierusalimschy
6b71a9cfe5 smaller tables for machines with 8-bit alignment 2001-01-29 15:17:26 -02:00
Roberto Ierusalimschy
fa8c44b510 avoid the use of "reopen" (not that standard) 2001-01-29 13:35:17 -02:00
Roberto Ierusalimschy
3b6f8bfbe6 simpler implementation of for loops 2001-01-29 13:26:40 -02:00
Roberto Ierusalimschy
caf01b5bfa better implementation for list "for" 2001-01-29 11:14:49 -02:00
Roberto Ierusalimschy
ca1f28b829 avoid side-effects on macros that may use twice their arguments 2001-01-26 16:43:22 -02:00
Roberto Ierusalimschy
b82242d4c4 detail 2001-01-26 13:58:50 -02:00
Roberto Ierusalimschy
ac390020e9 optimizations based on all types but number and nil are pointers 2001-01-26 12:16:35 -02:00
Roberto Ierusalimschy
9b45439860 details 2001-01-26 12:16:24 -02:00
Roberto Ierusalimschy
7959f3aebb easier way to erase 'dead' keys 2001-01-26 11:18:00 -02:00
Roberto Ierusalimschy
bce6572579 new macros + new names to facilitate compilation of threaded version 2001-01-26 09:45:51 -02:00
Roberto Ierusalimschy
a53d9b66ca first implementation for type names 2001-01-25 14:45:36 -02:00
Roberto Ierusalimschy
c8559e3c8d a small optimization 2001-01-24 14:20:54 -02:00
Roberto Ierusalimschy
71ae4801d6 macros LUA_ENTRY/LUA_EXIT to control exclusive access to Lua core 2001-01-24 13:45:33 -02:00
Roberto Ierusalimschy
6fda6a5302 support for multiple stacks sharing the same global environment 2001-01-22 16:01:38 -02:00
Roberto Ierusalimschy
4ac58853dc thead-specific state separated from "global" state 2001-01-19 11:20:30 -02:00
Roberto Ierusalimschy
f2c451d745 all accesses to TObjects done through macros 2001-01-18 13:59:09 -02:00
Roberto Ierusalimschy
619edfd9e4 details 2001-01-15 16:07:56 -02:00
Roberto Ierusalimschy
a04de4f0ad no more END opcode 2001-01-15 14:13:24 -02:00
Roberto Ierusalimschy
a653d93a43 string comparison only needs to test for "less than" 2001-01-11 16:59:32 -02:00
Roberto Ierusalimschy
321c7fb6f8 details 2001-01-11 16:59:20 -02:00
Roberto Ierusalimschy
dabb19fc17 specialized versions for luaH_set (numbers and strings) 2001-01-10 16:56:11 -02:00
Roberto Ierusalimschy
08496eea8b small changes in lstring 2001-01-10 15:41:50 -02:00
Roberto Ierusalimschy
4ff5545709 new macro pushliteral 2001-01-10 14:58:11 -02:00
Roberto Ierusalimschy
595e449537 tighter size for error buffers 2001-01-10 14:40:56 -02:00
Roberto Ierusalimschy
a907aeeb1e general corrections 2000-12-28 15:25:45 -02:00
Roberto Ierusalimschy
76f62fc5a1 correct size only after malloc success 2000-12-28 10:59:41 -02:00
Roberto Ierusalimschy
0183b8030c `free' gets size of the block: complete control over memory use 2000-12-28 10:55:41 -02:00
Roberto Ierusalimschy
8c49e19865 explicit control of size for growing vectors 2000-12-26 16:46:09 -02:00
Roberto Ierusalimschy
6af005ec20 bug: when `read' fails it must return nil (and not no value) 2000-12-22 15:32:28 -02:00
Roberto Ierusalimschy
f8a0fd268e temporary version 2000-12-22 14:58:41 -02:00
Roberto Ierusalimschy
0066bbbb0b details 2000-12-22 14:57:46 -02:00
Roberto Ierusalimschy
1db05793a0 time' does not need to correct its table argument (use date' for that) 2000-12-22 14:57:13 -02:00
Roberto Ierusalimschy
af97be026b new function for time and date 2000-12-18 11:42:19 -02:00
Roberto Ierusalimschy
cce8ebd306 obsolete `format' option (d$). 2000-12-18 11:41:41 -02:00
Roberto Ierusalimschy
4894c27962 lua_Number defined in lua.h (1st version) 2000-12-04 16:33:40 -02:00
Roberto Ierusalimschy
10ac68c648 first implementation for position captures 2000-12-04 12:43:06 -02:00
Roberto Ierusalimschy
01b00cc292 better control over extensions of char/short to int 2000-11-30 16:50:47 -02:00
Roberto Ierusalimschy
fc7b167ae0 BUG: parser does not accept a ;' after a return' 2000-11-29 09:57:42 -02:00
Roberto Ierusalimschy
96253ed8ce better support for 64-bit machines (avoid excessive use of longs) 2000-11-24 15:39:56 -02:00
Roberto Ierusalimschy
35d6b15057 some cleaning 2000-11-23 11:49:35 -02:00
Roberto Ierusalimschy
22914afab3 avoid the use of (non const) static data 2000-11-23 11:47:39 -02:00
63 changed files with 18371 additions and 11601 deletions

2083
bugs

File diff suppressed because it is too large Load Diff

1260
lapi.c

File diff suppressed because it is too large Load Diff

15
lapi.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.h,v 1.19 2000/08/28 17:57:04 roberto Exp roberto $
** $Id: lapi.h,v 2.6 2009/08/31 14:26:28 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -8,10 +8,17 @@
#define lapi_h
#include "lobject.h"
#include "llimits.h"
#include "lstate.h"
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
"stack overflow");}
#define adjustresults(L,nres) \
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
"not enough elements in the stack")
TObject *luaA_index (lua_State *L, int index);
void luaA_pushobject (lua_State *L, const TObject *o);
#endif

903
lauxlib.c

File diff suppressed because it is too large Load Diff

165
lauxlib.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.29 2000/10/27 16:15:53 roberto Exp roberto $
** $Id: lauxlib.h,v 1.112 2010/11/16 17:43:29 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -15,32 +15,81 @@
#include "lua.h"
#ifndef LUALIB_API
#define LUALIB_API extern
#endif
/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)
struct luaL_reg {
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
};
} luaL_Reg;
LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n);
LUALIB_API void luaL_argerror (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *luaL_check_lstr (lua_State *L, int numArg, size_t *len);
LUALIB_API const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, size_t *len);
LUALIB_API double luaL_check_number (lua_State *L, int numArg);
LUALIB_API double luaL_opt_number (lua_State *L, int numArg, double def);
LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM)
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg);
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
LUALIB_API void luaL_checkany (lua_State *L, int narg);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...);
LUALIB_API int luaL_findstring (const char *name, const char *const list[]);
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);
LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
lua_Unsigned def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);
/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API int (luaL_len) (lua_State *L, int idx);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
LUALIB_API void (luaL_findtable) (lua_State *L, int idx, const char *fname);
LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
const char *msg, int level);
LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
/*
** ===============================================================
@@ -48,15 +97,32 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]);
** ===============================================================
*/
#define luaL_arg_check(L, cond,numarg,extramsg) if (!(cond)) \
luaL_argerror(L, numarg,extramsg)
#define luaL_check_string(L,n) (luaL_check_lstr(L, (n), NULL))
#define luaL_opt_string(L,n,d) (luaL_opt_lstr(L, (n), (d), NULL))
#define luaL_check_int(L,n) ((int)luaL_check_number(L, n))
#define luaL_check_long(L,n) ((long)luaL_check_number(L, n))
#define luaL_opt_int(L,n,d) ((int)luaL_opt_number(L, n,d))
#define luaL_opt_long(L,n,d) ((long)luaL_opt_number(L, n,d))
#define luaL_openl(L,a) luaL_openlib(L, a, (sizeof(a)/sizeof(a[0])))
#define luaL_newlibtable(L,l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
/*
@@ -65,36 +131,45 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]);
** =======================================================
*/
#ifndef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE BUFSIZ
#endif
typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int level;
char *b; /* buffer address */
size_t size; /* buffer size */
size_t n; /* number of characters in buffer */
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
char initb[LUAL_BUFFERSIZE]; /* initial buffer */
} luaL_Buffer;
#define luaL_putchar(B,c) \
((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))
#define luaL_addsize(B,n) ((B)->p += (n))
#define luaL_addchar(B,c) \
((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
((B)->b[(B)->n++] = (c)))
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
LUALIB_API void luaL_addvalue (luaL_Buffer *B);
LUALIB_API void luaL_pushresult (luaL_Buffer *B);
#define luaL_addsize(B,s) ((B)->n += (s))
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
/* }====================================================== */
/* compatibility with old module system */
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
int sizehint);
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
#endif

File diff suppressed because it is too large Load Diff

163
lbitlib.c Normal file
View File

@@ -0,0 +1,163 @@
/*
** $Id: lbitlib.c,v 1.12 2010/11/22 16:39:20 roberto Exp roberto $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
#define lbitlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/* number of bits to consider in a number */
#define NBITS 32
#define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1))
/* mask to trim extra bits */
#define trim(x) ((x) & ALLONES)
typedef lua_Unsigned b_uint;
#define getuintarg(L,arg) luaL_checkunsigned(L,arg)
static b_uint andaux (lua_State *L) {
int i, n = lua_gettop(L);
b_uint r = ~(b_uint)0;
for (i = 1; i <= n; i++)
r &= getuintarg(L, i);
return trim(r);
}
static int b_and (lua_State *L) {
b_uint r = andaux(L);
lua_pushunsigned(L, r);
return 1;
}
static int b_test (lua_State *L) {
b_uint r = andaux(L);
lua_pushboolean(L, r != 0);
return 1;
}
static int b_or (lua_State *L) {
int i, n = lua_gettop(L);
b_uint r = 0;
for (i = 1; i <= n; i++)
r |= getuintarg(L, i);
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_xor (lua_State *L) {
int i, n = lua_gettop(L);
b_uint r = 0;
for (i = 1; i <= n; i++)
r ^= getuintarg(L, i);
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_not (lua_State *L) {
b_uint r = ~getuintarg(L, 1);
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_shift (lua_State *L, b_uint r, int i) {
if (i < 0) { /* shift right? */
i = -i;
r = trim(r);
if (i >= NBITS) r = 0;
else r >>= i;
}
else { /* shift left */
if (i >= NBITS) r = 0;
else r <<= i;
r = trim(r);
}
lua_pushunsigned(L, r);
return 1;
}
static int b_lshift (lua_State *L) {
return b_shift(L, getuintarg(L, 1), luaL_checkint(L, 2));
}
static int b_rshift (lua_State *L) {
return b_shift(L, getuintarg(L, 1), -luaL_checkint(L, 2));
}
static int b_arshift (lua_State *L) {
b_uint r = getuintarg(L, 1);
int i = luaL_checkint(L, 2);
if (i < 0 || !(r & ((b_uint)1 << (NBITS - 1))))
return b_shift(L, r, -i);
else { /* arithmetic shift for 'negative' number */
if (i >= NBITS) r = ALLONES;
else
r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
lua_pushunsigned(L, r);
return 1;
}
}
static int b_rot (lua_State *L, int i) {
b_uint r = getuintarg(L, 1);
i &= (NBITS - 1); /* i = i % NBITS */
r = trim(r);
r = (r << i) | (r >> (NBITS - i));
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_lrot (lua_State *L) {
return b_rot(L, luaL_checkint(L, 2));
}
static int b_rrot (lua_State *L) {
return b_rot(L, -luaL_checkint(L, 2));
}
static const luaL_Reg bitlib[] = {
{"arshift", b_arshift},
{"band", b_and},
{"bnot", b_not},
{"bor", b_or},
{"bxor", b_xor},
{"lrotate", b_lrot},
{"lshift", b_lshift},
{"rrotate", b_rrot},
{"rshift", b_rshift},
{"btest", b_test},
{NULL, NULL}
};
LUAMOD_API int luaopen_bit32 (lua_State *L) {
luaL_newlib(L, bitlib);
return 1;
}

1415
lcode.c

File diff suppressed because it is too large Load Diff

77
lcode.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.h,v 1.15 2000/06/28 20:20:36 roberto Exp roberto $
** $Id: lcode.h,v 1.54 2010/04/17 12:46:32 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -21,50 +21,63 @@
/*
** grep "ORDER OPR" if you change these enums
** grep "ORDER OPR" if you change these enums (ORDER OP)
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT,
OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
OPR_EQ, OPR_LT, OPR_LE,
OPR_NE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR,
OPR_NOBINOPR
} BinOpr;
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
enum Mode {iO, iU, iS, iAB}; /* instruction format */
#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
#define VD 100 /* flag for variable delta */
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
extern const struct OpProperties {
char mode;
unsigned char push;
unsigned char pop;
} luaK_opproperties[];
#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
void luaK_error (LexState *ls, const char *msg);
int luaK_code0 (FuncState *fs, OpCode o);
int luaK_code1 (FuncState *fs, OpCode o, int arg1);
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
int luaK_jump (FuncState *fs);
void luaK_patchlist (FuncState *fs, int list, int target);
void luaK_concat (FuncState *fs, int *l1, int l2);
void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
int luaK_getlabel (FuncState *fs);
void luaK_deltastack (FuncState *fs, int delta);
void luaK_kstr (LexState *ls, int c);
void luaK_number (FuncState *fs, Number f);
void luaK_adjuststack (FuncState *fs, int n);
int luaK_lastisopen (FuncState *fs);
void luaK_setcallreturns (FuncState *fs, int nresults);
void luaK_tostack (LexState *ls, expdesc *v, int onlyone);
void luaK_storevar (LexState *ls, const expdesc *var);
void luaK_prefix (LexState *ls, UnOpr op, expdesc *v);
void luaK_infix (LexState *ls, BinOpr op, expdesc *v);
void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2);
#define luaK_codek(fs,reg,k) luaK_codeABxX(fs, OP_LOADK, reg, k)
LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
LUAI_FUNC int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_jump (FuncState *fs);
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
LUAI_FUNC int luaK_getlabel (FuncState *fs);
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
expdesc *v2, int line);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
#endif

154
lcorolib.c Normal file
View File

@@ -0,0 +1,154 @@
/*
** $Id: lcorolib.c,v 1.1 2010/06/10 21:30:26 roberto Exp roberto $
** Coroutine Library
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#define lcorolib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int auxresume (lua_State *L, lua_State *co, int narg) {
int status;
if (!lua_checkstack(co, narg)) {
lua_pushliteral(L, "too many arguments to resume");
return -1; /* error flag */
}
if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
lua_xmove(L, co, narg);
status = lua_resume(co, narg);
if (status == LUA_OK || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres + 1)) {
lua_pop(co, nres); /* remove results anyway */
lua_pushliteral(L, "too many results to resume");
return -1; /* error flag */
}
lua_xmove(co, L, nres); /* move yielded values */
return nres;
}
else {
lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
}
static int luaB_coresume (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
int r;
luaL_argcheck(L, co, 1, "coroutine expected");
r = auxresume(L, co, lua_gettop(L) - 1);
if (r < 0) {
lua_pushboolean(L, 0);
lua_insert(L, -2);
return 2; /* return false + error message */
}
else {
lua_pushboolean(L, 1);
lua_insert(L, -(r + 1));
return r + 1; /* return true + `resume' returns */
}
}
static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) {
if (lua_isstring(L, -1)) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
}
lua_error(L); /* propagate error */
}
return r;
}
static int luaB_cocreate (lua_State *L) {
lua_State *NL = lua_newthread(L);
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_pushvalue(L, 1); /* move function to top */
lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
}
static int luaB_cowrap (lua_State *L) {
luaB_cocreate(L);
lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
}
static int luaB_yield (lua_State *L) {
return lua_yield(L, lua_gettop(L));
}
static int luaB_costatus (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
luaL_argcheck(L, co, 1, "coroutine expected");
if (L == co) lua_pushliteral(L, "running");
else {
switch (lua_status(co)) {
case LUA_YIELD:
lua_pushliteral(L, "suspended");
break;
case LUA_OK: {
lua_Debug ar;
if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
lua_pushliteral(L, "normal"); /* it is running */
else if (lua_gettop(co) == 0)
lua_pushliteral(L, "dead");
else
lua_pushliteral(L, "suspended"); /* initial state */
break;
}
default: /* some error occurred */
lua_pushliteral(L, "dead");
break;
}
}
return 1;
}
static int luaB_corunning (lua_State *L) {
int ismain = lua_pushthread(L);
lua_pushboolean(L, ismain);
return 2;
}
static const luaL_Reg co_funcs[] = {
{"create", luaB_cocreate},
{"resume", luaB_coresume},
{"running", luaB_corunning},
{"status", luaB_costatus},
{"wrap", luaB_cowrap},
{"yield", luaB_yield},
{NULL, NULL}
};
LUAMOD_API int luaopen_coroutine (lua_State *L) {
luaL_newlib(L, co_funcs);
return 1;
}

45
lctype.c Normal file
View File

@@ -0,0 +1,45 @@
/*
** $Id: lctype.c,v 1.7 2009/05/27 16:51:15 roberto Exp roberto $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
#include <limits.h>
#include "lctype.h"
LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
0x00, /* EOZ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x25,
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
0x25, 0x25, 0x25, 0x04, 0x04, 0x04, 0x04, 0x05,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

50
lctype.h Normal file
View File

@@ -0,0 +1,50 @@
/*
** $Id: lctype.h,v 1.7 2009/05/27 16:51:15 roberto Exp roberto $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
#ifndef lctype_h
#define lctype_h
#include <limits.h>
#include "lua.h"
#include "llimits.h"
#define ALPHABIT 0
#define DIGITBIT 1
#define PRINTBIT 2
#define SPACEBIT 3
#define XDIGITBIT 4
#define UPPERBIT 5
#define MASK(B) (1 << (B))
/*
** add 1 to char to allow index -1 (EOZ)
*/
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
/*
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
*/
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisupper(c) testprop(c, MASK(UPPERBIT))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
/* one more entry for 0 and one more for -1 (EOZ) */
LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
#endif

477
ldblib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldblib.c,v 1.28 2000/11/06 13:19:08 roberto Exp roberto $
** $Id: ldblib.c,v 1.125 2010/11/10 18:06:10 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -9,180 +9,397 @@
#include <stdlib.h>
#include <string.h>
#define ldblib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "luadebug.h"
#include "lualib.h"
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
}
static int db_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L); /* no metatable */
}
return 1;
}
static int db_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
lua_settop(L, 2);
lua_pushboolean(L, lua_setmetatable(L, 1));
return 1;
}
static int db_getuservalue (lua_State *L) {
if (lua_type(L, 1) != LUA_TUSERDATA)
lua_pushnil(L);
else
lua_getuservalue(L, 1);
return 1;
}
static int db_setuservalue (lua_State *L) {
if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
luaL_argerror(L, 1, "full userdata expected, got light userdata");
luaL_checktype(L, 1, LUA_TUSERDATA);
if (!lua_isnoneornil(L, 2))
luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2);
lua_setuservalue(L, 1);
return 1;
}
static void settabss (lua_State *L, const char *i, const char *v) {
lua_pushstring(L, i);
lua_pushstring(L, v);
lua_settable(L, -3);
lua_setfield(L, -2, i);
}
static void settabsi (lua_State *L, const char *i, int v) {
lua_pushstring(L, i);
lua_pushnumber(L, v);
lua_settable(L, -3);
lua_pushinteger(L, v);
lua_setfield(L, -2, i);
}
static int getinfo (lua_State *L) {
static void settabsb (lua_State *L, const char *i, int v) {
lua_pushboolean(L, v);
lua_setfield(L, -2, i);
}
static lua_State *getthread (lua_State *L, int *arg) {
if (lua_isthread(L, 1)) {
*arg = 1;
return lua_tothread(L, 1);
}
else {
*arg = 0;
return L;
}
}
static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
if (L == L1) {
lua_pushvalue(L, -2);
lua_remove(L, -3);
}
else
lua_xmove(L1, L, 1);
lua_setfield(L, -2, fname);
}
static int db_getinfo (lua_State *L) {
lua_Debug ar;
const char *options = luaL_opt_string(L, 2, "flnSu");
char buff[20];
if (lua_isnumber(L, 1)) {
if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
int arg;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnStu");
if (lua_isnumber(L, arg+1)) {
if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
}
else if (lua_isfunction(L, 1)) {
lua_pushvalue(L, 1);
sprintf(buff, ">%.10s", options);
options = buff;
else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
lua_xmove(L, L1, 1);
}
else
luaL_argerror(L, 1, "function or level expected");
if (!lua_getinfo(L, options, &ar))
luaL_argerror(L, 2, "invalid option");
lua_newtable(L);
for (; *options; options++) {
switch (*options) {
case 'S':
settabss(L, "source", ar.source);
if (ar.source)
settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined);
settabss(L, "what", ar.what);
break;
case 'l':
settabsi(L, "currentline", ar.currentline);
break;
case 'u':
settabsi(L, "nups", ar.nups);
break;
case 'n':
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
break;
case 'f':
lua_pushstring(L, "func");
lua_pushvalue(L, -3);
lua_settable(L, -3);
break;
}
return luaL_argerror(L, arg+1, "function or level expected");
if (!lua_getinfo(L1, options, &ar))
return luaL_argerror(L, arg+2, "invalid option");
lua_createtable(L, 0, 2);
if (strchr(options, 'S')) {
settabss(L, "source", ar.source);
settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined);
settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what);
}
if (strchr(options, 'l'))
settabsi(L, "currentline", ar.currentline);
if (strchr(options, 'u')) {
settabsi(L, "nups", ar.nups);
settabsi(L, "nparams", ar.nparams);
settabsb(L, "isvararg", ar.isvararg);
}
if (strchr(options, 'n')) {
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
}
if (strchr(options, 't'))
settabsb(L, "istailcall", ar.istailcall);
if (strchr(options, 'L'))
treatstackoption(L, L1, "activelines");
if (strchr(options, 'f'))
treatstackoption(L, L1, "func");
return 1; /* return table */
}
static int getlocal (lua_State *L) {
static int db_getlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
luaL_argerror(L, 1, "level out of range");
name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
if (name) {
lua_pushstring(L, name);
lua_pushvalue(L, -2);
return 2;
}
else {
lua_pushnil(L);
int nvar = luaL_checkint(L, arg+2); /* local-variable index */
if (lua_isfunction(L, arg + 1)) { /* function argument? */
lua_pushvalue(L, arg + 1); /* push function */
lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
return 1;
}
}
static int setlocal (lua_State *L) {
lua_Debug ar;
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
luaL_argerror(L, 1, "level out of range");
luaL_checkany(L, 3);
lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
return 1;
}
/* dummy variables (to define unique addresses) */
static char key1, key2;
#define KEY_CALLHOOK (&key1)
#define KEY_LINEHOOK (&key2)
static void hookf (lua_State *L, void *key) {
lua_getregistry(L);
lua_pushuserdata(L, key);
lua_gettable(L, -2);
if (lua_isfunction(L, -1)) {
lua_pushvalue(L, 1);
lua_rawcall(L, 1, 0);
else { /* stack-level argument */
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
name = lua_getlocal(L1, &ar, nvar);
if (name) {
lua_xmove(L1, L, 1); /* push local value */
lua_pushstring(L, name); /* push name */
lua_pushvalue(L, -2); /* re-order */
return 2;
}
else {
lua_pushnil(L); /* no name (nor value) */
return 1;
}
}
else
lua_pop(L, 1); /* pop result from gettable */
lua_pop(L, 1); /* pop table */
}
static void callf (lua_State *L, lua_Debug *ar) {
lua_pushstring(L, ar->event);
hookf(L, KEY_CALLHOOK);
}
static void linef (lua_State *L, lua_Debug *ar) {
lua_pushnumber(L, ar->currentline);
hookf(L, KEY_LINEHOOK);
}
static void sethook (lua_State *L, void *key, lua_Hook hook,
lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) {
lua_settop(L, 1);
if (lua_isnil(L, 1))
(*sethookf)(L, NULL);
else if (lua_isfunction(L, 1))
(*sethookf)(L, hook);
else
luaL_argerror(L, 1, "function expected");
lua_getregistry(L);
lua_pushuserdata(L, key);
lua_pushvalue(L, -1); /* dup key */
lua_gettable(L, -3); /* get old value */
lua_pushvalue(L, -2); /* key (again) */
lua_pushvalue(L, 1);
lua_settable(L, -5); /* set new value */
}
static int setcallhook (lua_State *L) {
sethook(L, KEY_CALLHOOK, callf, lua_setcallhook);
static int db_setlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
lua_xmove(L, L1, 1);
lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
return 1;
}
static int setlinehook (lua_State *L) {
sethook(L, KEY_LINEHOOK, linef, lua_setlinehook);
static int auxupvalue (lua_State *L, int get) {
const char *name;
int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
lua_insert(L, -(get+1));
return get + 1;
}
static int db_getupvalue (lua_State *L) {
return auxupvalue(L, 1);
}
static int db_setupvalue (lua_State *L) {
luaL_checkany(L, 3);
return auxupvalue(L, 0);
}
static int checkupval (lua_State *L, int argf, int argnup) {
lua_Debug ar;
int nup = luaL_checkint(L, argnup);
luaL_checktype(L, argf, LUA_TFUNCTION);
lua_pushvalue(L, argf);
lua_getinfo(L, ">u", &ar);
luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index");
return nup;
}
static int db_upvalueid (lua_State *L) {
int n = checkupval(L, 1, 2);
lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
return 1;
}
static const struct luaL_reg dblib[] = {
{"getlocal", getlocal},
{"getinfo", getinfo},
{"setcallhook", setcallhook},
{"setlinehook", setlinehook},
{"setlocal", setlocal}
static int db_upvaluejoin (lua_State *L) {
int n1 = checkupval(L, 1, 2);
int n2 = checkupval(L, 3, 4);
luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
lua_upvaluejoin(L, 1, n1, 3, n2);
return 0;
}
static const char KEY_HOOK = 'h';
static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail call"};
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, L);
lua_rawget(L, -2);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0)
lua_pushinteger(L, ar->currentline);
else lua_pushnil(L);
lua_assert(lua_getinfo(L, "lS", ar));
lua_call(L, 2, 0);
}
}
static int makemask (const char *smask, int count) {
int mask = 0;
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
if (count > 0) mask |= LUA_MASKCOUNT;
return mask;
}
static char *unmakemask (int mask, char *smask) {
int i = 0;
if (mask & LUA_MASKCALL) smask[i++] = 'c';
if (mask & LUA_MASKRET) smask[i++] = 'r';
if (mask & LUA_MASKLINE) smask[i++] = 'l';
smask[i] = '\0';
return smask;
}
static void gethooktable (lua_State *L) {
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
lua_createtable(L, 0, 1);
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
}
}
static int db_sethook (lua_State *L) {
int arg, mask, count;
lua_Hook func;
lua_State *L1 = getthread(L, &arg);
if (lua_isnoneornil(L, arg+1)) {
lua_settop(L, arg+1);
func = NULL; mask = 0; count = 0; /* turn off hooks */
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
gethooktable(L);
lua_pushlightuserdata(L, L1);
lua_pushvalue(L, arg+1);
lua_rawset(L, -3); /* set new hook */
lua_pop(L, 1); /* remove hook table */
lua_sethook(L1, func, mask, count); /* set hooks */
return 0;
}
static int db_gethook (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
char buff[5];
int mask = lua_gethookmask(L1);
lua_Hook hook = lua_gethook(L1);
if (hook != NULL && hook != hookf) /* external hook? */
lua_pushliteral(L, "external hook");
else {
gethooktable(L);
lua_pushlightuserdata(L, L1);
lua_rawget(L, -2); /* get hook */
lua_remove(L, -2); /* remove hook table */
}
lua_pushstring(L, unmakemask(mask, buff));
lua_pushinteger(L, lua_gethookcount(L1));
return 3;
}
static int db_debug (lua_State *L) {
for (;;) {
char buffer[250];
luai_writestringerror("%s", "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
lua_pcall(L, 0, 0, 0))
luai_writestringerror("%s\n", lua_tostring(L, -1));
lua_settop(L, 0); /* remove eventual returns */
}
}
static int db_traceback (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
const char *msg = lua_tostring(L, arg + 1);
if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
lua_pushvalue(L, arg + 1); /* return it untouched */
else {
int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
luaL_traceback(L, L1, msg, level);
}
return 1;
}
static const luaL_Reg dblib[] = {
{"debug", db_debug},
{"getuservalue", db_getuservalue},
{"gethook", db_gethook},
{"getinfo", db_getinfo},
{"getlocal", db_getlocal},
{"getregistry", db_getregistry},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
{"upvaluejoin", db_upvaluejoin},
{"upvalueid", db_upvalueid},
{"setuservalue", db_setuservalue},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
{"traceback", db_traceback},
{NULL, NULL}
};
LUALIB_API void lua_dblibopen (lua_State *L) {
luaL_openl(L, dblib);
LUAMOD_API int luaopen_debug (lua_State *L) {
luaL_newlib(L, dblib);
return 1;
}

755
ldebug.c
View File

@@ -1,11 +1,17 @@
/*
** $Id: ldebug.c,v 1.49 2000/10/27 11:39:52 roberto Exp roberto $
** $Id: ldebug.c,v 2.73 2010/09/07 19:21:39 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#define ldebug_c
#define LUA_CORE
#include "lua.h"
@@ -20,269 +26,242 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "luadebug.h"
#include "lvm.h"
static const char *getfuncname (lua_State *L, StkId f, const char **name);
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
static void setnormalized (TObject *d, const TObject *s) {
if (ttype(s) == LUA_TMARK) {
clvalue(d) = infovalue(s)->func;
ttype(d) = LUA_TFUNCTION;
static int currentpc (CallInfo *ci) {
lua_assert(isLua(ci));
return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
}
static int currentline (CallInfo *ci) {
return getfuncline(ci_func(ci)->l.p, currentpc(ci));
}
/*
** this function can be called asynchronous (e.g. during a signal)
*/
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
mask = 0;
func = NULL;
}
else *d = *s;
if (isLua(L->ci))
L->oldpc = L->ci->u.l.savedpc;
L->hook = func;
L->basehookcount = count;
resethookcount(L);
L->hookmask = cast_byte(mask);
return 1;
}
static int isLmark (StkId o) {
return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC);
LUA_API lua_Hook lua_gethook (lua_State *L) {
return L->hook;
}
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
lua_Hook oldhook = L->callhook;
L->callhook = func;
return oldhook;
LUA_API int lua_gethookmask (lua_State *L) {
return L->hookmask;
}
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
lua_Hook oldhook = L->linehook;
L->linehook = func;
return oldhook;
}
static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
int i;
for (i = (top-1) - L->stack; i>=0; i--) {
if (is_T_MARK(L->stack[i].ttype)) {
if (level == 0)
return L->stack+i;
level--;
}
}
return NULL;
LUA_API int lua_gethookcount (lua_State *L) {
return L->basehookcount;
}
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
StkId f = aux_stackedfunction(L, level, L->top);
if (f == NULL) return 0; /* there is no such level */
else {
ar->_func = f;
return 1;
int status;
CallInfo *ci;
if (level < 0) return 0; /* invalid (negative) level */
lua_lock(L);
for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
level--;
if (level == 0 && ci != &L->base_ci) { /* level found? */
status = 1;
ar->i_ci = ci;
}
else status = 0; /* no such level */
lua_unlock(L);
return status;
}
static int nups (StkId f) {
switch (ttype(f)) {
case LUA_TFUNCTION:
return clvalue(f)->nupvalues;
case LUA_TMARK:
return infovalue(f)->func->nupvalues;
default:
return 0;
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId *pos) {
const char *name = NULL;
StkId base;
if (isLua(ci)) {
base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci));
}
}
int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
int refi;
if (lineinfo == NULL || pc == -1)
return -1; /* no line info or function is not active */
refi = prefi ? *prefi : 0;
if (lineinfo[refi] < 0)
refline += -lineinfo[refi++];
LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
while (lineinfo[refi] > pc) {
refline--;
refi--;
if (lineinfo[refi] < 0)
refline -= -lineinfo[refi--];
LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
}
for (;;) {
int nextline = refline + 1;
int nextref = refi + 1;
if (lineinfo[nextref] < 0)
nextline += -lineinfo[nextref++];
LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
if (lineinfo[nextref] > pc)
break;
refline = nextline;
refi = nextref;
}
if (prefi) *prefi = refi;
return refline;
}
static int currentpc (StkId f) {
CallInfo *ci = infovalue(f);
LUA_ASSERT(isLmark(f), "function has no pc");
if (ci->pc)
return (*ci->pc - ci->func->f.l->code) - 1;
else
return -1; /* function is not active */
}
static int currentline (StkId f) {
if (!isLmark(f))
return -1; /* only active lua functions have current-line information */
else {
CallInfo *ci = infovalue(f);
int *lineinfo = ci->func->f.l->lineinfo;
return luaG_getline(lineinfo, currentpc(f), 1, NULL);
base = ci->func + 1;
if (name == NULL) { /* no 'standard' name? */
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
name = "(*temporary)"; /* generic name for any valid slot */
else {
*pos = base; /* to avoid warnings */
return NULL; /* no name */
}
}
}
static Proto *getluaproto (StkId f) {
return (isLmark(f) ? infovalue(f)->func->f.l : NULL);
*pos = base + (n - 1);
return name;
}
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
StkId f = ar->_func;
Proto *fp = getluaproto(f);
if (!fp) return NULL; /* `f' is not a Lua function? */
name = luaF_getlocalname(fp, n, currentpc(f));
if (!name) return NULL;
luaA_pushobject(L, (f+1)+(n-1)); /* push value */
lua_lock(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
else /* consider live variables at function start (parameters) */
name = luaF_getlocalname(clvalue(L->top - 1)->l.p, n, 0);
}
else { /* active function; get information through 'ar' */
StkId pos;
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobj2s(L, L->top, pos);
api_incr_top(L);
}
}
lua_unlock(L);
return name;
}
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
StkId f = ar->_func;
Proto *fp = getluaproto(f);
L->top--; /* pop new value */
if (!fp) return NULL; /* `f' is not a Lua function? */
name = luaF_getlocalname(fp, n, currentpc(f));
if (!name || name[0] == '(') return NULL; /* `(' starts private locals */
*((f+1)+(n-1)) = *L->top;
StkId pos;
const char *name = findlocal(L, ar->i_ci, n, &pos);
lua_lock(L);
if (name)
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
lua_unlock(L);
return name;
}
static void infoLproto (lua_Debug *ar, Proto *f) {
ar->source = f->source->str;
ar->linedefined = f->lineDefined;
ar->what = "Lua";
}
static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
Closure *cl = NULL;
switch (ttype(func)) {
case LUA_TFUNCTION:
cl = clvalue(func);
break;
case LUA_TMARK:
cl = infovalue(func)->func;
break;
default:
lua_error(L, "value for `lua_getinfo' is not a function");
}
if (cl->isC) {
ar->source = "=C";
static void funcinfo (lua_Debug *ar, Closure *cl) {
if (cl == NULL || cl->c.isC) {
ar->source = "=[C]";
ar->linedefined = -1;
ar->lastlinedefined = -1;
ar->what = "C";
}
else
infoLproto(ar, cl->f.l);
luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src));
if (ar->linedefined == 0)
ar->what = "main";
else {
Proto *p = cl->l.p;
ar->source = p->source ? getstr(p->source) : "=?";
ar->linedefined = p->linedefined;
ar->lastlinedefined = p->lastlinedefined;
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
}
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
}
static const char *travtagmethods (lua_State *L, const TObject *o) {
if (ttype(o) == LUA_TFUNCTION) {
int e;
for (e=0; e<TM_N; e++) {
int t;
for (t=0; t<=L->last_tag; t++)
if (clvalue(o) == luaT_gettm(L, t, e))
return luaT_eventname[e];
static void collectvalidlines (lua_State *L, Closure *f) {
if (f == NULL || f->c.isC) {
setnilvalue(L->top);
incr_top(L);
}
else {
int i;
int *lineinfo = f->l.p->lineinfo;
Table *t = luaH_new(L);
sethvalue(L, L->top, t);
incr_top(L);
for (i=0; i<f->l.p->sizelineinfo; i++)
setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
}
}
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
break;
}
case 'u': {
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
if (f == NULL || f->c.isC) {
ar->isvararg = 1;
ar->nparams = 0;
}
else {
ar->isvararg = f->l.p->is_vararg;
ar->nparams = f->l.p->numparams;
}
break;
}
case 't': {
ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
break;
}
case 'n': {
ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return NULL;
}
static const char *travglobals (lua_State *L, const TObject *o) {
Hash *g = L->gt;
int i;
for (i=0; i<g->size; i++) {
if (luaO_equalObj(o, val(node(g, i))) &&
ttype(key(node(g, i))) == LUA_TSTRING)
return tsvalue(key(node(g, i)))->str;
}
return NULL;
}
static void getname (lua_State *L, StkId f, lua_Debug *ar) {
TObject o;
setnormalized(&o, f);
/* try to find a name for given function */
if ((ar->name = travglobals(L, &o)) != NULL)
ar->namewhat = "global";
/* not found: try tag methods */
else if ((ar->name = travtagmethods(L, &o)) != NULL)
ar->namewhat = "tag-method";
else ar->namewhat = ""; /* not found at all */
return status;
}
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status;
Closure *cl;
CallInfo *ci;
StkId func;
int isactive = (*what != '>');
if (isactive)
func = ar->_func;
else {
what++; /* skip the '>' */
lua_lock(L);
if (*what == '>') {
ci = NULL;
func = L->top - 1;
luai_apicheck(L, ttisfunction(func));
what++; /* skip the '>' */
L->top--; /* pop function */
}
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(L, ar, func);
break;
}
case 'l': {
ar->currentline = currentline(func);
break;
}
case 'u': {
ar->nups = nups(func);
break;
}
case 'n': {
ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL;
if (ar->namewhat == NULL)
getname(L, func, ar);
break;
}
case 'f': {
setnormalized(L->top, func);
incr_top; /* push function */
break;
}
default: return 0; /* invalid option */
}
else {
ci = ar->i_ci;
func = ci->func;
lua_assert(ttisfunction(ci->func));
}
if (!isactive) L->top--; /* pop function */
return 1;
cl = ttisclosure(func) ? clvalue(func) : NULL;
status = auxgetinfo(L, what, ar, cl, ci);
if (strchr(what, 'f')) {
setobjs2s(L, L->top, func);
incr_top(L);
}
if (strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);
return status;
}
@@ -293,174 +272,260 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
*/
static int pushpc (int *stack, int pc, int top, int n) {
while (n--)
stack[top++] = pc-1;
return top;
static void kname (Proto *p, int c, int reg, const char *what,
const char **name) {
if (c == reg && what && *what == 'c')
return; /* index is a constant; name already correct */
else if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
*name = svalue(&p->k[INDEXK(c)]);
else
*name = "?";
}
static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
const Instruction *code = pt->code;
int top = pt->numparams;
int pc = 0;
if (pt->is_vararg) /* varargs? */
top++; /* `arg' */
while (pc < lastpc) {
const Instruction i = code[pc++];
LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack");
switch (GET_OPCODE(i)) {
case OP_RETURN: {
LUA_ASSERT(top >= GETARG_U(i), "wrong stack");
top = GETARG_U(i);
break;
}
case OP_TAILCALL: {
LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
top = GETARG_B(i);
break;
}
case OP_CALL: {
int nresults = GETARG_B(i);
if (nresults == MULT_RET) nresults = 1;
LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
top = pushpc(stack, pc, GETARG_A(i), nresults);
break;
}
case OP_PUSHNIL: {
top = pushpc(stack, pc, top, GETARG_U(i));
break;
}
case OP_POP: {
top -= GETARG_U(i);
break;
}
case OP_SETTABLE:
case OP_SETLIST: {
top -= GETARG_B(i);
break;
}
case OP_SETMAP: {
top -= 2*GETARG_U(i);
break;
}
case OP_CONCAT: {
top -= GETARG_U(i);
stack[top++] = pc-1;
break;
}
case OP_CLOSURE: {
top -= GETARG_B(i);
stack[top++] = pc-1;
break;
}
case OP_JMPONT:
case OP_JMPONF: {
int newpc = pc + GETARG_S(i);
/* jump is forward and do not skip `lastpc'? */
if (pc < newpc && newpc <= lastpc) {
stack[top-1] = pc-1; /* value comes from `and'/`or' */
pc = newpc; /* do the jump */
static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
const char **name) {
Proto *p = ci_func(ci)->l.p;
const char *what = NULL;
int lastpc = currentpc(ci);
int pc;
*name = luaF_getlocalname(p, reg + 1, lastpc);
if (*name) /* is a local? */
return "local";
/* else try symbolic execution */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
switch (op) {
case OP_MOVE: {
if (reg == a) {
int b = GETARG_B(i); /* move from 'b' to 'a' */
if (b < a)
what = getobjname(L, ci, b, name); /* get name for 'b' */
else what = NULL;
}
else
top--; /* do not jump; pop value */
break;
}
default: {
OpCode op = GET_OPCODE(i);
LUA_ASSERT(luaK_opproperties[op].push != VD,
"invalid opcode for default");
top -= luaK_opproperties[op].pop;
LUA_ASSERT(top >= 0, "wrong stack");
top = pushpc(stack, pc, top, luaK_opproperties[op].push);
case OP_GETTABUP:
case OP_GETTABLE: {
if (reg == a) {
int k = GETARG_C(i); /* key index */
int t = GETARG_B(i);
const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
? luaF_getlocalname(p, t + 1, pc)
: getstr(p->upvalues[t].name);
kname(p, k, a, what, name);
what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
}
break;
}
}
}
return code[stack[stackpos]];
}
static const char *getobjname (lua_State *L, StkId obj, const char **name) {
StkId func = aux_stackedfunction(L, 0, obj);
if (!isLmark(func))
return NULL; /* not an active Lua function */
else {
Proto *p = infovalue(func)->func->f.l;
int pc = currentpc(func);
int stackpos = obj - (func+1); /* func+1 == function base */
Instruction i = luaG_symbexec(p, pc, stackpos);
LUA_ASSERT(pc != -1, "function must be active");
switch (GET_OPCODE(i)) {
case OP_GETGLOBAL: {
*name = p->kstr[GETARG_U(i)]->str;
return "global";
case OP_GETUPVAL: {
if (reg == a) {
int u = GETARG_B(i); /* upvalue index */
TString *tn = p->upvalues[u].name;
*name = tn ? getstr(tn) : "?";
what = "upvalue";
}
break;
}
case OP_GETLOCAL: {
*name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
LUA_ASSERT(*name, "local must exist");
return "local";
case OP_LOADK: {
if (reg == a) {
int b = GETARG_Bx(i);
b = (b > 0) ? b - 1 : GETARG_Ax(p->code[pc + 1]);
if (ttisstring(&p->k[b])) {
what = "constant";
*name = svalue(&p->k[b]);
}
}
break;
}
case OP_PUSHSELF:
case OP_GETDOTTED: {
*name = p->kstr[GETARG_U(i)]->str;
return "field";
case OP_LOADNIL: {
int b = GETARG_B(i); /* move from 'b' to 'a' */
if (a <= reg && reg <= b) /* set registers from 'a' to 'b' */
what = NULL;
break;
}
case OP_SELF: {
if (reg == a) {
int k = GETARG_C(i); /* key index */
kname(p, k, a, what, name);
what = "method";
}
break;
}
case OP_TFORCALL: {
if (reg >= a + 2) what = NULL; /* affect all regs above its base */
break;
}
case OP_CALL:
case OP_TAILCALL: {
if (reg >= a) what = NULL; /* affect all registers above base */
break;
}
case OP_JMP: {
int b = GETARG_sBx(i);
int dest = pc + 1 + b;
/* jump is forward and do not skip `lastpc'? */
if (pc < dest && dest <= lastpc)
pc += b; /* do the jump */
break;
}
default:
return NULL; /* no useful name found */
if (testAMode(op) && reg == a) what = NULL;
break;
}
}
return what;
}
static const char *getfuncname (lua_State *L, StkId f, const char **name) {
StkId func = aux_stackedfunction(L, 0, f); /* calling function */
if (!isLmark(func))
return NULL; /* not an active Lua function */
else {
Proto *p = infovalue(func)->func->f.l;
int pc = currentpc(func);
Instruction i;
if (pc == -1) return NULL; /* function is not activated */
i = p->code[pc];
switch (GET_OPCODE(i)) {
case OP_CALL: case OP_TAILCALL:
return getobjname(L, (func+1)+GETARG_A(i), name);
default:
return NULL; /* no useful name found */
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm;
Instruction i;
if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
return NULL; /* calling function is not Lua (or is unknown) */
ci = ci->previous; /* calling function */
i = ci_func(ci)->l.p->code[currentpc(ci)];
if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
i = ci_func(ci)->l.p->code[currentpc(ci) - 1]; /* get 'real' instruction */
switch (GET_OPCODE(i)) {
case OP_CALL:
case OP_TAILCALL:
return getobjname(L, ci, GETARG_A(i), name);
case OP_TFORCALL: {
*name = "for iterator";
return "for iterator";
}
case OP_SELF:
case OP_GETTABUP:
case OP_GETTABLE: tm = TM_INDEX; break;
case OP_SETTABUP:
case OP_SETTABLE: tm = TM_NEWINDEX; break;
case OP_EQ: tm = TM_EQ; break;
case OP_ADD: tm = TM_ADD; break;
case OP_SUB: tm = TM_SUB; break;
case OP_MUL: tm = TM_MUL; break;
case OP_DIV: tm = TM_DIV; break;
case OP_MOD: tm = TM_MOD; break;
case OP_POW: tm = TM_POW; break;
case OP_UNM: tm = TM_UNM; break;
case OP_LEN: tm = TM_LEN; break;
case OP_LT: tm = TM_LT; break;
case OP_LE: tm = TM_LE; break;
case OP_CONCAT: tm = TM_CONCAT; break;
default:
return NULL; /* else no useful name can be found */
}
*name = getstr(G(L)->tmname[tm]);
return "metamethod";
}
/* }====================================================== */
void luaG_typeerror (lua_State *L, StkId o, const char *op) {
const char *name;
const char *kind = getobjname(L, o, &name);
const char *t = luaO_typename(o);
/* only ANSI way to check whether a pointer points to an array */
static int isinstack (CallInfo *ci, const TValue *o) {
StkId p;
for (p = ci->u.l.base; p < ci->top; p++)
if (o == p) return 1;
return 0;
}
static const char *getupvalname (CallInfo *ci, const TValue *o,
const char **name) {
LClosure *c = &ci_func(ci)->l;
int i;
for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) {
*name = getstr(c->p->upvalues[i].name);
return "upvalue";
}
}
return NULL;
}
void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
CallInfo *ci = L->ci;
const char *name = NULL;
const char *t = objtypename(o);
const char *kind = NULL;
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */
kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name);
}
if (kind)
luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
op, kind, name, t);
else
luaO_verror(L, "attempt to %.30s a %.10s value", op, t);
luaG_runerror(L, "attempt to %s a %s value", op, t);
}
void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) {
if (ttype(p1) == t) p1++;
LUA_ASSERT(ttype(p1) != t, "must be an error");
luaG_typeerror(L, p1, op);
void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
lua_assert(!ttisstring(p1) && !ttisnumber(p2));
luaG_typeerror(L, p1, "concatenate");
}
void luaG_ordererror (lua_State *L, StkId top) {
const char *t1 = luaO_typename(top-2);
const char *t2 = luaO_typename(top-1);
if (t1[2] == t2[2])
luaO_verror(L, "attempt to compare two %.10s values", t1);
void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, "perform arithmetic on");
}
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
if (t1 == t2)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2);
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
return 0;
}
static void addinfo (lua_State *L, const char *msg) {
CallInfo *ci = L->ci;
if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(ci);
TString *src = ci_func(ci)->l.p->source;
if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */
buff[0] = '?'; buff[1] = '\0';
}
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
}
void luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
incr_top(L);
luaD_call(L, L->top - 2, 1, 0); /* call it */
}
luaD_throw(L, LUA_ERRRUN);
}
void luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
va_end(argp);
luaG_errormsg(L);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 1.6 2000/10/02 20:10:55 roberto Exp roberto $
** $Id: ldebug.h,v 2.4 2009/04/30 17:42:21 roberto Exp roberto $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@@ -9,13 +9,23 @@
#include "lstate.h"
#include "luadebug.h"
void luaG_typeerror (lua_State *L, StkId o, const char *op);
void luaG_binerror (lua_State *L, StkId p1, int t, const char *op);
int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
void luaG_ordererror (lua_State *L, StkId top);
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
#define resethookcount(L) (L->hookcount = L->basehookcount)
LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaG_errormsg (lua_State *L);
#endif

864
ldo.c
View File

@@ -1,22 +1,27 @@
/*
** $Id: ldo.c,v 1.108 2000/10/20 16:39:03 roberto Exp roberto $
** $Id: ldo.c,v 2.89 2010/09/30 17:21:31 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ldo_c
#define LUA_CORE
#include "lua.h"
#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
@@ -27,359 +32,624 @@
#include "lzio.h"
/* space to handle stack overflow errors */
#define EXTRA_STACK (2*LUA_MINSTACK)
void luaD_init (lua_State *L, int stacksize) {
L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
L->nblocks += stacksize*sizeof(TObject);
L->stack_last = L->stack+(stacksize-1);
L->stacksize = stacksize;
L->Cbase = L->top = L->stack;
/*
** {======================================================
** Error-recovery functions
** =======================================================
*/
/*
** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
** default, Lua handles errors with exceptions when compiling as
** C++ code, with _longjmp/_setjmp when asked to use them, and with
** longjmp/setjmp otherwise.
*/
#if !defined(LUAI_THROW)
#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) \
try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif
#endif
/* chain list of long jump buffers */
struct lua_longjmp {
struct lua_longjmp *previous;
luai_jmpbuf b;
volatile int status; /* error code */
};
static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
switch (errcode) {
case LUA_ERRMEM: { /* memory error? */
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
break;
}
case LUA_ERRERR: {
setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
break;
}
default: {
setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
break;
}
}
L->top = oldtop + 1;
}
void luaD_checkstack (lua_State *L, int n) {
if (L->stack_last - L->top <= n) { /* stack overflow? */
if (L->stack_last-L->stack > (L->stacksize-1)) {
/* overflow while handling overflow */
luaD_breakrun(L, LUA_ERRERR); /* break run without error message */
void luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) { /* thread has an error handler? */
L->errorJmp->status = errcode; /* set status */
LUAI_THROW(L, L->errorJmp); /* jump to it */
}
else { /* thread has no error handler */
L->status = cast_byte(errcode); /* mark it as dead */
if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */
setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */
luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */
}
else {
L->stack_last += EXTRA_STACK; /* to be used by error message */
lua_error(L, "stack overflow");
else { /* no handler at all; abort */
if (G(L)->panic) { /* panic function? */
lua_unlock(L);
G(L)->panic(L); /* call it (last chance to jump out) */
}
abort();
}
}
}
static void restore_stack_limit (lua_State *L) {
if (L->top - L->stack < L->stacksize - 1)
L->stack_last = L->stack + (L->stacksize-1);
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
unsigned short oldnCcalls = G(L)->nCcalls;
struct lua_longjmp lj;
lj.status = LUA_OK;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
LUAI_TRY(L, &lj,
(*f)(L, ud);
);
L->errorJmp = lj.previous; /* restore old error handler */
G(L)->nCcalls = oldnCcalls;
return lj.status;
}
/* }====================================================== */
static void correctstack (lua_State *L, TValue *oldstack) {
CallInfo *ci;
GCObject *up;
L->top = (L->top - oldstack) + L->stack;
for (up = L->openupval; up != NULL; up = up->gch.next)
gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
ci->top = (ci->top - oldstack) + L->stack;
ci->func = (ci->func - oldstack) + L->stack;
if (isLua(ci))
ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
}
}
/*
** Adjust stack. Set top to base+extra, pushing NILs if needed.
** (we cannot add base+extra unless we are sure it fits in the stack;
** otherwise the result of such operation on pointers is undefined)
*/
void luaD_adjusttop (lua_State *L, StkId base, int extra) {
int diff = extra-(L->top-base);
if (diff <= 0)
L->top = base+extra;
/* some space for error handling */
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
void luaD_reallocstack (lua_State *L, int newsize) {
TValue *oldstack = L->stack;
int lim = L->stacksize;
lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
for (; lim < newsize; lim++)
setnilvalue(L->stack + lim); /* erase new segment */
L->stacksize = newsize;
L->stack_last = L->stack + newsize - EXTRA_STACK;
correctstack(L, oldstack);
}
void luaD_growstack (lua_State *L, int n) {
int size = L->stacksize;
if (size > LUAI_MAXSTACK) /* error after extra size? */
luaD_throw(L, LUA_ERRERR);
else {
luaD_checkstack(L, diff);
while (diff--)
ttype(L->top++) = LUA_TNIL;
int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
int newsize = 2 * size;
if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
if (newsize < needed) newsize = needed;
if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
luaD_reallocstack(L, ERRORSTACKSIZE);
luaG_runerror(L, "stack overflow");
}
else
luaD_reallocstack(L, newsize);
}
}
static int stackinuse (lua_State *L) {
CallInfo *ci;
StkId lim = L->top;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
lua_assert(ci->top <= L->stack_last);
if (lim < ci->top) lim = ci->top;
}
return cast_int(lim - L->stack) + 1; /* part of stack in use */
}
void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L);
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */
goodsize >= L->stacksize) /* would grow instead of shrink? */
condmovestack(L); /* don't change stack (change only for debugging) */
else
luaD_reallocstack(L, goodsize); /* shrink it */
}
void luaD_hook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && L->allowhook) {
CallInfo *ci = L->ci;
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, ci->top);
lua_Debug ar;
ar.event = event;
ar.currentline = line;
ar.i_ci = ci;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
L->allowhook = 0; /* cannot call hooks inside a hook */
ci->callstatus |= CIST_HOOKED;
lua_unlock(L);
(*hook)(L, &ar);
lua_lock(L);
lua_assert(!L->allowhook);
L->allowhook = 1;
ci->top = restorestack(L, ci_top);
L->top = restorestack(L, top);
ci->callstatus &= ~CIST_HOOKED;
}
}
static void callhook (lua_State *L, CallInfo *ci) {
int hook = LUA_HOOKCALL;
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
if (isLua(ci->previous) &&
GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
ci->callstatus |= CIST_TAIL;
hook = LUA_HOOKTAILCALL;
}
luaD_hook(L, hook, -1);
ci->u.l.savedpc--; /* correct 'pc' */
}
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
int nfixargs = p->numparams;
StkId base, fixed;
lua_assert(actual >= nfixargs);
/* move fixed parameters to final position */
fixed = L->top - actual; /* first fixed argument */
base = L->top; /* final position of first argument */
for (i=0; i<nfixargs; i++) {
setobjs2s(L, L->top++, fixed + i);
setnilvalue(fixed + i);
}
return base;
}
static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
ptrdiff_t funcr = savestack(L, func);
if (!ttisfunction(tm))
luaG_typeerror(L, func, "call");
/* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
incr_top(L);
func = restorestack(L, funcr); /* previous call may change stack */
setobj2s(L, func, tm); /* tag method is the new function to be called */
return func;
}
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
/*
** Open a hole inside the stack at `pos'
** returns true if function has been executed (C function)
*/
static void luaD_openstack (lua_State *L, StkId pos) {
int i = L->top-pos;
while (i--) pos[i+1] = pos[i];
incr_top;
}
static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
StkId old_Cbase = L->Cbase;
StkId old_top = L->Cbase = L->top;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->allowhooks = 0; /* cannot call hooks inside a hook */
(*hook)(L, ar);
LUA_ASSERT(L->allowhooks == 0, "invalid allow");
L->allowhooks = 1;
L->top = old_top;
L->Cbase = old_Cbase;
}
void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
if (L->allowhooks) {
lua_Debug ar;
ar._func = func;
ar.event = "line";
ar.currentline = line;
dohook(L, &ar, linehook);
int luaD_precall (lua_State *L, StkId func, int nresults) {
Closure *cl;
lua_CFunction f;
ptrdiff_t funcr;
if (!ttisfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
if (ttislcf(func)) { /* light C function? */
f = fvalue(func); /* get it */
goto isCfunc; /* go to call it */
}
cl = clvalue(func);
if (cl->c.isC) { /* C closure? */
CallInfo *ci;
int n;
f = cl->c.f;
isCfunc: /* call C function 'f' */
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = restorestack(L, funcr);
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, L->top - n);
return 1;
}
else { /* Lua function: prepare its call */
CallInfo *ci;
int nparams, nargs;
StkId base;
Proto *p = cl->l.p;
luaD_checkstack(L, p->maxstacksize);
func = restorestack(L, funcr);
nargs = cast_int(L->top - func) - 1; /* number of real arguments */
nparams = p->numparams; /* number of expected parameters */
for (; nargs < nparams; nargs++)
setnilvalue(L->top++); /* complete missing arguments */
if (!p->is_vararg) /* no varargs? */
base = func + 1;
else /* vararg function */
base = adjust_varargs(L, p, nargs);
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
ci->top = base + p->maxstacksize;
lua_assert(ci->top <= L->stack_last);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
L->top = ci->top;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
}
}
static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
const char *event) {
if (L->allowhooks) {
lua_Debug ar;
ar._func = func;
ar.event = event;
infovalue(func)->pc = NULL; /* function is not active */
dohook(L, &ar, callhook);
int luaD_poscall (lua_State *L, StkId firstResult) {
StkId res;
int wanted, i;
CallInfo *ci = L->ci;
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET) {
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
luaD_hook(L, LUA_HOOKRET, -1);
firstResult = restorestack(L, fr);
}
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
}
}
static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
int nup = cl->nupvalues; /* number of upvalues */
StkId old_Cbase = L->Cbase;
int n;
L->Cbase = base; /* new base for C function */
luaD_checkstack(L, nup+LUA_MINSTACK); /* ensure minimum stack size */
for (n=0; n<nup; n++) /* copy upvalues as extra arguments */
*(L->top++) = cl->upvalue[n];
n = (*cl->f.c)(L); /* do the actual call */
L->Cbase = old_Cbase; /* restore old C base */
return L->top - n; /* return index of first result */
}
void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) {
StkId base = L->top - nParams;
luaD_openstack(L, base);
clvalue(base) = f;
ttype(base) = LUA_TFUNCTION;
luaD_call(L, base, nResults);
res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults;
L->ci = ci = ci->previous; /* back to caller */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
while (i-- > 0)
setnilvalue(res++);
L->top = res;
return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
}
/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
** When returns, the results are on the stack, starting at the original
** When returns, all the results are on the stack, starting at the original
** function position.
** The number of results is nResults, unless nResults=LUA_MULTRET.
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
lua_Hook callhook;
StkId firstResult;
CallInfo ci;
Closure *cl;
if (ttype(func) != LUA_TFUNCTION) {
/* `func' is not a function; check the `function' tag method */
Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION);
if (tm == NULL)
luaG_typeerror(L, func, "call");
luaD_openstack(L, func);
clvalue(func) = tm; /* tag method is the new function to be called */
ttype(func) = LUA_TFUNCTION;
}
cl = clvalue(func);
ci.func = cl;
infovalue(func) = &ci;
ttype(func) = LUA_TMARK;
callhook = L->callhook;
if (callhook)
luaD_callHook(L, func, callhook, "call");
firstResult = (cl->isC ? callCclosure(L, cl, func+1) :
luaV_execute(L, cl, func+1));
if (callhook) /* same hook that was active at entry */
luaD_callHook(L, func, callhook, "return");
LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag");
/* move results to `func' (to erase parameters and function) */
if (nResults == LUA_MULTRET) {
while (firstResult < L->top) /* copy all results */
*func++ = *firstResult++;
L->top = func;
}
else { /* copy at most `nResults' */
for (; nResults > 0 && firstResult < L->top; nResults--)
*func++ = *firstResult++;
L->top = func;
for (; nResults > 0; nResults--) { /* if there are not enough results */
ttype(L->top) = LUA_TNIL; /* adjust the stack */
incr_top; /* must check stack space */
}
*/
void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
global_State *g = G(L);
if (++g->nCcalls >= LUAI_MAXCCALLS) {
if (g->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
else if (g->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
if (!allowyield) L->nny++;
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
luaV_execute(L); /* call it */
if (!allowyield) L->nny--;
g->nCcalls--;
luaC_checkGC(L);
}
/*
** Execute a protected call.
*/
struct CallS { /* data to `f_call' */
StkId func;
int nresults;
};
static void f_call (lua_State *L, void *ud) {
struct CallS *c = (struct CallS *)ud;
luaD_call(L, c->func, c->nresults);
static void finishCcall (lua_State *L) {
CallInfo *ci = L->ci;
int n;
lua_assert(ci->u.c.k != NULL); /* must have a continuation */
lua_assert(L->nny == 0);
/* finish 'luaD_call' */
G(L)->nCcalls--;
/* finish 'lua_callk' */
adjustresults(L, ci->nresults);
/* call continuation function */
if (!(ci->callstatus & CIST_STAT)) /* no call status? */
ci->u.c.status = LUA_YIELD; /* 'default' status */
lua_assert(ci->u.c.status != LUA_OK);
ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
lua_unlock(L);
n = (*ci->u.c.k)(L);
lua_lock(L);
api_checknelems(L, n);
/* finish 'luaD_precall' */
luaD_poscall(L, L->top - n);
}
LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
StkId func = L->top - (nargs+1); /* function to be called */
struct CallS c;
static void unroll (lua_State *L, void *ud) {
UNUSED(ud);
for (;;) {
if (L->ci == &L->base_ci) /* stack is empty? */
return; /* coroutine finished normally */
if (!isLua(L->ci)) /* C function? */
finishCcall(L);
else { /* Lua function */
luaV_finishOp(L); /* finish interrupted instruction */
luaV_execute(L); /* execute down to higher C 'boundary' */
}
}
}
/*
** check whether thread has a suspended protected call
*/
static CallInfo *findpcall (lua_State *L) {
CallInfo *ci;
for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
if (ci->callstatus & CIST_YPCALL)
return ci;
}
return NULL; /* no pending pcall */
}
static int recover (lua_State *L, int status) {
StkId oldtop;
CallInfo *ci = findpcall(L);
if (ci == NULL) return 0; /* no recovery point */
/* "finish" luaD_pcall */
oldtop = restorestack(L, ci->u.c.extra);
luaF_close(L, oldtop);
seterrorobj(L, status, oldtop);
L->ci = ci;
L->allowhook = ci->u.c.old_allowhook;
L->nny = 0; /* should be zero to be yieldable */
luaD_shrinkstack(L);
L->errfunc = ci->u.c.old_errfunc;
ci->callstatus |= CIST_STAT; /* call has error status */
ci->u.c.status = status; /* (here it is) */
return 1; /* continue running the coroutine */
}
/*
** signal an error in the call to 'resume', not in the execution of the
** coroutine itself. (Such errors should not be handled by any coroutine
** error handler and should not kill the coroutine.)
*/
static void resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
incr_top(L);
luaD_throw(L, -1); /* jump back to 'lua_resume' */
}
/*
** do the work for 'lua_resume' in protected mode
*/
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
if (G(L)->nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (ci != &L->base_ci) /* not in base level? */
resume_error(L, "cannot resume non-suspended coroutine", firstArg);
/* coroutine is in base level; start running it */
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
luaV_execute(L); /* call it */
}
else if (L->status != LUA_YIELD)
resume_error(L, "cannot resume dead coroutine", firstArg);
else { /* resuming from previous yield */
L->status = LUA_OK;
if (isLua(ci)) /* yielded inside a hook? */
luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
ci->func = restorestack(L, ci->u.c.extra);
if (ci->u.c.k != NULL) { /* does it have a continuation? */
int n;
ci->u.c.status = LUA_YIELD; /* 'default' status */
ci->callstatus |= CIST_YIELDED;
lua_unlock(L);
n = (*ci->u.c.k)(L); /* call continuation */
lua_lock(L);
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
G(L)->nCcalls--; /* finish 'luaD_call' */
luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
}
unroll(L, NULL);
}
}
LUA_API int lua_resume (lua_State *L, int nargs) {
int status;
c.func = func; c.nresults = nresults;
status = luaD_runprotected(L, f_call, &c);
if (status != 0) /* an error occurred? */
L->top = func; /* remove parameters from the stack */
lua_lock(L);
luai_userstateresume(L, nargs);
++G(L)->nCcalls; /* count resume */
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, L->top - nargs);
if (status == -1) /* error calling 'lua_resume'? */
status = LUA_ERRRUN;
else { /* yield or regular error */
while (status != LUA_OK && status != LUA_YIELD) { /* error? */
if (recover(L, status)) /* recover point? */
status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */
else { /* unrecoverable error */
L->status = cast_byte(status); /* mark thread as `dead' */
seterrorobj(L, status, L->top);
L->ci->top = L->top;
break;
}
}
lua_assert(status == L->status);
}
L->nny = 1; /* do not allow yields */
--G(L)->nCcalls;
lua_unlock(L);
return status;
}
LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
CallInfo *ci = L->ci;
luai_userstateyield(L, nresults);
lua_lock(L);
api_checknelems(L, nresults);
if (L->nny > 0) {
if (L != G(L)->mainthread)
luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
else
luaG_runerror(L, "attempt to yield from outside a coroutine");
}
L->status = LUA_YIELD;
if (isLua(ci)) { /* inside a hook? */
api_check(L, k == NULL, "hooks cannot continue after yielding");
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
ci->u.c.ctx = ctx; /* save context */
ci->u.c.extra = savestack(L, ci->func); /* save current 'func' */
ci->func = L->top - nresults - 1; /* protect stack below results */
luaD_throw(L, LUA_YIELD);
}
lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
lua_unlock(L);
return 0; /* return to 'luaD_hook' */
}
int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
int status;
CallInfo *old_ci = L->ci;
lu_byte old_allowhooks = L->allowhook;
unsigned short old_nny = L->nny;
ptrdiff_t old_errfunc = L->errfunc;
L->errfunc = ef;
status = luaD_rawrunprotected(L, func, u);
if (status != LUA_OK) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
luaF_close(L, oldtop); /* close possible pending closures */
seterrorobj(L, status, oldtop);
L->ci = old_ci;
L->allowhook = old_allowhooks;
L->nny = old_nny;
luaD_shrinkstack(L);
}
L->errfunc = old_errfunc;
return status;
}
/*
** Execute a protected parser.
*/
struct ParserS { /* data to `f_parser' */
struct SParser { /* data to `f_parser' */
ZIO *z;
int bin;
Mbuffer buff; /* buffer to be used by the scanner */
Varlist varl; /* list of local variables (to be used by the parser) */
const char *name;
};
static void f_parser (lua_State *L, void *ud) {
struct ParserS *p = (struct ParserS *)ud;
Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
luaV_Lclosure(L, tf, 0);
int i;
Proto *tf;
Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p->z);
tf = (c == LUA_SIGNATURE[0])
? luaU_undump(L, p->z, &p->buff, p->name)
: luaY_parser(L, p->z, &p->buff, &p->varl, p->name);
setptvalue2s(L, L->top, tf);
incr_top(L);
cl = luaF_newLclosure(L, tf);
setclvalue(L, L->top - 1, cl);
for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */
cl->l.upvals[i] = luaF_newupval(L);
}
static int protectedparser (lua_State *L, ZIO *z, int bin) {
struct ParserS p;
unsigned long old_blocks;
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
struct SParser p;
int status;
p.z = z; p.bin = bin;
luaC_checkGC(L);
old_blocks = L->nblocks;
status = luaD_runprotected(L, f_parser, &p);
if (status == 0) {
/* add new memory to threshold (as it probably will stay) */
L->GCthreshold += (L->nblocks - old_blocks);
}
else if (status == LUA_ERRRUN) /* an error occurred: correct error code */
status = LUA_ERRSYNTAX;
L->nny++; /* cannot yield during parsing */
p.z = z; p.name = name;
p.varl.actvar = NULL; p.varl.nactvar = p.varl.actvarsize = 0;
luaZ_initbuffer(L, &p.buff);
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
luaZ_freebuffer(L, &p.buff);
luaM_freearray(L, p.varl.actvar, p.varl.actvarsize);
L->nny--;
return status;
}
static int parse_file (lua_State *L, const char *filename) {
ZIO z;
int status;
int bin; /* flag for file mode */
int c; /* look ahead char */
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL) return LUA_ERRFILE; /* unable to open file */
c = fgetc(f);
ungetc(c, f);
bin = (c == ID_CHUNK);
if (bin && f != stdin) {
f = freopen(filename, "rb", f); /* set binary mode */
if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */
}
lua_pushstring(L, "@");
lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
lua_concat(L, 2);
filename = lua_tostring(L, -1); /* filename = '@'..filename */
lua_pop(L, 1); /* OK: there is no GC during parser */
luaZ_Fopen(&z, f, filename);
status = protectedparser(L, &z, bin);
if (f != stdin)
fclose(f);
return status;
}
LUA_API int lua_dofile (lua_State *L, const char *filename) {
int status = parse_file(L, filename);
if (status == 0) /* parse OK? */
status = lua_call(L, 0, LUA_MULTRET); /* call main */
return status;
}
static int parse_buffer (lua_State *L, const char *buff, size_t size,
const char *name) {
ZIO z;
if (!name) name = "?";
luaZ_mopen(&z, buff, size, name);
return protectedparser(L, &z, buff[0]==ID_CHUNK);
}
LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
int status = parse_buffer(L, buff, size, name);
if (status == 0) /* parse OK? */
status = lua_call(L, 0, LUA_MULTRET); /* call main */
return status;
}
LUA_API int lua_dostring (lua_State *L, const char *str) {
return lua_dobuffer(L, str, strlen(str), str);
}
/*
** {======================================================
** Error-recover functions (based on long jumps)
** =======================================================
*/
/* chain list of long jump buffers */
struct lua_longjmp {
jmp_buf b;
struct lua_longjmp *previous;
volatile int status; /* error code */
};
static void message (lua_State *L, const char *s) {
const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE);
if (ttype(em) == LUA_TFUNCTION) {
*L->top = *em;
incr_top;
lua_pushstring(L, s);
luaD_call(L, L->top-2, 0);
}
}
/*
** Reports an error, and jumps up to the available recovery label
*/
LUA_API void lua_error (lua_State *L, const char *s) {
if (s) message(L, s);
luaD_breakrun(L, LUA_ERRRUN);
}
void luaD_breakrun (lua_State *L, int errcode) {
if (L->errorJmp) {
L->errorJmp->status = errcode;
longjmp(L->errorJmp->b, 1);
}
else {
if (errcode != LUA_ERRMEM)
message(L, "unable to recover; exiting\n");
exit(EXIT_FAILURE);
}
}
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
StkId oldCbase = L->Cbase;
StkId oldtop = L->top;
struct lua_longjmp lj;
int allowhooks = L->allowhooks;
lj.status = 0;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
if (setjmp(lj.b) == 0)
(*f)(L, ud);
else { /* an error occurred: restore the state */
L->allowhooks = allowhooks;
L->Cbase = oldCbase;
L->top = oldtop;
restore_stack_limit(L);
}
L->errorJmp = lj.previous; /* restore old error handler */
return lj.status;
}
/* }====================================================== */

40
ldo.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 1.27 2000/10/05 13:00:17 roberto Exp roberto $
** $Id: ldo.h,v 2.17 2009/11/25 15:27:51 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -10,24 +10,36 @@
#include "lobject.h"
#include "lstate.h"
#include "lzio.h"
/*
** macro to increment stack top.
** There must be always an empty slot at the L->stack.top
*/
#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \
luaD_growstack(L, n); else condmovestack(L);
void luaD_init (lua_State *L, int stacksize);
void luaD_adjusttop (lua_State *L, StkId base, int extra);
void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
void luaD_call (lua_State *L, StkId func, int nResults);
void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
void luaD_checkstack (lua_State *L, int n);
#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
void luaD_breakrun (lua_State *L, int errcode);
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
/* type of protected functions, to be ran by `runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
int allowyield);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
#endif

172
ldump.c Normal file
View File

@@ -0,0 +1,172 @@
/*
** $Id: ldump.c,v 1.17 2010/10/13 21:04:52 lhf Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define ldump_c
#define LUA_CORE
#include "lua.h"
#include "lobject.h"
#include "lstate.h"
#include "lundump.h"
typedef struct {
lua_State* L;
lua_Writer writer;
void* data;
int strip;
int status;
} DumpState;
#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
static void DumpBlock(const void* b, size_t size, DumpState* D)
{
if (D->status==0)
{
lua_unlock(D->L);
D->status=(*D->writer)(D->L,b,size,D->data);
lua_lock(D->L);
}
}
static void DumpChar(int y, DumpState* D)
{
char x=(char)y;
DumpVar(x,D);
}
static void DumpInt(int x, DumpState* D)
{
DumpVar(x,D);
}
static void DumpNumber(lua_Number x, DumpState* D)
{
DumpVar(x,D);
}
static void DumpVector(const void* b, int n, size_t size, DumpState* D)
{
DumpInt(n,D);
DumpMem(b,n,size,D);
}
static void DumpString(const TString* s, DumpState* D)
{
if (s==NULL)
{
size_t size=0;
DumpVar(size,D);
}
else
{
size_t size=s->tsv.len+1; /* include trailing '\0' */
DumpVar(size,D);
DumpBlock(getstr(s),size,D);
}
}
#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
static void DumpFunction(const Proto* f, DumpState* D);
static void DumpConstants(const Proto* f, DumpState* D)
{
int i,n=f->sizek;
DumpInt(n,D);
for (i=0; i<n; i++)
{
const TValue* o=&f->k[i];
DumpChar(ttype(o),D);
switch (ttype(o))
{
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
DumpChar(bvalue(o),D);
break;
case LUA_TNUMBER:
DumpNumber(nvalue(o),D);
break;
case LUA_TSTRING:
DumpString(rawtsvalue(o),D);
break;
}
}
n=f->sizep;
DumpInt(n,D);
for (i=0; i<n; i++) DumpFunction(f->p[i],D);
}
static void DumpUpvalues(const Proto* f, DumpState* D)
{
int i,n=f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++)
{
DumpChar(f->upvalues[i].instack, D);
DumpChar(f->upvalues[i].idx, D);
}
}
static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
DumpString((D->strip) ? NULL : f->source,D);
n= (D->strip) ? 0 : f->sizelineinfo;
DumpVector(f->lineinfo,n,sizeof(int),D);
n= (D->strip) ? 0 : f->sizelocvars;
DumpInt(n,D);
for (i=0; i<n; i++)
{
DumpString(f->locvars[i].varname,D);
DumpInt(f->locvars[i].startpc,D);
DumpInt(f->locvars[i].endpc,D);
}
n= (D->strip) ? 0 : f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
}
static void DumpFunction(const Proto* f, DumpState* D)
{
DumpInt(f->linedefined,D);
DumpInt(f->lastlinedefined,D);
DumpChar(f->numparams,D);
DumpChar(f->is_vararg,D);
DumpChar(f->maxstacksize,D);
DumpCode(f,D);
DumpConstants(f,D);
DumpUpvalues(f,D);
DumpDebug(f,D);
}
static void DumpHeader(DumpState* D)
{
char h[LUAC_HEADERSIZE];
luaU_header(h);
DumpBlock(h,LUAC_HEADERSIZE,D);
}
/*
** dump Lua function as precompiled chunk
*/
int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
{
DumpState D;
D.L=L;
D.writer=w;
D.data=data;
D.strip=strip;
D.status=0;
DumpHeader(&D);
DumpFunction(f,&D);
return D.status;
}

174
lfunc.c
View File

@@ -1,93 +1,155 @@
/*
** $Id: lfunc.c,v 1.33 2000/10/18 17:19:09 roberto Exp roberto $
** $Id: lfunc.c,v 2.26 2010/06/10 21:27:09 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <stddef.h>
#define lfunc_c
#define LUA_CORE
#include "lua.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1))
Closure *luaF_newclosure (lua_State *L, int nelems) {
int size = sizeclosure(nelems);
Closure *c = (Closure *)luaM_malloc(L, size);
c->next = L->rootcl;
L->rootcl = c;
c->mark = c;
c->nupvalues = nelems;
L->nblocks += size;
Closure *luaF_newCclosure (lua_State *L, int n) {
Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeCclosure(n), NULL, 0)->cl;
c->c.isC = 1;
c->c.nupvalues = cast_byte(n);
return c;
}
Closure *luaF_newLclosure (lua_State *L, Proto *p) {
int n = p->sizeupvalues;
Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeLclosure(n), NULL, 0)->cl;
c->l.isC = 0;
c->l.p = p;
c->l.nupvalues = cast_byte(n);
while (n--) c->l.upvals[n] = NULL;
return c;
}
UpVal *luaF_newupval (lua_State *L) {
UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;
uv->v = &uv->u.value;
setnilvalue(uv->v);
return uv;
}
UpVal *luaF_findupval (lua_State *L, StkId level) {
global_State *g = G(L);
GCObject **pp = &L->openupval;
UpVal *p;
UpVal *uv;
while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
GCObject *o = obj2gco(p);
lua_assert(p->v != &p->u.value);
if (p->v == level) { /* found a corresponding upvalue? */
if (isdead(g, o)) /* is it dead? */
changewhite(o); /* resurrect it */
return p;
}
resetoldbit(o); /* may create a newer upval after this one */
pp = &p->next;
}
/* not found: create a new one */
uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;
uv->v = level; /* current value lives in the stack */
uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
uv->u.l.next = g->uvhead.u.l.next;
uv->u.l.next->u.l.prev = uv;
g->uvhead.u.l.next = uv;
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
return uv;
}
static void unlinkupval (UpVal *uv) {
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
uv->u.l.prev->u.l.next = uv->u.l.next;
}
void luaF_freeupval (lua_State *L, UpVal *uv) {
if (uv->v != &uv->u.value) /* is it open? */
unlinkupval(uv); /* remove from open list */
luaM_free(L, uv); /* free upvalue */
}
void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
global_State *g = G(L);
while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {
GCObject *o = obj2gco(uv);
lua_assert(!isblack(o) && uv->v != &uv->u.value);
L->openupval = uv->next; /* remove from `open' list */
if (isdead(g, o))
luaF_freeupval(L, uv); /* free upvalue */
else {
unlinkupval(uv); /* remove upvalue from 'uvhead' list */
setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
uv->v = &uv->u.value; /* now current value lives here */
gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */
g->allgc = o;
luaC_checkupvalcolor(g, uv);
}
}
}
Proto *luaF_newproto (lua_State *L) {
Proto *f = luaM_new(L, Proto);
f->knum = NULL;
f->nknum = 0;
f->kstr = NULL;
f->nkstr = 0;
f->kproto = NULL;
f->nkproto = 0;
Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;
f->k = NULL;
f->sizek = 0;
f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->ncode = 0;
f->cache = NULL;
f->sizecode = 0;
f->lineinfo = NULL;
f->sizelineinfo = 0;
f->upvalues = NULL;
f->sizeupvalues = 0;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
f->marked = 0;
f->lineinfo = NULL;
f->nlineinfo = 0;
f->nlocvars = 0;
f->locvars = NULL;
f->lineDefined = 0;
f->sizelocvars = 0;
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
f->next = L->rootproto; /* chain in list of protos */
L->rootproto = f;
return f;
}
static size_t protosize (Proto *f) {
return sizeof(Proto)
+ f->nknum*sizeof(Number)
+ f->nkstr*sizeof(TString *)
+ f->nkproto*sizeof(Proto *)
+ f->ncode*sizeof(Instruction)
+ f->nlocvars*sizeof(struct LocVar)
+ f->nlineinfo*sizeof(int);
}
void luaF_protook (lua_State *L, Proto *f, int pc) {
f->ncode = pc; /* signal that proto was properly created */
L->nblocks += protosize(f);
}
void luaF_freeproto (lua_State *L, Proto *f) {
if (f->ncode > 0) /* function was properly created? */
L->nblocks -= protosize(f);
luaM_free(L, f->code);
luaM_free(L, f->locvars);
luaM_free(L, f->kstr);
luaM_free(L, f->knum);
luaM_free(L, f->kproto);
luaM_free(L, f->lineinfo);
luaM_freearray(L, f->code, f->sizecode);
luaM_freearray(L, f->p, f->sizep);
luaM_freearray(L, f->k, f->sizek);
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
luaM_free(L, f);
}
void luaF_freeclosure (lua_State *L, Closure *c) {
L->nblocks -= sizeclosure(c->nupvalues);
luaM_free(L, c);
int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
sizeLclosure(c->l.nupvalues);
luaM_freemem(L, c, size);
}
@@ -97,11 +159,11 @@ void luaF_freeclosure (lua_State *L, Closure *c) {
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
int i;
for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number == 0)
return f->locvars[i].varname->str;
return getstr(f->locvars[i].varname);
}
}
return NULL; /* not found */

24
lfunc.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.h,v 1.12 2000/06/26 19:28:31 roberto Exp roberto $
** $Id: lfunc.h,v 2.5 2010/03/26 20:58:11 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -11,14 +11,24 @@
#include "lobject.h"
#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
cast(int, sizeof(TValue)*((n)-1)))
Proto *luaF_newproto (lua_State *L);
void luaF_protook (lua_State *L, Proto *f, int pc);
Closure *luaF_newclosure (lua_State *L, int nelems);
void luaF_freeproto (lua_State *L, Proto *f);
void luaF_freeclosure (lua_State *L, Closure *c);
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
cast(int, sizeof(TValue *)*((n)-1)))
const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, Proto *p);
LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc);
#endif

1185
lgc.c

File diff suppressed because it is too large Load Diff

132
lgc.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.h,v 1.7 1999/11/22 13:12:07 roberto Exp roberto $
** $Id: lgc.h,v 2.43 2010/06/07 16:55:34 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -9,10 +9,136 @@
#include "lobject.h"
#include "lstate.h"
/*
** Collectable objects may have one of three colors: white, which
** means the object is not marked; gray, which means the
** object is marked, but its references may be not marked; and
** black, which means that the object and all its references are marked.
** The main invariant of the garbage collector, while marking objects,
** is that a black object can never point to a white one. Moreover,
** any gray object must be in a "gray list" (gray, grayagain, weak,
** allweak, ephemeron) so that it can be visited again before finishing
** the collection cycle. These lists have no meaning when the invariant
** is not being enforced (e.g., sweep phase).
*/
void luaC_collect (lua_State *L, int all);
void luaC_checkGC (lua_State *L);
/*
** Possible states of the Garbage Collector
*/
#define GCSpropagate 0
#define GCSatomic 1
#define GCSsweepstring 2
#define GCSsweepudata 3
#define GCSsweep 4
#define GCSpause 5
#define issweepphase(g) \
(GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep)
#define isgenerational(g) ((g)->gckind == KGC_GEN)
/*
** macro to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a non-generational collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again. During a generational collection, the
** invariant must be kept all times.
*/
#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)
#define gcstopped(g) ((g)->GCdebt == MIN_LMEM)
#define stopgc(g) ((g)->GCdebt = MIN_LMEM)
/*
** some useful bit tricks
*/
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
/* Layout for bit use in `marked' field: */
#define WHITE0BIT 0 /* object is white (type 0) */
#define WHITE1BIT 1 /* object is white (type 1) */
#define BLACKBIT 2 /* object is black */
#define FINALIZEDBIT 3 /* for userdata: has been finalized */
#define SEPARATED 4 /* " ": it's in 'udgc' list or in 'tobefnz' */
#define FIXEDBIT 5 /* object is fixed (should not be collected) */
#define OLDBIT 6 /* object is old (only in generational mode) */
/* bit 7 is currently used by tests (luaL_checkmemory) */
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) testbits((x)->gch.marked, WHITEBITS)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
(!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
#define isold(x) testbit((x)->gch.marked, OLDBIT)
/* MOVE OLD rule: whenever an object is moved to the beginning of
a GC list, its old bit must be cleared */
#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT)
#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked)
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
#define luaC_checkGC(L) {condchangemem(L); if (G(L)->GCdebt > 0) luaC_step(L);}
#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrierback_(L,p); }
#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
#define luaC_objbarrierback(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }
#define luaC_barrierproto(L,p,c) \
{ if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
LUAI_FUNC void luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,
GCObject **list, int offset);
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c);
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, Udata *u);
LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv);
LUAI_FUNC void luaC_changemode (lua_State *L, int mode);
#endif

65
linit.c
View File

@@ -1,8 +1,67 @@
/*
** $Id: linit.c,v 1.5 2000/06/16 17:22:43 roberto Exp roberto $
** Initialization of libraries for lua.c
** $Id: linit.c,v 1.29 2010/10/25 14:32:36 roberto Exp roberto $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
>>>>>>> This module is now obsolete, and is not part of Lua. <<<<<<<<<
/*
** If you embed Lua in your program and need to open the standard
** libraries, call luaL_openlibs in your program. If you need a
** different set of libraries, copy this file to your project and edit
** it to suit your needs.
*/
#define linit_c
#define LUA_LIB
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};
/*
** these libs are preloaded and must be required before used
*/
static const luaL_Reg preloadedlibs[] = {
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* call open functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
/* add open functions from 'preloadedlibs' into 'package.preload' table */
luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
for (lib = preloadedlibs; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1); /* remove _PRELOAD table */
}

1091
liolib.c

File diff suppressed because it is too large Load Diff

678
llex.c
View File

@@ -1,116 +1,170 @@
/*
** $Id: llex.c,v 1.71 2000/09/27 17:41:58 roberto Exp roberto $
** $Id: llex.c,v 2.40 2010/10/25 12:24:36 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdio.h>
#include <locale.h>
#include <string.h>
#define llex_c
#define LUA_CORE
#include "lua.h"
#include "lctype.h"
#include "ldo.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "luadebug.h"
#include "lzio.h"
#define next(LS) (LS->current = zgetc(LS->z))
#define next(ls) (ls->current = zgetc(ls->z))
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
/* ORDER RESERVED */
static const char *const token2string [] = {
"and", "break", "do", "else", "elseif", "end", "for",
"function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
"until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", "<eof>"};
static const char *const luaX_tokens [] = {
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"..", "...", "==", ">=", "<=", "~=", "<eof>",
"<number>", "<name>", "<string>"
};
#define save_and_next(ls) (save(ls, ls->current), next(ls))
static void lexerror (LexState *ls, const char *msg, int token);
static void save (LexState *ls, int c) {
Mbuffer *b = ls->buff;
if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
size_t newsize;
if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
lexerror(ls, "lexical element too long", 0);
newsize = luaZ_sizebuffer(b) * 2;
luaZ_resizebuffer(ls->L, b, newsize);
}
b->buffer[luaZ_bufflen(b)++] = cast(char, c);
}
void luaX_init (lua_State *L) {
int i;
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, token2string[i]);
ts->marked = (unsigned char)(RESERVEDMARK+i); /* reserved word */
TString *ts = luaS_new(L, luaX_tokens[i]);
luaS_fix(ts); /* reserved words are never collected */
lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
ts->tsv.reserved = cast_byte(i+1); /* reserved word */
}
}
#define MAXSRC 80
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
if (val > limit) {
char buff[100];
sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
luaX_error(ls, buff, ls->t.token);
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) {
lua_assert(token == cast(unsigned char, token));
return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
luaO_pushfstring(ls->L, "char(%d)", token);
}
else {
const char *s = luaX_tokens[token - FIRST_RESERVED];
if (token < TK_EOS)
return luaO_pushfstring(ls->L, LUA_QS, s);
else
return s;
}
}
void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
char buff[MAXSRC];
luaO_chunkid(buff, ls->source->str, sizeof(buff));
luaO_verror(ls->L, "%.99s;\n last token read: `%.30s' at line %d in %.80s",
s, token, ls->linenumber, buff);
}
void luaX_error (LexState *ls, const char *s, int token) {
char buff[TOKEN_LEN];
luaX_token2str(token, buff);
if (buff[0] == '\0')
luaX_syntaxerror(ls, s, ls->L->Mbuffer);
else
luaX_syntaxerror(ls, s, buff);
}
void luaX_token2str (int token, char *s) {
if (token < 256) {
s[0] = (char)token;
s[1] = '\0';
static const char *txtToken (LexState *ls, int token) {
switch (token) {
case TK_NAME:
case TK_STRING:
case TK_NUMBER:
save(ls, '\0');
return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
default:
return luaX_token2str(ls, token);
}
else
strcpy(s, token2string[token-FIRST_RESERVED]);
}
static void luaX_invalidchar (LexState *ls, int c) {
char buff[8];
sprintf(buff, "0x%02X", c);
luaX_syntaxerror(ls, "invalid control char", buff);
static void lexerror (LexState *ls, const char *msg, int token) {
char buff[LUA_IDSIZE];
luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
if (token)
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
luaD_throw(ls->L, LUA_ERRSYNTAX);
}
static void inclinenumber (LexState *LS) {
next(LS); /* skip '\n' */
++LS->linenumber;
luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
void luaX_syntaxerror (LexState *ls, const char *msg) {
lexerror(ls, msg, ls->t.token);
}
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
LS->L = L;
LS->lookahead.token = TK_EOS; /* no look-ahead token */
LS->z = z;
LS->fs = NULL;
LS->linenumber = 1;
LS->lastline = 1;
LS->source = source;
next(LS); /* read first char */
if (LS->current == '#') {
do { /* skip first line */
next(LS);
} while (LS->current != '\n' && LS->current != EOZ);
/*
** creates a new string and anchors it in function's table so that
** it will not be collected until the end of the function's compilation
** (by that time it should be anchored in function's prototype)
*/
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
lua_State *L = ls->L;
TValue *o; /* entry for `str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
o = luaH_setstr(L, ls->fs->h, ts);
if (ttisnil(o)) {
setbvalue(o, 1); /* t[string] = true */
luaC_checkGC(L);
}
L->top--; /* remove string from stack */
return ts;
}
/*
** increment line number and skips newline sequence (any of
** \n, \r, \n\r, or \r\n)
*/
static void inclinenumber (LexState *ls) {
int old = ls->current;
lua_assert(currIsNewline(ls));
next(ls); /* skip `\n' or `\r' */
if (currIsNewline(ls) && ls->current != old)
next(ls); /* skip `\n\r' or `\r\n' */
if (++ls->linenumber >= MAX_INT)
luaX_syntaxerror(ls, "chunk has too many lines");
}
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
ls->decpoint = '.';
ls->L = L;
ls->lookahead.token = TK_EOS; /* no look-ahead token */
ls->z = z;
ls->fs = NULL;
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
ls->envn = luaS_new(L, LUA_ENV); /* create env name */
luaS_fix(ls->envn); /* never collect this name */
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
next(ls); /* read first char */
}
@@ -122,259 +176,333 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
*/
/* use Mbuffer to store names, literal strings and numbers */
#define EXTRABUFF 128
#define checkbuffer(L, n, len) if ((len)+(n) > L->Mbuffsize) \
luaO_openspace(L, (len)+(n)+EXTRABUFF)
#define save(L, c, l) (L->Mbuffer[l++] = (char)c)
#define save_and_next(L, LS, l) (save(L, LS->current, l), next(LS))
static int check_next (LexState *ls, const char *set) {
if (ls->current == '\0' || !strchr(set, ls->current))
return 0;
save_and_next(ls);
return 1;
}
static const char *readname (LexState *LS) {
lua_State *L = LS->L;
size_t l = 0;
checkbuffer(L, 10, l);
do {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
} while (isalnum(LS->current) || LS->current == '_');
save(L, '\0', l);
return L->Mbuffer;
/*
** change all characters 'from' in buffer to 'to'
*/
static void buffreplace (LexState *ls, char from, char to) {
size_t n = luaZ_bufflen(ls->buff);
char *p = luaZ_buffer(ls->buff);
while (n--)
if (p[n] == from) p[n] = to;
}
#if !defined(getlocaledecpoint)
#define getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
/*
** in case of format error, try to change decimal point separator to
** the one defined in the current locale and check again
*/
static void trydecpoint (LexState *ls, SemInfo *seminfo) {
char old = ls->decpoint;
ls->decpoint = getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
/* format error with correct decimal point: no more options */
buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
lexerror(ls, "malformed number", TK_NUMBER);
}
}
/* LUA_NUMBER */
static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
lua_State *L = LS->L;
size_t l = 0;
checkbuffer(L, 10, l);
if (comma) save(L, '.', l);
while (isdigit(LS->current)) {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
}
if (LS->current == '.') {
save_and_next(L, LS, l);
if (LS->current == '.') {
save_and_next(L, LS, l);
save(L, '\0', l);
luaX_error(LS, "ambiguous syntax"
" (decimal point x string concatenation)", TK_NUMBER);
}
}
while (isdigit(LS->current)) {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
}
if (LS->current == 'e' || LS->current == 'E') {
save_and_next(L, LS, l); /* read 'E' */
if (LS->current == '+' || LS->current == '-')
save_and_next(L, LS, l); /* optional exponent sign */
while (isdigit(LS->current)) {
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
}
}
save(L, '\0', l);
if (!luaO_str2d(L->Mbuffer, &seminfo->r))
luaX_error(LS, "malformed number", TK_NUMBER);
static void read_numeral (LexState *ls, SemInfo *seminfo) {
lua_assert(lisdigit(ls->current));
do {
save_and_next(ls);
if (check_next(ls, "EePp")) /* exponent part? */
check_next(ls, "+-"); /* optional exponent sign */
} while (lislalnum(ls->current) || ls->current == '.');
save(ls, '\0');
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
trydecpoint(ls, seminfo); /* try to update decimal point separator */
}
static void read_long_string (LexState *LS, SemInfo *seminfo) {
lua_State *L = LS->L;
int cont = 0;
size_t l = 0;
checkbuffer(L, 10, l);
save(L, '[', l); /* save first '[' */
save_and_next(L, LS, l); /* pass the second '[' */
/*
** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
** -1 if sequence is malformed
*/
static int skip_sep (LexState *ls) {
int count = 0;
int s = ls->current;
lua_assert(s == '[' || s == ']');
save_and_next(ls);
while (ls->current == '=') {
save_and_next(ls);
count++;
}
return (ls->current == s) ? count : (-count) - 1;
}
static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
save_and_next(ls); /* skip 2nd `[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
for (;;) {
checkbuffer(L, 10, l);
switch (LS->current) {
switch (ls->current) {
case EOZ:
save(L, '\0', l);
luaX_error(LS, "unfinished long string", TK_STRING);
lexerror(ls, (seminfo) ? "unfinished long string" :
"unfinished long comment", TK_EOS);
break; /* to avoid warnings */
case '[':
save_and_next(L, LS, l);
if (LS->current == '[') {
cont++;
save_and_next(L, LS, l);
case ']': {
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `]' */
goto endloop;
}
continue;
case ']':
save_and_next(L, LS, l);
if (LS->current == ']') {
if (cont == 0) goto endloop;
cont--;
save_and_next(L, LS, l);
}
continue;
case '\n':
save(L, '\n', l);
inclinenumber(LS);
continue;
default:
save_and_next(L, LS, l);
break;
}
case '\n': case '\r': {
save(ls, '\n');
inclinenumber(ls);
if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
break;
}
default: {
if (seminfo) save_and_next(ls);
else next(ls);
}
}
} endloop:
save_and_next(L, LS, l); /* skip the second ']' */
save(L, '\0', l);
seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
if (seminfo)
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
luaZ_bufflen(ls->buff) - 2*(2 + sep));
}
static void read_string (LexState *LS, int del, SemInfo *seminfo) {
lua_State *L = LS->L;
size_t l = 0;
checkbuffer(L, 10, l);
save_and_next(L, LS, l);
while (LS->current != del) {
checkbuffer(L, 10, l);
switch (LS->current) {
case EOZ: case '\n':
save(L, '\0', l);
luaX_error(LS, "unfinished string", TK_STRING);
static int hexavalue (int c) {
if (lisdigit(c)) return c - '0';
else if (lisupper(c)) return c - 'A' + 10;
else return c - 'a' + 10;
}
static int readhexaesc (LexState *ls) {
int c1, c2 = EOZ;
if (!lisxdigit(c1 = next(ls)) || !lisxdigit(c2 = next(ls))) {
luaZ_resetbuffer(ls->buff); /* prepare error message */
save(ls, '\\'); save(ls, 'x');
if (c1 != EOZ) save(ls, c1);
if (c2 != EOZ) save(ls, c2);
lexerror(ls, "hexadecimal digit expected", TK_STRING);
}
return (hexavalue(c1) << 4) + hexavalue(c2);
}
static int readdecesc (LexState *ls) {
int c1 = ls->current, c2, c3;
int c = c1 - '0';
if (lisdigit(c2 = next(ls))) {
c = 10*c + c2 - '0';
if (lisdigit(c3 = next(ls))) {
c = 10*c + c3 - '0';
if (c > UCHAR_MAX) {
luaZ_resetbuffer(ls->buff); /* prepare error message */
save(ls, '\\');
save(ls, c1); save(ls, c2); save(ls, c3);
lexerror(ls, "decimal escape too large", TK_STRING);
}
return c;
}
}
/* else, has read one character that was not a digit */
zungetc(ls->z); /* return it to input stream */
return c;
}
static void read_string (LexState *ls, int del, SemInfo *seminfo) {
save_and_next(ls); /* keep delimiter (for error messages) */
while (ls->current != del) {
switch (ls->current) {
case EOZ:
lexerror(ls, "unfinished string", TK_EOS);
break; /* to avoid warnings */
case '\\':
next(LS); /* do not save the '\' */
switch (LS->current) {
case 'a': save(L, '\a', l); next(LS); break;
case 'b': save(L, '\b', l); next(LS); break;
case 'f': save(L, '\f', l); next(LS); break;
case 'n': save(L, '\n', l); next(LS); break;
case 'r': save(L, '\r', l); next(LS); break;
case 't': save(L, '\t', l); next(LS); break;
case 'v': save(L, '\v', l); next(LS); break;
case '\n': save(L, '\n', l); inclinenumber(LS); break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
int c = 0;
int i = 0;
do {
c = 10*c + (LS->current-'0');
next(LS);
} while (++i<3 && isdigit(LS->current));
if (c != (unsigned char)c) {
save(L, '\0', l);
luaX_error(LS, "escape sequence too large", TK_STRING);
case '\n':
case '\r':
lexerror(ls, "unfinished string", TK_STRING);
break; /* to avoid warnings */
case '\\': { /* escape sequences */
int c; /* final character to be saved */
next(ls); /* do not save the `\' */
switch (ls->current) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case 'x': c = readhexaesc(ls); break;
case '\n':
case '\r': save(ls, '\n'); inclinenumber(ls); continue;
case EOZ: continue; /* will raise an error next loop */
case '*': { /* skip following span of spaces */
next(ls); /* skip the '*' */
while (lisspace(ls->current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
save(L, c, l);
continue; /* do not save 'c' */
}
default: {
if (!lisdigit(ls->current))
c = ls->current; /* handles \\, \", \', and \? */
else /* digital escape \ddd */
c = readdecesc(ls);
break;
}
default: /* handles \\, \", \', and \? */
save_and_next(L, LS, l);
}
next(ls);
save(ls, c);
break;
}
default:
save_and_next(L, LS, l);
save_and_next(ls);
}
}
save_and_next(L, LS, l); /* skip delimiter */
save(L, '\0', l);
seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
save_and_next(ls); /* skip delimiter */
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
luaZ_bufflen(ls->buff) - 2);
}
int luaX_lex (LexState *LS, SemInfo *seminfo) {
static int llex (LexState *ls, SemInfo *seminfo) {
luaZ_resetbuffer(ls->buff);
for (;;) {
switch (LS->current) {
case ' ': case '\t': case '\r': /* `\r' to avoid problems with DOS */
next(LS);
continue;
case '\n':
inclinenumber(LS);
continue;
case '$':
luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$');
switch (ls->current) {
case '\n': case '\r': { /* line breaks */
inclinenumber(ls);
break;
case '-':
next(LS);
if (LS->current != '-') return '-';
do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
continue;
case '[':
next(LS);
if (LS->current != '[') return '[';
else {
read_long_string(LS, seminfo);
}
case ' ': case '\f': case '\t': case '\v': { /* spaces */
next(ls);
break;
}
case '-': { /* '-' or '--' (comment) */
next(ls);
if (ls->current != '-') return '-';
/* else is a comment */
next(ls);
if (ls->current == '[') { /* long comment? */
int sep = skip_sep(ls);
luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
if (sep >= 0) {
read_long_string(ls, NULL, sep); /* skip long comment */
luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
break;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls->current != EOZ)
next(ls); /* skip until end of line (or end of file) */
break;
}
case '[': { /* long string or simply '[' */
int sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
case '=':
next(LS);
if (LS->current != '=') return '=';
else { next(LS); return TK_EQ; }
case '<':
next(LS);
if (LS->current != '=') return '<';
else { next(LS); return TK_LE; }
case '>':
next(LS);
if (LS->current != '=') return '>';
else { next(LS); return TK_GE; }
case '~':
next(LS);
if (LS->current != '=') return '~';
else { next(LS); return TK_NE; }
case '"':
case '\'':
read_string(LS, LS->current, seminfo);
else if (sep == -1) return '[';
else lexerror(ls, "invalid long string delimiter", TK_STRING);
}
case '=': {
next(ls);
if (ls->current != '=') return '=';
else { next(ls); return TK_EQ; }
}
case '<': {
next(ls);
if (ls->current != '=') return '<';
else { next(ls); return TK_LE; }
}
case '>': {
next(ls);
if (ls->current != '=') return '>';
else { next(ls); return TK_GE; }
}
case '~': {
next(ls);
if (ls->current != '=') return '~';
else { next(ls); return TK_NE; }
}
case '"': case '\'': { /* short literal strings */
read_string(ls, ls->current, seminfo);
return TK_STRING;
case '.':
next(LS);
if (LS->current == '.') {
next(LS);
if (LS->current == '.') {
next(LS);
return TK_DOTS; /* ... */
}
else return TK_CONCAT; /* .. */
}
case '.': { /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next(ls, ".")) {
if (check_next(ls, "."))
return TK_DOTS; /* '...' */
else return TK_CONCAT; /* '..' */
}
else if (!isdigit(LS->current)) return '.';
else {
read_number(LS, 1, seminfo);
return TK_NUMBER;
}
else if (!lisdigit(ls->current)) return '.';
/* else go through */
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
read_number(LS, 0, seminfo);
case '5': case '6': case '7': case '8': case '9': {
read_numeral(ls, seminfo);
return TK_NUMBER;
case EOZ:
}
case EOZ: {
return TK_EOS;
case '_': goto tname;
default:
if (!isalpha(LS->current)) {
int c = LS->current;
if (iscntrl(c))
luaX_invalidchar(LS, c);
next(LS);
}
default: {
if (lislalpha(ls->current)) { /* identifier or reserved word? */
TString *ts;
do {
save_and_next(ls);
} while (lislalnum(ls->current));
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
seminfo->ts = ts;
if (ts->tsv.reserved > 0) /* reserved word? */
return ts->tsv.reserved - 1 + FIRST_RESERVED;
else {
return TK_NAME;
}
}
else { /* single-char tokens (+ - / ...) */
int c = ls->current;
next(ls);
return c;
}
tname: { /* identifier or reserved word */
TString *ts = luaS_new(LS->L, readname(LS));
if (ts->marked >= RESERVEDMARK) /* reserved word? */
return ts->marked-RESERVEDMARK+FIRST_RESERVED;
seminfo->ts = ts;
return TK_NAME;
}
}
}
}
}
void luaX_next (LexState *ls) {
ls->lastline = ls->linenumber;
if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
ls->t = ls->lookahead; /* use this one */
ls->lookahead.token = TK_EOS; /* and discharge it */
}
else
ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
}
int luaX_lookahead (LexState *ls) {
lua_assert(ls->lookahead.token == TK_EOS);
ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
return ls->lookahead.token;
}

46
llex.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.30 2000/06/21 18:13:56 roberto Exp roberto $
** $Id: llex.h,v 1.64 2010/03/13 15:55:42 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -13,8 +13,8 @@
#define FIRST_RESERVED 257
/* maximum length of a reserved word (+1 for final 0) */
#define TOKEN_LEN 15
/* maximum length of a reserved word */
#define TOKEN_LEN (sizeof("function")/sizeof(char))
/*
@@ -24,19 +24,20 @@
enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_IF, TK_LOCAL,
TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_UNTIL, TK_WHILE,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
TK_STRING, TK_EOS
TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_EOS,
TK_NUMBER, TK_NAME, TK_STRING
};
/* number of reserved words */
#define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED+1))
#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
typedef union {
Number r;
lua_Number r;
TString *ts;
} SemInfo; /* semantics information */
@@ -48,25 +49,30 @@ typedef struct Token {
typedef struct LexState {
int current; /* current character */
int current; /* current character (charint) */
int linenumber; /* input line counter */
int lastline; /* line of last token `consumed' */
Token t; /* current token */
Token lookahead; /* look ahead token */
struct FuncState *fs; /* `FuncState' is private to the parser */
struct lua_State *L;
struct zio *z; /* input stream */
int linenumber; /* input line counter */
int lastline; /* line of last token `consumed' */
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
struct Varlist *varl; /* list of all active local variables */
TString *source; /* current source name */
TString *envn; /* environment variable name */
char decpoint; /* locale decimal point */
} LexState;
void luaX_init (lua_State *L);
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
int luaX_lex (LexState *LS, SemInfo *seminfo);
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
void luaX_error (LexState *ls, const char *s, int token);
void luaX_token2str (int token, char *s);
LUAI_FUNC void luaX_init (lua_State *L);
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
TString *source);
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next (LexState *ls);
LUAI_FUNC int luaX_lookahead (LexState *ls);
LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
#endif

359
llimits.h
View File

@@ -1,6 +1,6 @@
/*
** $Id: llimits.h,v 1.18 2000/10/09 13:47:32 roberto Exp roberto $
** Limits, basic types, and some other "installation-dependent" definitions
** $Id: llimits.h,v 1.83 2010/11/03 15:16:17 roberto Exp roberto $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -12,193 +12,270 @@
#include <stddef.h>
/*
** try to find number of bits in an integer
*/
#ifndef BITS_INT
/* avoid overflows in comparison */
#if INT_MAX-20 < 32760
#define BITS_INT 16
#else
#if INT_MAX > 2147483640L
/* machine has at least 32 bits */
#define BITS_INT 32
#else
#error "you must define BITS_INT with number of bits in an integer"
#endif
#endif
#endif
#include "lua.h"
/*
** Define the type `number' of Lua
** GREP LUA_NUMBER to change that
*/
#ifndef LUA_NUM_TYPE
#define LUA_NUM_TYPE double
#endif
typedef unsigned LUA_INT32 lu_int32;
typedef LUA_NUM_TYPE Number;
typedef LUAI_UMEM lu_mem;
/* function to convert a Number to a string */
#define NUMBER_FMT "%.16g" /* LUA_NUMBER */
#define lua_number2str(s,n) sprintf((s), NUMBER_FMT, (n))
/* function to convert a string to a Number */
#define lua_str2number(s,p) strtod((s), (p))
typedef LUAI_MEM l_mem;
typedef unsigned long lint32; /* unsigned int with at least 32 bits */
/* chars used as small naturals (so that `char' is reserved for characters) */
typedef unsigned char lu_byte;
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
#define MIN_LMEM ((l_mem)~((~(lu_mem)0)>>1))
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
/*
** conversion of pointer to int (for hashing only)
** (the shift removes bits that are usually 0 because of alignment)
** conversion of pointer to integer
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define IntPoint(p) (((unsigned long)(p)) >> 3)
#define MINPOWER2 4 /* minimum size for "growing" vectors */
#ifndef DEFAULT_STACK_SIZE
#define DEFAULT_STACK_SIZE 1024
#endif
#define IntPoint(p) ((unsigned int)(lu_mem)(p))
/* type to ensure maximum alignment */
union L_Umaxalign { double d; char *s; long l; };
#if !defined(LUAI_USER_ALIGNMENT_T)
#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
#endif
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
/* result of a `usual argument conversion' over lua_Number */
typedef LUAI_UACNUMBER l_uacNumber;
/* internal assertions for in-house debugging */
#if defined(lua_assert)
#define check_exp(c,e) (lua_assert(c), (e))
#else
#define lua_assert(c) /* empty */
#define check_exp(c,e) (e)
#endif
/*
** assertion for checking API calls
*/
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(L,e) { (void)L; assert(e); }
#elif !defined(luai_apicheck)
#define luai_apicheck(L,e) lua_assert(e)
#endif
#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
#if !defined(UNUSED)
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif
#define cast(t, exp) ((t)(exp))
#define cast_byte(i) cast(lu_byte, (i))
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))
/*
** maximum depth for nested C calls and syntactical nested non-terminals
** in a program. (Value must fit in an unsigned short int.)
*/
#if !defined(LUAI_MAXCCALLS)
#define LUAI_MAXCCALLS 200
#endif
/*
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in an unsigned char.)
*/
#define MAXUPVAL UCHAR_MAX
/*
** type for virtual-machine instructions
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
** For a very small machine, you may change that to 2 bytes (and adjust
** the following limits accordingly)
*/
typedef unsigned long Instruction;
typedef lu_int32 Instruction;
/*
** size and position of opcode arguments.
** For an instruction with 2 bytes, size is 16, and size_b can be 5
** (accordingly, size_u will be 10, and size_a will be 5)
*/
#define SIZE_INSTRUCTION 32
#define SIZE_B 9
#define SIZE_OP 6
#define SIZE_U (SIZE_INSTRUCTION-SIZE_OP)
#define POS_U SIZE_OP
#define POS_B SIZE_OP
#define SIZE_A (SIZE_INSTRUCTION-(SIZE_OP+SIZE_B))
#define POS_A (SIZE_OP+SIZE_B)
/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in BITS_INT-1 bits (-1 for sign)
*/
#if SIZE_U < BITS_INT-1
#define MAXARG_U ((1<<SIZE_U)-1)
#define MAXARG_S (MAXARG_U>>1) /* `S' is signed */
#else
#define MAXARG_U MAX_INT
#define MAXARG_S MAX_INT
#endif
#if SIZE_A < BITS_INT-1
#define MAXARG_A ((1<<SIZE_A)-1)
#else
#define MAXARG_A MAX_INT
#endif
#if SIZE_B < BITS_INT-1
#define MAXARG_B ((1<<SIZE_B)-1)
#else
#define MAXARG_B MAX_INT
#endif
/* maximum stack size in a function */
#ifndef MAXSTACK
/* maximum stack for a Lua function */
#define MAXSTACK 250
#endif
#if MAXSTACK > MAXARG_B
#undef MAXSTACK
#define MAXSTACK MAXARG_B
/* minimum size for the string table (must be power of 2) */
#if !defined(MINSTRTABSIZE)
#define MINSTRTABSIZE 32
#endif
/* maximum number of local variables */
#ifndef MAXLOCALS
#define MAXLOCALS 200 /* arbitrary limit (<MAXSTACK) */
#endif
#if MAXLOCALS>=MAXSTACK
#undef MAXLOCALS
#define MAXLOCALS (MAXSTACK-1)
/* minimum size for string buffer */
#if !defined(LUA_MINBUFFER)
#define LUA_MINBUFFER 32
#endif
/* maximum number of upvalues */
#ifndef MAXUPVALUES
#define MAXUPVALUES 32 /* arbitrary limit (<=MAXARG_B) */
#if !defined(lua_lock)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
#if MAXUPVALUES>MAXARG_B
#undef MAXUPVALUES
#define MAXUPVALUES MAXARG_B
#if !defined(luai_threadyield)
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif
/* maximum number of variables in the left side of an assignment */
#ifndef MAXVARSLH
#define MAXVARSLH 100 /* arbitrary limit (<MULT_RET) */
/*
** these macros allow user-specific actions on threads when you defined
** LUAI_EXTRASPACE and need to do something extra when a thread is
** created/deleted/resumed/yielded.
*/
#if !defined(luai_userstateopen)
#define luai_userstateopen(L) ((void)L)
#endif
#if MAXVARSLH>=MULT_RET
#undef MAXVARSLH
#define MAXVARSLH (MULT_RET-1)
#if !defined(luai_userstateclose)
#define luai_userstateclose(L) ((void)L)
#endif
#if !defined(luai_userstatethread)
#define luai_userstatethread(L,L1) ((void)L)
#endif
#if !defined(luai_userstatefree)
#define luai_userstatefree(L,L1) ((void)L)
#endif
#if !defined(luai_userstateresume)
#define luai_userstateresume(L,n) ((void)L)
#endif
#if !defined(luai_userstateyield)
#define luai_userstateyield(L,n) ((void)L)
#endif
/*
** lua_number2int is a macro to convert lua_Number to int.
** lua_number2integer is a macro to convert lua_Number to lua_Integer.
** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned.
** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number.
*/
#if defined(MS_ASMTRICK) /* { */
/* trick with Microsoft assembler for X86 */
#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i}
#define lua_number2integer(i,n) lua_number2int(i, n)
#define lua_number2unsigned(i,n) \
{__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
#elif defined(LUA_IEEE754TRICK) /* }{ */
/* the next trick should work on any machine using IEEE754 with
a 32-bit integer type */
union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
#if !defined(LUA_IEEEENDIAN) /* { */
#define LUAI_EXTRAIEEE \
static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
#define LUA_IEEEENDIAN (ieeeendian.l_p[1] == 33)
#else
#define LUAI_EXTRAIEEE /* empty */
#endif /* } */
#define lua_number2int32(i,n,t) \
{ LUAI_EXTRAIEEE \
volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
(i) = (t)u.l_p[LUA_IEEEENDIAN]; }
#define lua_number2int(i,n) lua_number2int32(i, n, int)
#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer)
#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned)
#endif /* } */
/* the following definitions always work, but may be slow */
#if !defined(lua_number2int)
#define lua_number2int(i,n) ((i)=(int)(n))
#endif
#if !defined(lua_number2integer)
#define lua_number2integer(i,n) ((i)=(lua_Integer)(n))
#endif
#if !defined(lua_number2unsigned) /* { */
/* the following definition assures proper modulo behavior */
#if defined(LUA_NUMBER_DOUBLE)
#include <math.h>
#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
#define lua_number2unsigned(i,n) \
((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
#else
#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n))
#endif
#endif /* } */
#if !defined(lua_unsigned2number)
/* on several machines, coercion from unsigned to double is slow,
so it may be worth to avoid */
#define lua_unsigned2number(u) \
(((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
#endif
/* maximum number of parameters in a function */
#ifndef MAXPARAMS
#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
#endif
#if MAXPARAMS>=MAXLOCALS
#undef MAXPARAMS
#define MAXPARAMS (MAXLOCALS-1)
/*
** luai_hashnum is a macro do hash a lua_Number value into an integer.
** The hash must be deterministic and give reasonable values for
** both small and large values (outside the range of integers).
** It is used only in ltable.c.
*/
#if !defined(luai_hashnum) /* { */
#include <float.h>
#include <math.h>
#define luai_hashnum(i,n) { int e; \
n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \
lua_number2int(i, n); i += e; }
#endif /* } */
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#if !defined(HARDSTACKTESTS)
#define condmovestack(L) ((void)0)
#else
/* realloc stack keeping its size */
#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize)
#endif
/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 64
#if LFIELDS_PER_FLUSH>(MAXSTACK/4)
#undef LFIELDS_PER_FLUSH
#define LFIELDS_PER_FLUSH (MAXSTACK/4)
#if !defined(HARDMEMTESTS)
#define condchangemem(L) condmovestack(L)
#else
#define condchangemem(L) \
((void)(gcstopped(G(L)) || (luaC_fullgc(L, 0), 1)))
#endif
/* number of record items to accumulate before a SETMAP instruction */
/* (each item counts 2 elements on the stack: an index and a value) */
#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2)
/* maximum lookback to find a real constant (for code generation) */
#ifndef LOOKBACKNUMS
#define LOOKBACKNUMS 20 /* arbitrary constant */
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmathlib.c,v 1.31 2000/10/27 16:15:53 roberto Exp roberto $
** $Id: lmathlib.c,v 1.78 2010/11/12 15:47:34 roberto Exp roberto $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -8,6 +8,9 @@
#include <stdlib.h>
#include <math.h>
#define lmathlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
@@ -19,119 +22,153 @@
#define RADIANS_PER_DEGREE (PI/180.0)
/*
** If you want Lua to operate in radians (instead of degrees),
** define RADIANS
*/
#ifdef RADIANS
#define FROMRAD(a) (a)
#define TORAD(a) (a)
#else
#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
/* macro 'l_tg' allows the addition of an 'l' or 'f' to all math operations */
#if !defined(l_tg)
#define l_tg(x) (x)
#endif
static int math_abs (lua_State *L) {
lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
lua_pushnumber(L, l_tg(fabs)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
lua_pushnumber(L, l_tg(sin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sinh (lua_State *L) {
lua_pushnumber(L, l_tg(sinh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cos (lua_State *L) {
lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
lua_pushnumber(L, l_tg(cos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cosh (lua_State *L) {
lua_pushnumber(L, l_tg(cosh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tan (lua_State *L) {
lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
lua_pushnumber(L, l_tg(tan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tanh (lua_State *L) {
lua_pushnumber(L, l_tg(tanh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_asin (lua_State *L) {
lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
lua_pushnumber(L, l_tg(asin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_acos (lua_State *L) {
lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
lua_pushnumber(L, l_tg(acos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan (lua_State *L) {
lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
lua_pushnumber(L, l_tg(atan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan2 (lua_State *L) {
lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
lua_pushnumber(L, l_tg(atan2)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_ceil (lua_State *L) {
lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
lua_pushnumber(L, l_tg(ceil)(luaL_checknumber(L, 1)));
return 1;
}
static int math_floor (lua_State *L) {
lua_pushnumber(L, floor(luaL_check_number(L, 1)));
lua_pushnumber(L, l_tg(floor)(luaL_checknumber(L, 1)));
return 1;
}
static int math_mod (lua_State *L) {
lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
static int math_fmod (lua_State *L) {
lua_pushnumber(L, l_tg(fmod)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_modf (lua_State *L) {
lua_Number ip;
lua_Number fp = l_tg(modf)(luaL_checknumber(L, 1), &ip);
lua_pushnumber(L, ip);
lua_pushnumber(L, fp);
return 2;
}
static int math_sqrt (lua_State *L) {
lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
lua_pushnumber(L, l_tg(sqrt)(luaL_checknumber(L, 1)));
return 1;
}
static int math_pow (lua_State *L) {
lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
lua_pushnumber(L, l_tg(pow)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_log (lua_State *L) {
lua_pushnumber(L, log(luaL_check_number(L, 1)));
lua_Number x = luaL_checknumber(L, 1);
lua_Number res;
if (lua_isnoneornil(L, 2))
res = l_tg(log)(x);
else {
lua_Number base = luaL_checknumber(L, 2);
if (base == 10.0) res = l_tg(log10)(x);
else res = l_tg(log)(x)/l_tg(log)(base);
}
lua_pushnumber(L, res);
return 1;
}
static int math_log10 (lua_State *L) {
lua_pushnumber(L, log10(luaL_check_number(L, 1)));
#if !defined(LUA_COMPAT_LOG10)
return luaL_error(L, "function " LUA_QL("log10")
" is deprecated; use log(x, 10) instead");
#else
lua_pushnumber(L, l_tg(log10)(luaL_checknumber(L, 1)));
return 1;
#endif
}
static int math_exp (lua_State *L) {
lua_pushnumber(L, exp(luaL_check_number(L, 1)));
lua_pushnumber(L, l_tg(exp)(luaL_checknumber(L, 1)));
return 1;
}
static int math_deg (lua_State *L) {
lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
return 1;
}
static int math_rad (lua_State *L) {
lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
return 1;
}
static int math_frexp (lua_State *L) {
int e;
lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
lua_pushnumber(L, e);
lua_pushnumber(L, l_tg(frexp)(luaL_checknumber(L, 1), &e));
lua_pushinteger(L, e);
return 2;
}
static int math_ldexp (lua_State *L) {
lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
lua_pushnumber(L, l_tg(ldexp)(luaL_checknumber(L, 1),
luaL_checkint(L, 2)));
return 1;
}
@@ -139,10 +176,10 @@ static int math_ldexp (lua_State *L) {
static int math_min (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
double dmin = luaL_check_number(L, 1);
lua_Number dmin = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
double d = luaL_check_number(L, i);
lua_Number d = luaL_checknumber(L, i);
if (d < dmin)
dmin = d;
}
@@ -153,10 +190,10 @@ static int math_min (lua_State *L) {
static int math_max (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
double dmax = luaL_check_number(L, 1);
lua_Number dmax = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
double d = luaL_check_number(L, i);
lua_Number d = luaL_checknumber(L, i);
if (d > dmax)
dmax = d;
}
@@ -166,73 +203,82 @@ static int math_max (lua_State *L) {
static int math_random (lua_State *L) {
/* the '%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
/* the `%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
lua_pushnumber(L, r); /* Number between 0 and 1 */
break;
}
case 1: { /* only upper limit */
int u = luaL_check_int(L, 1);
luaL_arg_check(L, 1<=u, 1, "interval is empty");
lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */
lua_Number u = luaL_checknumber(L, 1);
luaL_argcheck(L, 1.0 <= u, 1, "interval is empty");
lua_pushnumber(L, l_tg(floor)(r*u) + 1.0); /* int in [1, u] */
break;
}
case 2: { /* lower and upper limits */
int l = luaL_check_int(L, 1);
int u = luaL_check_int(L, 2);
luaL_arg_check(L, l<=u, 2, "interval is empty");
lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */
lua_Number l = luaL_checknumber(L, 1);
lua_Number u = luaL_checknumber(L, 2);
luaL_argcheck(L, l <= u, 2, "interval is empty");
lua_pushnumber(L, l_tg(floor)(r*(u-l+1)) + l); /* int in [l, u] */
break;
}
default: lua_error(L, "wrong number of arguments");
default: return luaL_error(L, "wrong number of arguments");
}
return 1;
}
static int math_randomseed (lua_State *L) {
srand(luaL_check_int(L, 1));
srand(luaL_checkunsigned(L, 1));
(void)rand(); /* discard first value to avoid undesirable correlations */
return 0;
}
static const struct luaL_reg mathlib[] = {
{"abs", math_abs},
{"sin", math_sin},
{"cos", math_cos},
{"tan", math_tan},
{"asin", math_asin},
{"acos", math_acos},
{"atan", math_atan},
{"atan2", math_atan2},
{"ceil", math_ceil},
{"floor", math_floor},
{"mod", math_mod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"sqrt", math_sqrt},
{"min", math_min},
{"max", math_max},
{"log", math_log},
{"log10", math_log10},
{"exp", math_exp},
{"deg", math_deg},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed}
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
{"asin", math_asin},
{"atan2", math_atan2},
{"atan", math_atan},
{"ceil", math_ceil},
{"cosh", math_cosh},
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
{"floor", math_floor},
{"fmod", math_fmod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"log10", math_log10},
{"log", math_log},
{"max", math_max},
{"min", math_min},
{"modf", math_modf},
{"pow", math_pow},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
{"sinh", math_sinh},
{"sin", math_sin},
{"sqrt", math_sqrt},
{"tanh", math_tanh},
{"tan", math_tan},
{NULL, NULL}
};
/*
** Open math library
*/
LUALIB_API void lua_mathlibopen (lua_State *L) {
luaL_openl(L, mathlib);
lua_pushcfunction(L, math_pow);
lua_settagmethod(L, LUA_TNUMBER, "pow");
LUAMOD_API int luaopen_math (lua_State *L) {
luaL_newlib(L, mathlib);
lua_pushnumber(L, PI);
lua_setglobal(L, "PI");
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
return 1;
}

192
lmem.c
View File

@@ -1,150 +1,120 @@
/*
** $Id: lmem.c,v 1.38 2000/10/26 12:47:05 roberto Exp roberto $
** $Id: lmem.c,v 1.78 2010/05/04 18:10:02 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <stddef.h>
#define lmem_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#ifdef LUA_DEBUG
/*
** {======================================================================
** Controlled version for realloc.
** =======================================================================
** About the realloc function:
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** (`osize' is the old size, `nsize' is the new size)
**
** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
** matter 'x').
**
** * frealloc(ud, p, x, 0) frees the block `p'
** (in this specific case, frealloc must return NULL);
** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ANSI C)
**
** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/
#include <assert.h>
#include <limits.h>
#include <string.h>
#define realloc(b, s) debug_realloc(b, s)
#define malloc(b) debug_realloc(NULL, b)
#define free(b) debug_realloc(b, 0)
#define MINSIZEARRAY 4
/* ensures maximum alignment for HEADER */
#define HEADER (sizeof(union L_Umaxalign))
#define MARKSIZE 16
#define MARK 0x55 /* 01010101 (a nice pattern) */
#define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
unsigned long memdebug_numblocks = 0;
unsigned long memdebug_total = 0;
unsigned long memdebug_maxmem = 0;
unsigned long memdebug_memlimit = LONG_MAX;
static void *checkblock (void *block) {
unsigned long *b = blocksize(block);
unsigned long size = *b;
int i;
for (i=0;i<MARKSIZE;i++)
assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */
memdebug_numblocks--;
memdebug_total -= size;
return b;
}
static void freeblock (void *block) {
if (block) {
size_t size = *blocksize(block);
block = checkblock(block);
memset(block, -1, size+HEADER+MARKSIZE); /* erase block */
(free)(block); /* free original block */
void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
int limit, const char *what) {
void *newblock;
int newsize;
if (*size >= limit/2) { /* cannot double it? */
if (*size >= limit) /* cannot grow even a little? */
luaG_runerror(L, "too many %s (limit is %d)", what, limit);
newsize = limit; /* still have at least one free place */
}
}
static void *debug_realloc (void *block, size_t size) {
if (size == 0) {
freeblock(block);
return NULL;
}
else if (memdebug_total+size > memdebug_memlimit)
return NULL; /* to test memory allocation errors */
else {
size_t realsize = HEADER+size+MARKSIZE;
char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
int i;
if (realsize < size) return NULL; /* overflow! */
if (newblock == NULL) return NULL;
if (block) {
size_t oldsize = *blocksize(block);
if (oldsize > size) oldsize = size;
memcpy(newblock+HEADER, block, oldsize);
freeblock(block); /* erase (and check) old copy */
}
memdebug_total += size;
if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total;
memdebug_numblocks++;
*(unsigned long *)newblock = size;
for (i=0;i<MARKSIZE;i++)
*(newblock+HEADER+size+i) = (char)(MARK+i);
return newblock+HEADER;
newsize = (*size)*2;
if (newsize < MINSIZEARRAY)
newsize = MINSIZEARRAY; /* minimum size */
}
newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
*size = newsize; /* update only when everything else is OK */
return newblock;
}
/* }====================================================================== */
#endif
/*
** Real ISO (ANSI) systems do not need these tests;
** but some systems (Sun OS) are not that ISO...
*/
#ifdef OLD_ANSI
#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
#define free(b) if (b) (free)(b)
#endif
void *luaM_growaux (lua_State *L, void *block, size_t nelems,
int inc, size_t size, const char *errormsg, size_t limit) {
size_t newn = nelems+inc;
if (nelems >= limit-inc) lua_error(L, errormsg);
if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */
(nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */
return block; /* do not need to reallocate */
else /* it crossed a power-of-2 boundary; grow to next power */
return luaM_realloc(L, block, luaO_power2(newn)*size);
void *luaM_toobig (lua_State *L) {
luaG_runerror(L, "memory allocation error: block too big");
return NULL; /* to avoid warnings */
}
/*
** generic allocation routine.
*/
void *luaM_realloc (lua_State *L, void *block, lint32 size) {
if (size == 0) {
free(block); /* block may be NULL; that is OK for free */
return NULL;
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
void *newblock;
global_State *g = G(L);
size_t realosize = (block) ? osize : 0;
lua_assert((realosize == 0) == (block == NULL));
#if defined(HARDMEMTESTS)
if (nsize > realosize && !gcstopped(g))
luaC_fullgc(L, 1); /* force a GC whenever possible */
#endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) {
api_check(L, nsize > realosize,
"realloc cannot fail when shrinking a block");
if (!gcstopped(g)) {
luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
}
if (newblock == NULL)
luaD_throw(L, LUA_ERRMEM);
}
else if (size >= MAX_SIZET)
lua_error(L, "memory allocation error: block too big");
block = realloc(block, size);
if (block == NULL) {
if (L)
luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */
else return NULL; /* error before creating state! */
lua_assert((nsize == 0) == (newblock == NULL));
g->totalbytes = (g->totalbytes - realosize) + nsize;
if (!gcstopped(g))
g->GCdebt += nsize; /* give some credit to garbage collector */
#if defined(TRACEMEM)
{ /* auxiliary patch to monitor garbage collection.
** To plot, gnuplot with following command:
** plot TRACEMEM using 1:2 with lines, TRACEMEM using 1:3 with lines
*/
static unsigned long total = 0; /* our "time" */
static FILE *f = NULL; /* output file */
total++; /* "time" always grows */
if ((total % 200) == 0) {
if (f == NULL) f = fopen(TRACEMEM, "w");
fprintf(f, "%lu %u %d %d\n", total,
g->totalbytes,
gcstopped(g) ? 0 : g->GCdebt,
g->gcstate * 1000);
}
}
return block;
#endif
return newblock;
}

46
lmem.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.h,v 1.15 2000/08/07 18:39:16 roberto Exp roberto $
** $Id: lmem.h,v 1.35 2009/12/16 16:42:58 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -13,30 +13,38 @@
#include "llimits.h"
#include "lua.h"
void *luaM_realloc (lua_State *L, void *oldblock, lint32 size);
void *luaM_growaux (lua_State *L, void *block, size_t nelems,
int inc, size_t size, const char *errormsg,
size_t limit);
#define luaM_free(L, b) luaM_realloc(L, (b), 0)
#define luaM_malloc(L, t) luaM_realloc(L, NULL, (t))
#define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(lint32)sizeof(t)))
#define luaM_reallocv(L,b,on,n,e) \
((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
luaM_toobig(L))
#define luaM_growvector(L, v,nelems,inc,t,e,l) \
((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0]))
#define luaM_reallocvector(L, v,n,t) \
((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t)))
#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L,n,t) \
cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
#ifdef LUA_DEBUG
extern unsigned long memdebug_numblocks;
extern unsigned long memdebug_total;
extern unsigned long memdebug_maxmem;
extern unsigned long memdebug_memlimit;
#endif
#define luaM_growvector(L,v,nelems,size,t,limit,e) \
if ((nelems)+1 > (size)) \
((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
#define luaM_reallocvector(L, v,oldn,n,t) \
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
LUAI_FUNC void *luaM_toobig (lua_State *L);
/* not to be called directly */
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
size_t size);
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
size_t size_elem, int limit,
const char *what);
#endif

653
loadlib.c Normal file
View File

@@ -0,0 +1,653 @@
/*
** $Id: loadlib.c,v 1.93 2010/11/10 18:05:36 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
** This module contains an implementation of loadlib for Unix systems
** that have dlfcn, an implementation for Windows, and a stub for other
** systems.
*/
#include <stdlib.h>
#include <string.h>
#define loadlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** LUA_PATH and LUA_CPATH are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH)
#define LUA_PATH "LUA_PATH"
#endif
#if !defined(LUA_CPATH)
#define LUA_CPATH "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX
#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined (LUA_PATH_SEP)
#define LUA_PATH_SEP ";"
#endif
#if !defined (LUA_PATH_MARK)
#define LUA_PATH_MARK "?"
#endif
#if !defined (LUA_EXEC_DIR)
#define LUA_EXEC_DIR "!"
#endif
#if !defined (LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
/* separator for open functions in C libraries */
#define LUA_OFSEP "_"
#define LIBPREFIX "LOADLIB: "
#define POF LUA_POF
#define LIB_FAIL "open"
/* error codes for ll_loadfunc */
#define ERRLIB 1
#define ERRFUNC 2
#define setprogdir(L) ((void)0)
/*
** system-dependent functions
*/
static void ll_unloadlib (void *lib);
static void *ll_load (lua_State *L, const char *path, int seeglb);
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
#if defined(LUA_USE_DLOPEN)
/*
** {========================================================================
** This is an implementation of loadlib based on the dlfcn interface.
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
** as an emulation layer on top of native functions.
** =========================================================================
*/
#include <dlfcn.h>
static void ll_unloadlib (void *lib) {
dlclose(lib);
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : 0));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
if (f == NULL) lua_pushstring(L, dlerror());
return f;
}
/* }====================================================== */
#elif defined(LUA_DL_DLL)
/*
** {======================================================================
** This is an implementation of loadlib for Windows using native functions.
** =======================================================================
*/
#include <windows.h>
#undef setprogdir
/*
** optional flags for LoadLibraryEx
*/
#if !defined(LUA_LLE_FLAGS)
#define LUA_LLE_FLAGS 0
#endif
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer), NULL))
lua_pushstring(L, buffer);
else
lua_pushfstring(L, "system error %d\n", error);
}
static void ll_unloadlib (void *lib) {
FreeLibrary((HMODULE)lib);
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
(void)(seeglb); /* symbols are 'global' by default */
if (lib == NULL) pusherror(L);
return lib;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
if (f == NULL) pusherror(L);
return f;
}
/* }====================================================== */
#else
/*
** {======================================================
** Fallback for other systems
** =======================================================
*/
#undef LIB_FAIL
#define LIB_FAIL "absent"
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
static void ll_unloadlib (void *lib) {
(void)(lib); /* to avoid warnings */
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
(void)(path); (void)(seeglb); /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
(void)(lib); (void)(sym); /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}
/* }====================================================== */
#endif
static void **ll_register (lua_State *L, const char *path) {
void **plib;
lua_pushfstring(L, "%s%s", LIBPREFIX, path);
lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
if (!lua_isnil(L, -1)) /* is there an entry? */
plib = (void **)lua_touserdata(L, -1);
else { /* no entry yet; create one */
lua_pop(L, 1); /* remove result from gettable */
plib = (void **)lua_newuserdata(L, sizeof(const void *));
*plib = NULL;
luaL_setmetatable(L, "_LOADLIB");
lua_pushfstring(L, "%s%s", LIBPREFIX, path);
lua_pushvalue(L, -2);
lua_settable(L, LUA_REGISTRYINDEX);
}
return plib;
}
/*
** __gc tag method: calls library's `ll_unloadlib' function with the lib
** handle
*/
static int gctm (lua_State *L) {
void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
if (*lib) ll_unloadlib(*lib);
*lib = NULL; /* mark library as closed */
return 0;
}
static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
void **reg = ll_register(L, path);
if (*reg == NULL) *reg = ll_load(L, path, *sym == '*');
if (*reg == NULL) return ERRLIB; /* unable to load library */
if (*sym == '*') { /* loading only library (no function)? */
lua_pushboolean(L, 1); /* return 'true' */
return 0; /* no errors */
}
else {
lua_CFunction f = ll_sym(L, *reg, sym);
if (f == NULL)
return ERRFUNC; /* unable to find function */
lua_pushcfunction(L, f); /* else create new function */
return 0; /* no errors */
}
}
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
int stat = ll_loadfunc(L, path, init);
if (stat == 0) /* no errors? */
return 1; /* return the loaded function */
else { /* error; error message is on stack top */
lua_pushnil(L);
lua_insert(L, -2);
lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
return 3; /* return nil, error message, and where */
}
}
/*
** {======================================================
** 'require' function
** =======================================================
*/
static int readable (const char *filename) {
FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL) return 0; /* open failed */
fclose(f);
return 1;
}
static const char *pushnexttemplate (lua_State *L, const char *path) {
const char *l;
while (*path == *LUA_PATH_SEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */
l = strchr(path, *LUA_PATH_SEP); /* find next separator */
if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
}
static const char *searchpath (lua_State *L, const char *name,
const char *path) {
name = luaL_gsub(L, name, ".", LUA_DIRSEP);
lua_pushliteral(L, ""); /* error accumulator */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
lua_concat(L, 2); /* add entry to possible error message */
}
return NULL; /* not found */
}
static int ll_searchpath (lua_State *L) {
const char *f = searchpath(L, luaL_checkstring(L, 1), luaL_checkstring(L, 2));
if (f != NULL) return 1;
else { /* error message is on top of the stack */
lua_pushnil(L);
lua_insert(L, -2);
return 2; /* return nil + error message */
}
}
static const char *findfile (lua_State *L, const char *name,
const char *pname) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
return searchpath(L, name, path);
}
static void loaderror (lua_State *L, const char *filename) {
luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
static int loader_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path");
if (filename == NULL) return 1; /* library not found in this path */
if (luaL_loadfile(L, filename) != LUA_OK)
loaderror(L, filename);
return 1; /* library loaded successfully */
}
static int loadfunc (lua_State *L, const char *filename, const char *modname) {
const char *funcname;
const char *mark;
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
mark = strchr(modname, *LUA_IGMARK);
if (mark) {
int stat;
funcname = lua_pushlstring(L, modname, mark - modname);
funcname = lua_pushfstring(L, POF"%s", funcname);
stat = ll_loadfunc(L, filename, funcname);
if (stat != ERRFUNC) return stat;
modname = mark + 1; /* else go ahead and try old-style name */
}
funcname = lua_pushfstring(L, POF"%s", modname);
return ll_loadfunc(L, filename, funcname);
}
static int loader_C (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
const char *filename = findfile(L, name, "cpath");
if (filename == NULL) return 1; /* library not found in this path */
if (loadfunc(L, filename, name) != 0)
loaderror(L, filename);
return 1; /* library loaded successfully */
}
static int loader_Croot (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
filename = findfile(L, lua_tostring(L, -1), "cpath");
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
if (stat != ERRFUNC) loaderror(L, filename); /* real error */
lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
name, filename);
return 1; /* function not found */
}
return 1;
}
static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
lua_getfield(L, -1, name);
if (lua_isnil(L, -1)) /* not found? */
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
return 1;
}
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
int i;
lua_settop(L, 1); /* _LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, 2, name);
if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */
/* else must load it; iterate over available loaders */
lua_getfield(L, lua_upvalueindex(1), "loaders");
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.loaders") " must be a table");
lua_pushliteral(L, ""); /* error message accumulator */
for (i=1; ; i++) {
lua_rawgeti(L, -2, i); /* get a loader */
if (lua_isnil(L, -1))
luaL_error(L, "module " LUA_QS " not found:%s",
name, lua_tostring(L, -2));
lua_pushstring(L, name);
lua_call(L, 1, 1); /* call it */
if (lua_isfunction(L, -1)) /* did it find module? */
break; /* module loaded successfully */
else if (lua_isstring(L, -1)) /* loader returned error message? */
lua_concat(L, 2); /* accumulate it */
else
lua_pop(L, 1);
}
lua_pushstring(L, name); /* pass name as argument to module */
lua_call(L, 1, 1); /* run loaded module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
lua_getfield(L, 2, name);
if (lua_isnil(L, -1)) { /* module did not set a value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
}
return 1;
}
/* }====================================================== */
/*
** {======================================================
** 'module' function
** =======================================================
*/
#if defined(LUA_COMPAT_MODULE)
/*
** changes the environment variable of calling function
*/
static void set_env (lua_State *L) {
lua_Debug ar;
if (lua_getstack(L, 1, &ar) == 0 ||
lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
luaL_error(L, LUA_QL("module") " not called from a Lua function");
lua_pushvalue(L, -2); /* copy new environment table to top */
lua_setupvalue(L, -2, 1);
lua_pop(L, 1); /* remove function */
}
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
lua_pushvalue(L, i); /* get option (a function) */
lua_pushvalue(L, -2); /* module */
lua_call(L, 1, 0);
}
}
static void modinit (lua_State *L, const char *modname) {
const char *dot;
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_M"); /* module._M = module */
lua_pushstring(L, modname);
lua_setfield(L, -2, "_NAME");
dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL) dot = modname;
else dot++;
/* set _PACKAGE as package name (full module name minus last part) */
lua_pushlstring(L, modname, dot - modname);
lua_setfield(L, -2, "_PACKAGE");
}
static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
int lastarg = lua_gettop(L); /* last parameter */
luaL_pushmodule(L, modname, 1); /* get/create module table */
/* check whether table already has a _NAME field */
lua_getfield(L, -1, "_NAME");
if (!lua_isnil(L, -1)) /* is table an initialized module? */
lua_pop(L, 1);
else { /* no; initialize it */
lua_pop(L, 1);
modinit(L, modname);
}
lua_pushvalue(L, -1);
set_env(L);
dooptions(L, lastarg);
return 1;
}
static int ll_seeall (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1)) {
lua_createtable(L, 0, 1); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushglobaltable(L);
lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
#else
static int ll_seeall (lua_State *L) {
return luaL_error(L, "deprecated function");
}
static int ll_module (lua_State *L) {
return luaL_error(L, "deprecated function");
}
#endif
/* }====================================================== */
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
if (path == NULL) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"searchpath", ll_searchpath},
{"seeall", ll_seeall},
{NULL, NULL}
};
static const luaL_Reg ll_funcs[] = {
{"module", ll_module},
{"require", ll_require},
{NULL, NULL}
};
static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
LUAMOD_API int luaopen_package (lua_State *L) {
int i;
/* create new type _LOADLIB */
luaL_newmetatable(L, "_LOADLIB");
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc");
/* create `package' table */
luaL_newlib(L, pk_funcs);
/* create `loaders' table */
lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
/* fill it with pre-defined loaders */
for (i=0; loaders[i] != NULL; i++) {
lua_pushvalue(L, -2); /* set 'package' as upvalue for all loaders */
lua_pushcclosure(L, loaders[i], 1);
lua_rawseti(L, -2, i+1);
}
lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
/* set field 'path' */
setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
/* set field 'cpath' */
setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
/* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
lua_setfield(L, -2, "config");
/* set field `loaded' */
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED");
lua_setfield(L, -2, "loaded");
/* set field `preload' */
luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
lua_setfield(L, -2, "preload");
lua_pushglobaltable(L);
lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
lua_pop(L, 1); /* pop global table */
return 1; /* return 'package' table */
}

266
lobject.c
View File

@@ -1,125 +1,241 @@
/*
** $Id: lobject.c,v 1.54 2000/10/10 19:53:20 roberto Exp roberto $
** $Id: lobject.c,v 2.42 2010/10/29 11:13:14 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lobject_c
#define LUA_CORE
#include "lua.h"
#include "lctype.h"
#include "ldebug.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "lvm.h"
const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
const char *const luaO_typenames[] = {
"userdata", "nil", "number", "string", "table", "function"
};
LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
/*
** returns smaller power of 2 larger than `n' (minimum is MINPOWER2)
** converts an integer to a "floating point byte", represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee != 0 and (xxx) otherwise.
*/
lint32 luaO_power2 (lint32 n) {
lint32 p = MINPOWER2;
while (p<=n) p<<=1;
return p;
int luaO_int2fb (lu_int32 x) {
int e = 0; /* exponent */
if (x < 8) return x;
while (x >= 0x10) {
x = (x+1) >> 1;
e++;
}
return ((e+1) << 3) | (cast_int(x) - 8);
}
int luaO_equalObj (const TObject *t1, const TObject *t2) {
/* converts back */
int luaO_fb2int (int x) {
int e = (x >> 3) & 0x1f;
if (e == 0) return x;
else return ((x & 7) + 8) << (e - 1);
}
int luaO_ceillog2 (unsigned int x) {
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = 0;
x--;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
}
int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
if (ttype(t1) != ttype(t2)) return 0;
switch (ttype(t1)) {
else switch (ttype(t1)) {
case LUA_TNIL:
return 1;
case LUA_TNUMBER:
return nvalue(t1) == nvalue(t2);
case LUA_TSTRING: case LUA_TUSERDATA:
return tsvalue(t1) == tsvalue(t2);
case LUA_TTABLE:
return hvalue(t1) == hvalue(t2);
case LUA_TFUNCTION:
return clvalue(t1) == clvalue(t2);
return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
return pvalue(t1) == pvalue(t2);
case LUA_TSTRING:
return rawtsvalue(t1) == rawtsvalue(t2);
case LUA_TLCF:
return fvalue(t1) == fvalue(t2);
default:
LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type");
return 1; /* LUA_TNIL */
lua_assert(iscollectable(t1));
return gcvalue(t1) == gcvalue(t2);
}
}
char *luaO_openspace (lua_State *L, size_t n) {
if (n > L->Mbuffsize) {
luaM_reallocvector(L, L->Mbuffer, n, char);
L->nblocks += (n - L->Mbuffsize)*sizeof(char);
L->Mbuffsize = n;
lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
switch (op) {
case LUA_OPADD: return luai_numadd(NULL, v1, v2);
case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
case LUA_OPUNM: return luai_numunm(NULL, v1);
default: lua_assert(0); return 0;
}
return L->Mbuffer;
}
int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */
static int checkend (const char *s, const char *endptr) {
if (endptr == s) return 0; /* no characters converted */
while (lisspace(cast(unsigned char, *endptr))) endptr++;
return (*endptr == '\0'); /* OK if no trailing characters */
}
int luaO_str2d (const char *s, lua_Number *result) {
char *endptr;
Number res = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* no conversion */
while (isspace((unsigned char)*endptr)) endptr++;
if (*endptr != '\0') return 0; /* invalid trailing characters? */
*result = res;
return 1;
*result = lua_str2number(s, &endptr);
if (checkend(s, endptr)) return 1; /* conversion OK? */
*result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */
return checkend(s, endptr);
}
/* maximum length of a string format for `luaO_verror' */
#define MAX_VERROR 280
/* this function needs to handle only '%d' and '%.XXs' formats */
void luaO_verror (lua_State *L, const char *fmt, ...) {
va_list argp;
char buff[MAX_VERROR]; /* to hold formatted message */
va_start(argp, fmt);
vsprintf(buff, fmt, argp);
va_end(argp);
lua_error(L, buff);
static void pushstr (lua_State *L, const char *str, size_t l) {
setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
incr_top(L);
}
void luaO_chunkid (char *out, const char *source, int bufflen) {
if (*source == '=') {
strncpy(out, source+1, bufflen); /* remove first char */
out[bufflen-1] = '\0'; /* ensures null termination */
}
else {
if (*source == '@') {
int l;
source++; /* skip the `@' */
bufflen -= sizeof("file `...%s'");
l = strlen(source);
if (l>bufflen) {
source += (l-bufflen); /* get last part of file name */
sprintf(out, "file `...%.99s'", source);
/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 0;
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
incr_top(L);
switch (*(e+1)) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
pushstr(L, s, strlen(s));
break;
}
else
sprintf(out, "file `%.99s'", source);
case 'c': {
char buff;
buff = cast(char, va_arg(argp, int));
pushstr(L, &buff, 1);
break;
}
case 'd': {
setnvalue(L->top, cast_num(va_arg(argp, int)));
incr_top(L);
break;
}
case 'f': {
setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
incr_top(L);
break;
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
int l = sprintf(buff, "%p", va_arg(argp, void *));
pushstr(L, buff, l);
break;
}
case '%': {
pushstr(L, "%", 1);
break;
}
default: {
luaG_runerror(L,
"invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
*(e + 1));
break;
}
}
n += 2;
fmt = e+2;
}
pushstr(L, fmt, strlen(fmt));
if (n > 0) luaV_concat(L, n + 1);
return svalue(L->top - 1);
}
const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
const char *msg;
va_list argp;
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
return msg;
}
#define LL(x) (sizeof(x) - 1)
#define RETS "..."
#define PRE "[string \""
#define POS "\"]"
#define addstr(a,b,l) ( memcpy(a,b,l), a += (l) )
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
size_t l = strlen(source);
if (*source == '=') { /* 'literal' source */
if (l <= bufflen) /* small enough? */
memcpy(out, source + 1, l);
else { /* truncate it */
addstr(out, source + 1, bufflen - 1);
*out = '\0';
}
}
else if (*source == '@') { /* file name */
if (l <= bufflen) /* small enough? */
memcpy(out, source + 1, l);
else { /* add '...' before rest of name */
addstr(out, RETS, LL(RETS));
bufflen -= LL(RETS);
memcpy(out, source + 1 + l - bufflen, bufflen);
}
}
else { /* string; format as [string "source"] */
const char *nl = strchr(source, '\n'); /* find first new line (if any) */
addstr(out, PRE, LL(PRE)); /* add prefix */
bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nl == NULL) { /* small one-line source? */
addstr(out, source, l); /* keep it */
}
else {
int len = strcspn(source, "\n"); /* stop at first newline */
bufflen -= sizeof("string \"%.*s...\"");
if (len > bufflen) len = bufflen;
if (source[len] != '\0') { /* must truncate? */
strcpy(out, "string \"");
out += strlen(out);
strncpy(out, source, len);
strcpy(out+len, "...\"");
}
else
sprintf(out, "string \"%.99s\"", source);
if (nl != NULL) l = nl - source; /* stop at first newline */
if (l > bufflen) l = bufflen;
addstr(out, source, l);
addstr(out, RETS, LL(RETS));
}
memcpy(out, POS, LL(POS) + 1);
}
}

487
lobject.h
View File

@@ -1,129 +1,272 @@
/*
** $Id: lobject.h,v 1.81 2000/10/30 16:29:59 roberto Exp roberto $
** $Id: lobject.h,v 2.41 2010/06/04 13:25:10 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
#ifndef lobject_h
#define lobject_h
#include <stdarg.h>
#include "llimits.h"
#include "lua.h"
#ifdef LUA_DEBUG
#undef NDEBUG
#include <assert.h>
#define LUA_INTERNALERROR(s) assert(((void)s,0))
#define LUA_ASSERT(c,s) assert(((void)s,(c)))
#else
#define LUA_INTERNALERROR(s) /* empty */
#define LUA_ASSERT(c,s) /* empty */
#endif
/*
** Extra tags for non-values
*/
#define LUA_TPROTO LUA_NUMTAGS
#define LUA_TUPVAL (LUA_NUMTAGS+1)
#define LUA_TDEADKEY (LUA_NUMTAGS+2)
#ifdef LUA_DEBUG
/* to avoid warnings, and make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
#else
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif
/*
** Variant tag for light C functions (negative to be considered
** non collectable by 'iscollectable')
*/
#define LUA_TLCF (~0x0F | LUA_TFUNCTION)
/*
** Union of all collectable objects
*/
typedef union GCObject GCObject;
/* mark for closures active in the stack */
#define LUA_TMARK 6
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/* tags for values visible from Lua == first user-created tag */
#define NUM_TAGS 6
/*
** Common header in struct form
*/
typedef struct GCheader {
CommonHeader;
} GCheader;
/* check whether `t' is a mark */
#define is_T_MARK(t) ((t) == LUA_TMARK)
/*
** Union of all Lua values
*/
typedef union {
struct TString *ts; /* LUA_TSTRING, LUA_TUSERDATA */
struct Closure *cl; /* LUA_TFUNCTION */
struct Hash *a; /* LUA_TTABLE */
struct CallInfo *i; /* LUA_TLMARK */
Number n; /* LUA_TNUMBER */
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
lua_Number n; /* numbers */
int b; /* booleans */
lua_CFunction f; /* light C functions */
} Value;
/*
** Tagged Values. This is the basic representation of values in Lua,
** an actual value plus a tag with its type.
*/
#define TValuefields Value value_; int tt_
typedef struct lua_TValue {
TValuefields;
} TValue;
/* macro defining a nil value */
#define NILCONSTANT {NULL}, LUA_TNIL
/*
** type tag of a TValue
*/
#define ttype(o) ((o)->tt_)
/*
** type tag of a TValue with no variants
*/
#define ttypenv(o) (ttype(o) & 0x0F)
/* Macros to test type */
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
#define ttistable(o) (ttype(o) == LUA_TTABLE)
#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION)
#define ttisclosure(o) (ttype(o) == LUA_TFUNCTION)
#define ttislcf(o) (ttype(o) == LUA_TLCF)
#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
#define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY)
/* Macros to access values */
#define ttype(o) ((o)->ttype)
#define nvalue(o) ((o)->value.n)
#define tsvalue(o) ((o)->value.ts)
#define clvalue(o) ((o)->value.cl)
#define hvalue(o) ((o)->value.a)
#define infovalue(o) ((o)->value.i)
#define svalue(o) (tsvalue(o)->str)
#define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p)
#define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n)
#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value_.gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv)
#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u)
#define uvalue(o) (&rawuvalue(o)->uv)
#define clvalue(o) check_exp(ttisclosure(o), &(o)->value_.gc->cl)
#define fvalue(o) check_exp(ttislcf(o), (o)->value_.f)
#define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h)
#define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b)
#define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th)
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
typedef struct lua_TObject {
int ttype;
Value value;
} TObject;
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
/* Macros for internal tests */
#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt)
#define checkconsistency(obj) lua_assert(!iscollectable(obj) || righttt(obj))
#define checkliveness(g,obj) \
lua_assert(!iscollectable(obj) || (righttt(obj) && !isdead(g,gcvalue(obj))))
/* Macros to set values */
#define setnilvalue(obj) ((obj)->tt_=LUA_TNIL)
#define setnvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; }
#define setfvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value_.f=(x); i_o->tt_=LUA_TLCF; }
#define changenvalue(o,x) check_exp((o)->tt_==LUA_TNUMBER, (o)->value_.n=(x))
#define setpvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value_.p=(x); i_o->tt_=LUA_TLIGHTUSERDATA; }
#define setbvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value_.b=(x); i_o->tt_=LUA_TBOOLEAN; }
#define setsvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TSTRING; \
checkliveness(G(L),i_o); }
#define setuvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TUSERDATA; \
checkliveness(G(L),i_o); }
#define setthvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TTHREAD; \
checkliveness(G(L),i_o); }
#define setclvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TFUNCTION; \
checkliveness(G(L),i_o); }
#define sethvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TTABLE; \
checkliveness(G(L),i_o); }
#define setptvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TPROTO; \
checkliveness(G(L),i_o); }
#define setdeadvalue(obj) ((obj)->tt_=LUA_TDEADKEY)
#define setobj(L,obj1,obj2) \
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
o1->value_ = o2->value_; o1->tt_=o2->tt_; \
checkliveness(G(L),o1); }
/*
** String headers for string table
** different types of assignments, according to destination
*/
/* from stack to (same) stack */
#define setobjs2s setobj
/* to stack (not from same stack) */
#define setobj2s setobj
#define setsvalue2s setsvalue
#define sethvalue2s sethvalue
#define setptvalue2s setptvalue
/* from table to same table */
#define setobjt2t setobj
/* to table */
#define setobj2t setobj
/* to new object */
#define setobj2n setobj
#define setsvalue2n setsvalue
typedef TValue *StkId; /* index to stack elements */
/*
** most `malloc' libraries allocate memory in blocks of 8 bytes. TSPACK
** tries to make sizeof(TString) a multiple of this granularity, to reduce
** waste of space.
** Header for string value; string bytes follow the end of this structure
*/
#define TSPACK ((int)sizeof(int))
typedef struct TString {
union {
struct { /* for strings */
unsigned long hash;
int constindex; /* hint to reuse constants */
} s;
struct { /* for userdata */
int tag;
void *value;
} d;
} u;
size_t len;
struct TString *nexthash; /* chain for hash table */
int marked;
char str[TSPACK]; /* variable length string!! must be the last field! */
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
struct {
CommonHeader;
lu_byte reserved;
unsigned int hash;
size_t len;
} tsv;
} TString;
/* get the actual string (array of bytes) from a TString */
#define getstr(ts) cast(const char *, (ts) + 1)
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(rawtsvalue(o))
/*
** Function Prototypes
** Header for userdata; memory area follows the end of this structure
*/
typedef struct Proto {
Number *knum; /* Number numbers used by the function */
int nknum; /* size of `knum' */
struct TString **kstr; /* strings used by the function */
int nkstr; /* size of `kstr' */
struct Proto **kproto; /* functions defined inside the function */
int nkproto; /* size of `kproto' */
Instruction *code;
int ncode; /* size of `code'; when 0 means an incomplete `Proto' */
short numparams;
short is_vararg;
short maxstacksize;
short marked;
struct Proto *next;
/* debug information */
int *lineinfo; /* map from opcodes to source lines */
int nlineinfo; /* size of `lineinfo' */
int nlocvars;
struct LocVar *locvars; /* information about local variables */
int lineDefined;
TString *source;
} Proto;
typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
CommonHeader;
struct Table *metatable;
struct Table *env;
size_t len;
} uv;
} Udata;
/*
** Description of an upvalue for function prototypes
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
lu_byte instack; /* whether it is in stack */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
/*
** Description of a local variable for function prototypes
** (used for debug information)
*/
typedef struct LocVar {
TString *varname;
int startpc; /* first point where variable is active */
@@ -132,73 +275,145 @@ typedef struct LocVar {
/*
** Closures
** Function Prototypes
*/
typedef struct Closure {
union {
lua_CFunction c; /* C functions */
struct Proto *l; /* Lua functions */
} f;
struct Closure *next;
struct Closure *mark; /* marked closures (point to itself when not marked) */
short isC; /* 0 for Lua functions, 1 for C functions */
short nupvalues;
TObject upvalue[1];
} Closure;
typedef struct Proto {
CommonHeader;
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines */
LocVar *locvars; /* information about local variables */
Upvaldesc *upvalues; /* upvalue information */
union Closure *cache; /* last created closure with this prototype */
TString *source;
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of `k' */
int sizecode;
int sizelineinfo;
int sizep; /* size of `p' */
int sizelocvars;
int linedefined;
int lastlinedefined;
GCObject *gclist;
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg;
lu_byte maxstacksize; /* maximum stack used by this function */
} Proto;
#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)
typedef struct Node {
TObject key;
TObject val;
struct Node *next; /* for chaining */
} Node;
typedef struct Hash {
Node *node;
int htag;
int size;
Node *firstfree; /* this position is free; all positions after it are full */
struct Hash *next;
struct Hash *mark; /* marked tables (point to itself when not marked) */
} Hash;
/* unmarked tables and closures are represented by pointing `mark' to
** themselves
*/
#define ismarked(x) ((x)->mark != (x))
/*
** informations about a call (for debugging)
** Lua Upvalues
*/
typedef struct CallInfo {
struct Closure *func; /* function being called */
const Instruction **pc; /* current pc of called function */
int lastpc; /* last pc traced */
int line; /* current line */
int refi; /* current index in `lineinfo' */
} CallInfo;
typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
union {
TValue value; /* the value (when closed) */
struct { /* double linked list (when open) */
struct UpVal *prev;
struct UpVal *next;
} l;
} u;
} UpVal;
extern const TObject luaO_nilobject;
extern const char *const luaO_typenames[];
/*
** Closures
*/
#define ClosureHeader \
CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1]; /* list of upvalues */
} CClosure;
#define luaO_typename(o) (luaO_typenames[ttype(o)])
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
UpVal *upvals[1]; /* list of upvalues */
} LClosure;
lint32 luaO_power2 (lint32 n);
char *luaO_openspace (lua_State *L, size_t n);
typedef union Closure {
CClosure c;
LClosure l;
} Closure;
int luaO_equalObj (const TObject *t1, const TObject *t2);
int luaO_str2d (const char *s, Number *result);
void luaO_verror (lua_State *L, const char *fmt, ...);
void luaO_chunkid (char *out, const char *source, int len);
#define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC)
#define getproto(o) (clvalue(o)->l.p)
/*
** Tables
*/
typedef union TKey {
struct {
TValuefields;
struct Node *next; /* for chaining */
} nk;
TValue tvk;
} TKey;
typedef struct Node {
TValue i_val;
TKey i_key;
} Node;
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
GCObject *gclist;
int sizearray; /* size of `array' array */
} Table;
/*
** `module' operation for hashing (size is always a power of 2)
*/
#define lmod(s,size) \
(check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
#define twoto(x) (1<<(x))
#define sizenode(t) (twoto((t)->lsizenode))
/*
** (address of) a fixed nil value
*/
#define luaO_nilobject (&luaO_nilobject_)
LUAI_DDEC const TValue luaO_nilobject_;
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
LUAI_FUNC int luaO_ceillog2 (lu_int32 x);
LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2);
LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
#endif

106
lopcodes.c Normal file
View File

@@ -0,0 +1,106 @@
/*
** $Id: lopcodes.c,v 1.43 2010/03/12 19:14:06 roberto Exp roberto $
** See Copyright Notice in lua.h
*/
#define lopcodes_c
#define LUA_CORE
#include "lopcodes.h"
/* ORDER OP */
LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"MOVE",
"LOADK",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"GETTABUP",
"GETTABLE",
"SETTABUP",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
"SELF",
"ADD",
"SUB",
"MUL",
"DIV",
"MOD",
"POW",
"UNM",
"NOT",
"LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
"TESTSET",
"CALL",
"TAILCALL",
"RETURN",
"FORLOOP",
"FORPREP",
"TFORCALL",
"TFORLOOP",
"SETLIST",
"CLOSE",
"CLOSURE",
"VARARG",
"EXTRAARG",
NULL
};
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
};

View File

@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.67 2000/08/29 14:48:16 roberto Exp roberto $
** $Id: lopcodes.h,v 1.136 2010/10/13 16:45:54 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -12,33 +12,72 @@
/*===========================================================================
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits. Moreover,
an instruction can have 0, 1, or 2 arguments. Instructions can
have the following types:
type 0: no arguments
type 1: 1 unsigned argument in the higher bits (called `U')
type 2: 1 signed argument in the higher bits (`S')
type 3: 1st unsigned argument in the higher bits (`A')
2nd unsigned argument in the middle bits (`B')
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
'Ax' : 26 bits ('A', 'B', and 'C' together)
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx
A signed argument is represented in excess K; that is, the number
value is the unsigned value minus K. K is exactly the maximum value
for that argument (so that -max is represented by 0, and +max is
represented by 2*max), which is half the maximum for the corresponding
unsigned argument.
The size of each argument is defined in `llimits.h'. The usual is an
instruction with 32 bits, U arguments with 26 bits (32-6), B arguments
with 9 bits, and A arguments with 17 bits (32-6-9). For small
installations, the instruction size can be 16, so U has 10 bits,
and A and B have 5 bits each.
===========================================================================*/
enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8
#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
#define SIZE_OP 6
#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C
#define POS_Ax POS_A
/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
*/
#if SIZE_Bx < LUAI_BITSINT-1
#define MAXARG_Bx ((1<<SIZE_Bx)-1)
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
#else
#define MAXARG_Bx MAX_INT
#define MAXARG_sBx MAX_INT
#endif
#if SIZE_Ax < LUAI_BITSINT-1
#define MAXARG_Ax ((1<<SIZE_Ax)-1)
#else
#define MAXARG_Ax MAX_INT
#endif
#define MAXARG_A ((1<<SIZE_A)-1)
#define MAXARG_B ((1<<SIZE_B)-1)
#define MAXARG_C ((1<<SIZE_C)-1)
/* creates a mask with `n' 1 bits at position `p' */
#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p))
/* creates a mask with `n' 0 bits at position `p' */
#define MASK0(n,p) (~MASK1(n,p))
@@ -47,122 +86,204 @@
** the following macros help to manipulate instructions
*/
#define CREATE_0(o) ((Instruction)(o))
#define GET_OPCODE(i) ((OpCode)((i)&MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | (Instruction)(o)))
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
#define CREATE_U(o,u) ((Instruction)(o) | ((Instruction)(u)<<POS_U))
#define GETARG_U(i) ((int)((i)>>POS_U))
#define SETARG_U(i,u) ((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
((Instruction)(u)<<POS_U)))
#define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0)))
#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
((cast(Instruction, v)<<pos)&MASK1(size,pos))))
#define CREATE_S(o,s) CREATE_U((o),(s)+MAXARG_S)
#define GETARG_S(i) (GETARG_U(i)-MAXARG_S)
#define SETARG_S(i,s) SETARG_U((i),(s)+MAXARG_S)
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A)
#define GETARG_B(i) getarg(i, POS_B, SIZE_B)
#define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B)
#define GETARG_C(i) getarg(i, POS_C, SIZE_C)
#define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C)
#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx)
#define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx)
#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax)
#define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax)
#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<POS_A) \
| ((Instruction)(b)<<POS_B))
#define GETARG_A(i) ((int)((i)>>POS_A))
#define SETARG_A(i,a) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
((Instruction)(a)<<POS_A)))
#define GETARG_B(i) ((int)(((i)>>POS_B) & MASK1(SIZE_B,0)))
#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
((Instruction)(b)<<POS_B)))
#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_A) \
| (cast(Instruction, b)<<POS_B) \
| (cast(Instruction, c)<<POS_C))
#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_A) \
| (cast(Instruction, bc)<<POS_Bx))
#define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_Ax))
/*
** K = U argument used as index to `kstr'
** J = S argument used as jump offset (relative to pc of next instruction)
** L = unsigned argument used as index of local variable
** N = U argument used as index to `knum'
** Macros to operate RK indices
*/
/* this bit 1 means constant (0 means register) */
#define BITRK (1 << (SIZE_B - 1))
/* test whether value is a constant */
#define ISK(x) ((x) & BITRK)
/* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK)
#define MAXINDEXRK (BITRK - 1)
/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)
/*
** invalid register that fits in 8 bits
*/
#define NO_REG MAXARG_A
/*
** R(x) - register
** Kst(x) - constant (in constant table)
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
*/
/*
** grep "ORDER OP" if you change these enums
*/
typedef enum {
/*----------------------------------------------------------------------
name args stack before stack after side effects
name args description
------------------------------------------------------------------------*/
OP_END,/* - - (return) no results */
OP_RETURN,/* U v_n-v_x(at u) (return) returns v_x-v_n */
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADK,/* A Bx R(A) := Kst(Bx - 1) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
OP_CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */
OP_TAILCALL,/* A B v_n-v_1 f(at a) (return) f(v1,...,v_n) */
OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
OP_PUSHNIL,/* U - nil_1-nil_u */
OP_POP,/* U a_u-a_1 - */
OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_PUSHINT,/* S - (Number)s */
OP_PUSHSTRING,/* K - KSTR[k] */
OP_PUSHNUM,/* N - KNUM[n] */
OP_PUSHNEGNUM,/* N - -KNUM[n] */
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
OP_PUSHUPVALUE,/* U - Closure[u] */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_GETLOCAL,/* L - LOC[l] */
OP_GETGLOBAL,/* K - VAR[KSTR[k]] */
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */
OP_GETTABLE,/* - i t t[i] */
OP_GETDOTTED,/* K t t[KSTR[k]] */
OP_GETINDEXED,/* L t t[LOC[l]] */
OP_PUSHSELF,/* K t t t[KSTR[k]] */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
OP_CREATETABLE,/* U - newarray(size = u) */
OP_JMP,/* sBx pc+=sBx */
OP_SETLOCAL,/* L x - LOC[l]=x */
OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */
OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */
OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_ADD,/* - y x x+y */
OP_ADDI,/* S x x+s */
OP_SUB,/* - y x x-y */
OP_MULT,/* - y x x*y */
OP_DIV,/* - y x x/y */
OP_POW,/* - y x x^y */
OP_CONCAT,/* U v_u-v_1 v1..-..v_u */
OP_MINUS,/* - x -x */
OP_NOT,/* - x (x==nil)? 1 : nil */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_JMPNE,/* J y x - (x~=y)? PC+=s */
OP_JMPEQ,/* J y x - (x==y)? PC+=s */
OP_JMPLT,/* J y x - (x<y)? PC+=s */
OP_JMPLE,/* J y x - (x<y)? PC+=s */
OP_JMPGT,/* J y x - (x>y)? PC+=s */
OP_JMPGE,/* J y x - (x>=y)? PC+=s */
OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_JMPT,/* J x - (x~=nil)? PC+=s */
OP_JMPF,/* J x - (x==nil)? PC+=s */
OP_JMPONT,/* J x (x~=nil)? x : - (x~=nil)? PC+=s */
OP_JMPONF,/* J x (x==nil)? x : - (x==nil)? PC+=s */
OP_JMP,/* J - - PC+=s */
OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
OP_PUSHNILJMP,/* - - nil PC++; */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_FORPREP,/* J */
OP_FORLOOP,/* J */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
OP_LFORPREP,/* J */
OP_LFORLOOP,/* J */
OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
} OpCode;
#define NUM_OPCODES ((int)OP_CLOSURE+1)
#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)
#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1)
/* special code to fit a LUA_MULTRET inside an argB */
#define MULT_RET 255 /* (<=MAXARG_B) */
#if MULT_RET>MAXARG_B
#undef MULT_RET
#define MULT_RET MAXARG_B
#endif
/*===========================================================================
Notes:
(*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is
set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
OP_SETLIST) may use `top'.
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to `top'.
(*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
'instruction' is EXTRAARG(real C).
(*) In OP_LOADK, if (Bx == 0) then next 'instruction' is EXTRAARG(real Bx).
(*) For comparisons, A specifies what condition the test should accept
(true or false).
(*) All `skips' (pc++) assume that next instruction is a jump.
===========================================================================*/
/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test (next instruction must be a jump)
*/
enum OpArgMask {
OpArgN, /* argument is not used */
OpArgU, /* argument is used */
OpArgR, /* argument is a register or a jump offset */
OpArgK /* argument is a constant or register/constant */
};
LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 50
#endif

313
loslib.c Normal file
View File

@@ -0,0 +1,313 @@
/*
** $Id: loslib.c,v 1.31 2010/07/02 12:01:53 roberto Exp roberto $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define loslib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** list of valid conversion specifiers @* for the 'strftime' function
*/
#if !defined(LUA_STRFTIMEOPTIONS)
#if !defined(LUA_USE_POSIX)
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
#else
#define LUA_STRFTIMEOPTIONS { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
"E", "cCxXyY", \
"O", "deHImMSuUVwWy" }
#endif
#endif
/*
** By default, Lua uses tmpnam except when POSIX is available, where it
** uses mkstemp.
*/
#if defined(LUA_USE_MKSTEMP)
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#define lua_tmpnam(b,e) { \
strcpy(b, "/tmp/lua_XXXXXX"); \
e = mkstemp(b); \
if (e != -1) close(e); \
e = (e == -1); }
#elif !defined(lua_tmpnam)
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
lua_pushfstring(L, "%s: %s", filename, strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
static int os_execute (lua_State *L) {
lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
return 1;
}
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return os_pushresult(L, remove(filename) == 0, filename);
}
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return os_pushresult(L, rename(fromname, toname) == 0, fromname);
}
static int os_tmpname (lua_State *L) {
char buff[LUA_TMPNAMBUFSIZE];
int err;
lua_tmpnam(buff, err);
if (err)
return luaL_error(L, "unable to generate a unique filename");
lua_pushstring(L, buff);
return 1;
}
static int os_getenv (lua_State *L) {
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
return 1;
}
static int os_clock (lua_State *L) {
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
return 1;
}
/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
lua_getfield(L, -1, key);
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
static int getfield (lua_State *L, const char *key, int d) {
int res, isnum;
lua_getfield(L, -1, key);
res = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum) {
if (d < 0)
return luaL_error(L, "field " LUA_QS " missing in date table", key);
res = d;
}
lua_pop(L, 1);
return res;
}
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
static const char *const options[] = LUA_STRFTIMEOPTIONS;
unsigned int i;
for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
buff[1] = *conv;
if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
buff[2] = '\0'; /* end buffer */
return conv + 1;
}
else if (*(conv + 1) != '\0' &&
strchr(options[i + 1], *(conv + 1)) != NULL) {
buff[2] = *(conv + 1); /* valid two-char conversion specifier */
buff[3] = '\0'; /* end buffer */
return conv + 2;
}
}
}
luaL_argerror(L, 1,
lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
return conv; /* to avoid warnings */
}
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm *stm;
if (*s == '!') { /* UTC? */
stm = gmtime(&t);
s++; /* skip `!' */
}
else
stm = localtime(&t);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon+1);
setfield(L, "year", stm->tm_year+1900);
setfield(L, "wday", stm->tm_wday+1);
setfield(L, "yday", stm->tm_yday+1);
setboolfield(L, "isdst", stm->tm_isdst);
}
else {
char cc[4];
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
while (*s) {
if (*s != '%') /* no conversion specifier? */
luaL_addchar(&b, *s++);
else {
size_t reslen;
char buff[200]; /* should be big enough for any conversion result */
s = checkoption(L, s + 1, cc);
reslen = strftime(buff, sizeof(buff), cc, stm);
luaL_addlstring(&b, buff, reslen);
}
}
luaL_pushresult(&b);
}
return 1;
}
static int os_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, "sec", 0);
ts.tm_min = getfield(L, "min", 0);
ts.tm_hour = getfield(L, "hour", 12);
ts.tm_mday = getfield(L, "day", -1);
ts.tm_mon = getfield(L, "month", -1) - 1;
ts.tm_year = getfield(L, "year", -1) - 1900;
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
}
if (t == (time_t)(-1))
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)t);
return 1;
}
static int os_difftime (lua_State *L) {
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, 0))));
return 1;
}
/* }====================================================== */
static int os_setlocale (lua_State *L) {
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, "all", catnames);
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}
static int os_exit (lua_State *L) {
int status;
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
status = luaL_optint(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
exit(status);
}
static const luaL_Reg syslib[] = {
{"clock", os_clock},
{"date", os_date},
{"difftime", os_difftime},
{"execute", os_execute},
{"exit", os_exit},
{"getenv", os_getenv},
{"remove", os_remove},
{"rename", os_rename},
{"setlocale", os_setlocale},
{"time", os_time},
{"tmpname", os_tmpname},
{NULL, NULL}
};
/* }====================================================== */
LUAMOD_API int luaopen_os (lua_State *L) {
luaL_newlib(L, syslib);
return 1;
}

1651
lparser.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,13 @@
/*
** $Id: lparser.h,v 1.25 2000/09/29 12:42:13 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** $Id: lparser.h,v 1.64 2010/07/02 20:42:40 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
#ifndef lparser_h
#define lparser_h
#include "llimits.h"
#include "lobject.h"
#include "lzio.h"
@@ -16,45 +17,81 @@
*/
typedef enum {
VGLOBAL,
VLOCAL,
VINDEXED,
VEXP
VVOID, /* no value */
VNIL,
VTRUE,
VFALSE,
VK, /* info = index of constant in `k' */
VKNUM, /* nval = numerical value */
VNONRELOC, /* info = result register */
VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in 'upvalues' */
VINDEXED, /* t = table register/upvalue; idx = index R/K */
VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */
VCALL, /* info = instruction pc */
VVARARG /* info = instruction pc */
} expkind;
#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
typedef struct expdesc {
expkind k;
union {
int index; /* VGLOBAL: `kstr' index of global name; VLOCAL: stack index */
struct {
int t; /* patch list of `exit when true' */
int f; /* patch list of `exit when false' */
} l;
struct { /* for indexed variables (VINDEXED) */
short idx; /* index (R/K) */
lu_byte t; /* table (register or upvalue) */
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
} ind;
int info; /* for generic use */
lua_Number nval; /* for VKNUM */
} u;
int t; /* patch list of `exit when true' */
int f; /* patch list of `exit when false' */
} expdesc;
typedef struct vardesc {
unsigned short idx;
} vardesc;
/* list of all active local variables */
typedef struct Varlist {
vardesc *actvar;
int nactvar;
int actvarsize;
} Varlist;
struct BlockCnt; /* defined in lparser.c */
/* state needed to generate code for a given function */
typedef struct FuncState {
Proto *f; /* current function header */
Table *h; /* table to find (and reuse) elements in `k' */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
struct lua_State *L; /* copy of the Lua state */
int pc; /* next position to code */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
int lasttarget; /* `pc' of last `jump target' */
int jlt; /* list of jumps to `lasttarget' */
short stacklevel; /* number of values on activation register */
short nactloc; /* number of active local variables */
short nupvalues; /* number of upvalues */
int lastline; /* line where last `lineinfo' was generated */
struct Breaklabel *bl; /* chain of breakable blocks */
expdesc upvalues[MAXUPVALUES]; /* upvalues */
int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
int jpc; /* list of pending jumps to `pc' */
int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
int firstlocal; /* index of first local var of this function */
short nlocvars; /* number of elements in `locvars' */
lu_byte nactvar; /* number of active local variables */
lu_byte nups; /* number of upvalues */
} FuncState;
Proto *luaY_parser (lua_State *L, ZIO *z);
LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
Varlist *varl, const char *name);
#endif

316
lstate.c
View File

@@ -1,15 +1,21 @@
/*
** $Id: lstate.c,v 1.47 2000/10/26 12:47:05 roberto Exp roberto $
** $Id: lstate.c,v 2.85 2010/04/30 18:36:22 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <stddef.h>
#define lstate_c
#define LUA_CORE
#include "lua.h"
#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
@@ -19,103 +25,261 @@
#include "ltm.h"
#ifdef LUA_DEBUG
static lua_State *lua_state = NULL;
void luaB_opentests (lua_State *L);
#if !defined(LUAI_GCPAUSE)
#define LUAI_GCPAUSE 200 /* 200% */
#endif
#if !defined(LUAI_GCMAJOR)
#define LUAI_GCMAJOR 200 /* 200% */
#endif
#if !defined(LUAI_GCMUL)
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
#endif
#define MEMERRMSG "not enough memory"
/*
** built-in implementation for ERRORMESSAGE. In a "correct" environment
** ERRORMESSAGE should have an external definition, and so this function
** would not be used.
** thread state + extra space
*/
static int errormessage (lua_State *L) {
const char *s = lua_tostring(L, 1);
if (s == NULL) s = "(no message)";
fprintf(stderr, "error: %s\n", s);
return 0;
typedef struct LX {
#if defined(LUAI_EXTRASPACE)
char buff[LUAI_EXTRASPACE];
#endif
lua_State l;
} LX;
/*
** Main thread combines a thread state and the global state
*/
typedef struct LG {
LX l;
global_State g;
} LG;
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
/*
** maximum number of nested calls made by error-handling function
*/
#define LUAI_EXTRACALLS 10
CallInfo *luaE_extendCI (lua_State *L) {
CallInfo *ci = luaM_new(L, CallInfo);
lua_assert(L->ci->next == NULL);
L->ci->next = ci;
ci->previous = L->ci;
ci->next = NULL;
return ci;
}
void luaE_freeCI (lua_State *L) {
CallInfo *ci = L->ci;
CallInfo *next = ci->next;
ci->next = NULL;
while ((ci = next) != NULL) {
next = ci->next;
luaM_free(L, ci);
}
}
static void stack_init (lua_State *L1, lua_State *L) {
int i; CallInfo *ci;
/* initialize stack array */
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
L1->stacksize = BASIC_STACK_SIZE;
for (i = 0; i < BASIC_STACK_SIZE; i++)
setnilvalue(L1->stack + i); /* erase new stack */
L1->top = L1->stack;
L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
/* initialize first ci */
ci = &L1->base_ci;
ci->next = ci->previous = NULL;
ci->callstatus = 0;
ci->func = L1->top;
setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
ci->top = L1->top + LUA_MINSTACK;
L1->ci = ci;
}
static void freestack (lua_State *L) {
if (L->stack == NULL)
return; /* stack not completely built yet */
L->ci = &L->base_ci; /* free the entire 'ci' list */
luaE_freeCI(L);
luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
}
/*
** open parts that may cause memory-allocation errors
** Create registry table and its predefined values
*/
static void init_registry (lua_State *L, global_State *g) {
TValue mt;
/* create registry */
Table *registry = luaH_new(L);
sethvalue(L, &g->l_registry, registry);
luaH_resize(L, registry, LUA_RIDX_LAST, 0);
/* registry[LUA_RIDX_MAINTHREAD] = L */
setthvalue(L, &mt, L);
setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt);
/* registry[LUA_RIDX_GLOBALS] = table of globals */
sethvalue(L, &mt, luaH_new(L));
setobj2t(L, luaH_setint(L, registry, LUA_RIDX_GLOBALS), &mt);
}
/*
** open parts of the state that may cause memory-allocation errors
*/
static void f_luaopen (lua_State *L, void *ud) {
int stacksize = *(int *)ud;
if (stacksize == 0)
stacksize = DEFAULT_STACK_SIZE;
else
stacksize += LUA_MINSTACK;
L->gt = luaH_new(L, 10); /* table of globals */
luaD_init(L, stacksize);
luaS_init(L);
luaX_init(L);
global_State *g = G(L);
UNUSED(ud);
stack_init(L, L); /* init stack */
init_registry(L, g);
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
lua_newtable(L);
lua_ref(L, 1); /* create registry */
lua_register(L, LUA_ERRORMESSAGE, errormessage);
#ifdef LUA_DEBUG
luaB_opentests(L);
if (lua_state == NULL) lua_state = L; /* keep first state to be opened */
#endif
LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
luaX_init(L);
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaS_fix(g->memerrmsg); /* it should never be collected */
g->GCdebt = 0;
}
LUA_API lua_State *lua_open (int stacksize) {
lua_State *L = luaM_new(NULL, lua_State);
if (L == NULL) return NULL; /* memory allocation error */
/*
** preinitialize a state with consistent values without allocating
** any memory (to avoid errors)
*/
static void preinit_state (lua_State *L, global_State *g) {
G(L) = g;
L->stack = NULL;
L->strt.size = L->udt.size = 0;
L->strt.nuse = L->udt.nuse = 0;
L->strt.hash = NULL;
L->udt.hash = NULL;
L->Mbuffer = NULL;
L->Mbuffsize = 0;
L->rootproto = NULL;
L->rootcl = NULL;
L->roottable = NULL;
L->TMtable = NULL;
L->last_tag = -1;
L->refArray = NULL;
L->refSize = 0;
L->refFree = NONEXT;
L->nblocks = sizeof(lua_State);
L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */
L->callhook = NULL;
L->linehook = NULL;
L->allowhooks = 1;
L->ci = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
if (luaD_runprotected(L, f_luaopen, &stacksize) != 0) {
L->hook = NULL;
L->hookmask = 0;
L->basehookcount = 0;
L->allowhook = 1;
resethookcount(L);
L->openupval = NULL;
L->nny = 1;
L->status = LUA_OK;
L->errfunc = 0;
}
static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_freeallobjects(L); /* collect all objects */
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
luaZ_freebuffer(L, &g->buff);
freestack(L);
lua_assert(g->totalbytes == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);
}
LUA_API lua_State *lua_newthread (lua_State *L) {
lua_State *L1;
lua_lock(L);
luaC_checkGC(L);
L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
setthvalue(L, L->top, L1);
api_incr_top(L);
preinit_state(L1, G(L));
L1->hookmask = L->hookmask;
L1->basehookcount = L->basehookcount;
L1->hook = L->hook;
resethookcount(L1);
luai_userstatethread(L, L1);
stack_init(L1, L); /* init stack */
lua_unlock(L);
return L1;
}
void luaE_freethread (lua_State *L, lua_State *L1) {
LX *l = fromstate(L1);
luaF_close(L1, L1->stack); /* close all upvalues for this thread */
lua_assert(L1->openupval == NULL);
luai_userstatefree(L, L1);
freestack(L1);
luaM_free(L, l);
}
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
global_State *g;
LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
if (l == NULL) return NULL;
L = &l->l.l;
g = &l->g;
L->next = NULL;
L->tt = LUA_TTHREAD;
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
L->marked = luaC_white(g);
g->gckind = KGC_NORMAL;
g->nCcalls = 0;
preinit_state(L, g);
g->frealloc = f;
g->ud = ud;
g->mainthread = L;
g->uvhead.u.l.prev = &g->uvhead;
g->uvhead.u.l.next = &g->uvhead;
stopgc(g); /* no GC while building state */
g->lastmajormem = 0;
g->strt.size = 0;
g->strt.nuse = 0;
g->strt.hash = NULL;
setnilvalue(&g->l_registry);
luaZ_initbuffer(L, &g->buff);
g->panic = NULL;
g->version = lua_version(NULL);
g->gcstate = GCSpause;
g->allgc = NULL;
g->udgc = NULL;
g->tobefnz = NULL;
g->gray = g->grayagain = NULL;
g->weak = g->ephemeron = g->allweak = NULL;
g->totalbytes = sizeof(LG);
g->gcpause = LUAI_GCPAUSE;
g->gcmajorinc = LUAI_GCMAJOR;
g->gcstepmul = LUAI_GCMUL;
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
lua_close(L);
return NULL;
close_state(L);
L = NULL;
}
L->GCthreshold = 2*L->nblocks;
else
luai_userstateopen(L);
return L;
}
LUA_API void lua_close (lua_State *L) {
LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack");
luaC_collect(L, 1); /* collect all elements */
LUA_ASSERT(L->rootproto == NULL, "list should be empty");
LUA_ASSERT(L->rootcl == NULL, "list should be empty");
LUA_ASSERT(L->roottable == NULL, "list should be empty");
luaS_freeall(L);
if (L->stack)
L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject);
luaM_free(L, L->stack);
L->nblocks -= (L->last_tag+1)*sizeof(struct TM);
luaM_free(L, L->TMtable);
L->nblocks -= (L->refSize)*sizeof(struct Ref);
luaM_free(L, L->refArray);
L->nblocks -= (L->Mbuffsize)*sizeof(char);
luaM_free(L, L->Mbuffer);
LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
luaM_free(L, L);
LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_separateudata(L, 1); /* separate all udata with GC metamethods */
lua_assert(L->next == NULL);
luai_userstateclose(L);
close_state(L);
}

233
lstate.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.40 2000/09/29 12:42:13 roberto Exp roberto $
** $Id: lstate.h,v 2.67 2010/09/30 17:21:31 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -7,71 +7,212 @@
#ifndef lstate_h
#define lstate_h
#include "lobject.h"
#include "lua.h"
#include "luadebug.h"
typedef TObject *StkId; /* index to stack elements */
#include "lobject.h"
#include "ltm.h"
#include "lzio.h"
/*
** marks for Reference array
** Some notes about garbage-collected objects: All objects in Lua must
** be kept somehow accessible until being freed.
**
** Lua keeps most objects linked in list g->allgc. The link uses field
** 'next' of the CommonHeader.
**
** Strings are kept in several lists headed by the array g->strt.hash.
**
** Open upvalues are not subject to independent garbage collection. They
** are collected together with their respective threads. Lua keeps a
** double-linked list with all open upvalues (g->uvhead) so that it can
** mark objects referred by them. (They are always gray, so they must
** be remarked in the atomic step. Usually their contents would be marked
** when traversing the respective threads, but the thread may already be
** dead, while the upvalue is still accessible through closures.)
**
** Userdata with finalizers are kept in the list g->udgc.
**
** The list g->tobefnz links all userdata being finalized.
*/
#define NONEXT -1 /* to end the free list */
#define HOLD -2
#define COLLECTED -3
#define LOCK -4
struct Ref {
TObject o;
int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
};
struct lua_longjmp; /* defined in ldo.c */
struct TM; /* defined in ltm.h */
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
#define BASIC_CI_SIZE 8
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
/* kinds of Garbage Collection */
#define KGC_NORMAL 0
#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */
#define KGC_GEN 2 /* generational collection */
typedef struct stringtable {
GCObject **hash;
lu_int32 nuse; /* number of elements */
int size;
lint32 nuse; /* number of elements */
TString **hash;
} stringtable;
/*
** information about a call
*/
typedef struct CallInfo {
StkId func; /* function index in the stack */
StkId top; /* top for this function */
struct CallInfo *previous, *next; /* dynamic call link */
short nresults; /* expected number of results from this function */
lu_byte callstatus;
union {
struct { /* only for Lua functions */
StkId base; /* base for this function */
const Instruction *savedpc;
} l;
struct { /* only for C functions */
int ctx; /* context info. in case of yields */
lua_CFunction k; /* continuation in case of yields */
ptrdiff_t old_errfunc;
ptrdiff_t extra;
lu_byte old_allowhook;
lu_byte status;
} c;
} u;
} CallInfo;
struct lua_State {
/* thread-specific state */
StkId top; /* first free slot in the stack */
StkId stack; /* stack base */
StkId stack_last; /* last free slot in the stack */
int stacksize;
StkId Cbase; /* base for current C function */
struct lua_longjmp *errorJmp; /* current error recover point */
char *Mbuffer; /* global buffer */
size_t Mbuffsize; /* size of Mbuffer */
/* global state */
Proto *rootproto; /* list of all prototypes */
Closure *rootcl; /* list of all closures */
Hash *roottable; /* list of all tables */
/*
** Bits in CallInfo status
*/
#define CIST_LUA (1<<0) /* call is running a Lua function */
#define CIST_HOOKED (1<<1) /* call is running a debug hook */
#define CIST_REENTRY (1<<2) /* call is running on same invocation of
luaV_execute of previous call */
#define CIST_YIELDED (1<<3) /* call reentered after suspension */
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
#define CIST_STAT (1<<5) /* call has an error status (pcall) */
#define CIST_TAIL (1<<6) /* call was tail called */
#define ci_func(ci) (clvalue((ci)->func))
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
/*
** `global state', shared by all threads of this state
*/
typedef struct global_State {
lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to `frealloc' */
lu_mem totalbytes; /* number of bytes currently allocated */
l_mem GCdebt; /* when positive, run a GC step */
lu_mem lastmajormem; /* memory in use after last major collection */
stringtable strt; /* hash table for strings */
stringtable udt; /* hash table for udata */
Hash *gt; /* table for globals */
struct TM *TMtable; /* table for tag methods */
int last_tag; /* last used tag in TMtable */
struct Ref *refArray; /* locked objects */
int refSize; /* size of refArray */
int refFree; /* list of free positions in refArray */
unsigned long GCthreshold;
unsigned long nblocks; /* number of `bytes' currently allocated */
lua_Hook callhook;
lua_Hook linehook;
int allowhooks;
TValue l_registry;
unsigned short nCcalls; /* number of nested C calls */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
lu_byte gckind; /* kind of GC running */
int sweepstrgc; /* position of sweep in `strt' */
GCObject *allgc; /* list of all collectable objects */
GCObject *udgc; /* list of collectable userdata with finalizers */
GCObject **sweepgc; /* current position of sweep */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of tables with weak values */
GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
GCObject *allweak; /* list of all-weak tables */
GCObject *tobefnz; /* list of userdata to be GC */
UpVal uvhead; /* head of double-linked list of all open upvalues */
Mbuffer buff; /* temporary buffer for string concatenation */
int gcpause; /* size of pause between successive GCs */
int gcmajorinc; /* how much to wait for a major GC (only in gen. mode) */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
struct lua_State *mainthread;
const lua_Number *version; /* pointer to version number */
TString *memerrmsg; /* memory-error message */
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
} global_State;
/*
** `per thread' state
*/
struct lua_State {
CommonHeader;
lu_byte status;
StkId top; /* first free slot in the stack */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
int stacksize;
unsigned short nny; /* number of non-yieldable calls in stack */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
int hookcount;
lua_Hook hook;
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
};
#define G(L) (L->l_G)
/*
** Union of all collectable objects
*/
union GCObject {
GCheader gch; /* common header */
union TString ts;
union Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct UpVal uv;
struct lua_State th; /* thread */
};
#define gch(o) (&(o)->gch)
/* macros to convert a GCObject into a specific value */
#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
#define gco2ts(o) (&rawgco2ts(o)->tsv)
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
#define gco2u(o) (&rawgco2u(o)->uv)
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
/* macro to convert any Lua object into a GCObject */
#define obj2gco(v) (cast(GCObject *, (v)))
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
LUAI_FUNC void luaE_freeCI (lua_State *L);
#endif

178
lstring.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 1.44 2000/10/26 12:47:05 roberto Exp roberto $
** $Id: lstring.c,v 2.17 2010/04/03 20:24:18 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -7,6 +7,9 @@
#include <string.h>
#define lstring_c
#define LUA_CORE
#include "lua.h"
#include "lmem.h"
@@ -15,130 +18,80 @@
#include "lstring.h"
/*
** type equivalent to TString, but with maximum alignment requirements
*/
union L_UTString {
TString ts;
union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
};
void luaS_init (lua_State *L) {
L->strt.hash = luaM_newvector(L, 1, TString *);
L->udt.hash = luaM_newvector(L, 1, TString *);
L->nblocks += 2*sizeof(TString *);
L->strt.size = L->udt.size = 1;
L->strt.nuse = L->udt.nuse = 0;
L->strt.hash[0] = L->udt.hash[0] = NULL;
}
void luaS_freeall (lua_State *L) {
LUA_ASSERT(L->strt.nuse==0, "non-empty string table");
L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *);
luaM_free(L, L->strt.hash);
LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
luaM_free(L, L->udt.hash);
}
static unsigned long hash_s (const char *s, size_t l) {
unsigned long h = l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
return h;
}
void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
TString **newhash = luaM_newvector(L, newsize, TString *);
void luaS_resize (lua_State *L, int newsize) {
int i;
for (i=0; i<newsize; i++) newhash[i] = NULL;
stringtable *tb = &G(L)->strt;
/* cannot resize while GC is traversing strings */
luaC_runtilstate(L, ~bitmask(GCSsweepstring));
if (newsize > tb->size) {
luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
}
/* rehash */
for (i=0; i<tb->size; i++) {
TString *p = tb->hash[i];
GCObject *p = tb->hash[i];
tb->hash[i] = NULL;
while (p) { /* for each node in the list */
TString *next = p->nexthash; /* save next */
unsigned long h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value);
int h1 = h&(newsize-1); /* new position */
LUA_ASSERT(h%newsize == (h&(newsize-1)),
"a&(x-1) == a%x, for x power of 2");
p->nexthash = newhash[h1]; /* chain it in new position */
newhash[h1] = p;
GCObject *next = gch(p)->next; /* save next */
unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */
gch(p)->next = tb->hash[h]; /* chain it */
tb->hash[h] = p;
resetoldbit(p); /* see MOVE OLD rule */
p = next;
}
}
luaM_free(L, tb->hash);
L->nblocks += (newsize - tb->size)*sizeof(TString *);
if (newsize < tb->size) {
/* shrinking slice must be empty */
lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
}
tb->size = newsize;
tb->hash = newhash;
}
static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) {
ts->nexthash = tb->hash[h]; /* chain new entry */
tb->hash[h] = ts;
static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h) {
size_t totalsize; /* total size of TString object */
GCObject **list; /* (pointer to) list where it will be inserted */
TString *ts;
stringtable *tb = &G(L)->strt;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
list = &tb->hash[lmod(h, tb->size)];
ts = &luaC_newobj(L, LUA_TSTRING, totalsize, list, 0)->ts;
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.reserved = 0;
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
tb->nuse++;
if (tb->nuse > (lint32)tb->size && tb->size < MAX_INT/2) /* too crowded? */
luaS_resize(L, tb, tb->size*2);
return ts;
}
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
unsigned long h = hash_s(str, l);
int h1 = h & (L->strt.size-1);
TString *ts;
for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) {
if (ts->len == l && (memcmp(str, ts->str, l) == 0))
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1;
for (l1=l; l1>=step; l1-=step) /* compute hash */
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL;
o = gch(o)->next) {
TString *ts = rawgco2ts(o);
if (h == ts->tsv.hash && ts->tsv.len == l &&
(memcmp(str, getstr(ts), l) == 0)) {
if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */
changewhite(o); /* resurrect it */
return ts;
}
}
/* not found */
ts = (TString *)luaM_malloc(L, sizestring(l));
ts->marked = 0;
ts->nexthash = NULL;
ts->len = l;
ts->u.s.hash = h;
ts->u.s.constindex = 0;
memcpy(ts->str, str, l);
ts->str[l] = 0; /* ending 0 */
L->nblocks += sizestring(l);
newentry(L, &L->strt, ts, h1); /* insert it on table */
return ts;
}
TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
union L_UTString *uts = (union L_UTString *)luaM_malloc(L,
(lint32)sizeof(union L_UTString)+s);
TString *ts = &uts->ts;
ts->marked = 0;
ts->nexthash = NULL;
ts->len = s;
ts->u.d.tag = 0;
ts->u.d.value = (udata == NULL) ? uts+1 : udata;
L->nblocks += sizestring(s);
/* insert it on table */
newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1));
return ts;
}
TString *luaS_createudata (lua_State *L, void *udata, int tag) {
int h1 = IntPoint(udata) & (L->udt.size-1);
TString *ts;
for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) {
if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
return ts;
}
/* not found */
ts = luaS_newudata(L, 0, udata);
if (tag != LUA_ANYTAG)
ts->u.d.tag = tag;
return ts;
return newlstr(L, str, l, h); /* not found; create a new string */
}
@@ -147,9 +100,14 @@ TString *luaS_new (lua_State *L, const char *str) {
}
TString *luaS_newfixed (lua_State *L, const char *str) {
TString *ts = luaS_new(L, str);
if (ts->marked == 0) ts->marked = FIXMARK; /* avoid GC */
return ts;
Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
if (s > MAX_SIZET - sizeof(Udata))
luaM_toobig(L);
u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;
u->uv.len = s;
u->uv.metatable = NULL;
u->uv.env = e;
return u;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.h,v 1.23 2000/10/26 12:47:05 roberto Exp roberto $
** $Id: lstring.h,v 1.45 2010/04/03 20:24:18 roberto Exp roberto $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -7,31 +7,31 @@
#ifndef lstring_h
#define lstring_h
#include "lgc.h"
#include "lobject.h"
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
/*
** any TString with mark>=FIXMARK is never collected.
** Marks>=RESERVEDMARK are used to identify reserved words.
** as all string are internalized, string equality becomes
** pointer equality
*/
#define FIXMARK 2
#define RESERVEDMARK 3
#define eqstr(a,b) ((a) == (b))
#define sizestring(l) ((long)sizeof(TString) + \
((long)(l+1)-TSPACK)*(long)sizeof(char))
void luaS_init (lua_State *L);
void luaS_resize (lua_State *L, stringtable *tb, int newsize);
TString *luaS_newudata (lua_State *L, size_t s, void *udata);
TString *luaS_createudata (lua_State *L, void *udata, int tag);
void luaS_freeall (lua_State *L);
TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
TString *luaS_new (lua_State *L, const char *str);
TString *luaS_newfixed (lua_State *L, const char *str);
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
#endif

911
lstrlib.c

File diff suppressed because it is too large Load Diff

719
ltable.c
View File

@@ -1,25 +1,33 @@
/*
** $Id: ltable.c,v 1.57 2000/10/05 12:14:08 roberto Exp roberto $
** $Id: ltable.c,v 2.52 2010/06/25 12:18:10 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
/*
** Implementation of tables (aka arrays, objects, or hash tables);
** uses a mix of chained scatter table with Brent's variation.
** Implementation of tables (aka arrays, objects, or hash tables).
** Tables keep its elements in two parts: an array part and a hash part.
** Non-negative integer keys are all candidates to be kept in the array
** part. The actual size of the array is the largest `n' such that at
** least half the slots between 0 and n are in use.
** Hash uses a mix of chained scatter table with Brent's variation.
** A main invariant of these tables is that, if an element is not
** in its main position (i.e. the `original' position that its hash gives
** to it), then the colliding element is in its own main position.
** In other words, there are collisions only when two elements have the
** same main position (i.e. the same hash values for that table size).
** Because of that, the load factor of these tables can be 100% without
** performance penalties.
** Hence even when the load factor reaches 100%, performance remains good.
*/
#include <string.h>
#define ltable_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
@@ -27,11 +35,63 @@
#include "ltable.h"
#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node))
/*
** max size of array part is 2^MAXBITS
*/
#if LUAI_BITSINT >= 32
#define MAXBITS 30
#else
#define MAXBITS (LUAI_BITSINT-2)
#endif
#define MAXASIZE (1 << MAXBITS)
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
/*
** for some types, it is better to avoid modulus by power of 2, as
** they tend to have many 2 factors.
*/
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
#define hashpointer(t,p) hashmod(t, IntPoint(p))
/*
** number of ints inside a lua_Number
*/
#define numints cast_int(sizeof(lua_Number)/sizeof(int))
#define TagDefault LUA_TTABLE
#define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
static const Node dummynode_ = {
{NILCONSTANT}, /* value */
{{NILCONSTANT, NULL}} /* key */
};
/*
** hash for lua_Numbers
*/
static Node *hashnum (const Table *t, lua_Number n) {
int i;
luai_hashnum(i, n);
if (i < 0) {
i = -i; /* must be a positive value */
if (i < 0) i = 0; /* handle INT_MIN */
}
return hashmod(t, i);
}
@@ -39,265 +99,490 @@
** returns the `main' position of an element in a table (that is, the index
** of its hash value)
*/
Node *luaH_mainposition (const Hash *t, const TObject *key) {
unsigned long h;
static Node *mainposition (const Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNUMBER:
h = (unsigned long)(long)nvalue(key);
break;
return hashnum(t, nvalue(key));
case LUA_TSTRING:
h = tsvalue(key)->u.s.hash;
break;
case LUA_TUSERDATA:
h = IntPoint(tsvalue(key));
break;
case LUA_TTABLE:
h = IntPoint(hvalue(key));
break;
case LUA_TFUNCTION:
h = IntPoint(clvalue(key));
break;
return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
return hashpointer(t, pvalue(key));
case LUA_TLCF:
return hashpointer(t, fvalue(key));
default:
return NULL; /* invalid key */
return hashpointer(t, gcvalue(key));
}
LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)),
"a&(x-1) == a%x, for x power of 2");
return &t->node[h&(t->size-1)];
}
static const TObject *luaH_getany (lua_State *L, const Hash *t,
const TObject *key) {
Node *n = luaH_mainposition(t, key);
if (!n)
lua_error(L, "table index is nil");
else do {
if (luaO_equalObj(key, &n->key))
return &n->val;
n = n->next;
} while (n);
return &luaO_nilobject; /* key not found */
}
/* specialized version for numbers */
const TObject *luaH_getnum (const Hash *t, Number key) {
Node *n = &t->node[(unsigned long)(long)key&(t->size-1)];
do {
if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key)
return &n->val;
n = n->next;
} while (n);
return &luaO_nilobject; /* key not found */
}
/* specialized version for strings */
const TObject *luaH_getstr (const Hash *t, TString *key) {
Node *n = &t->node[key->u.s.hash&(t->size-1)];
do {
if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key)
return &n->val;
n = n->next;
} while (n);
return &luaO_nilobject; /* key not found */
}
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
switch (ttype(key)) {
case LUA_TNUMBER: return luaH_getnum(t, nvalue(key));
case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
default: return luaH_getany(L, t, key);
}
}
Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
int i;
if (ttype(key) == LUA_TNIL)
i = 0; /* first iteration */
else {
const TObject *v = luaH_get(L, t, key);
if (v == &luaO_nilobject)
lua_error(L, "invalid key for `next'");
i = (int)(((const char *)v -
(const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
}
for (; i<t->size; i++) {
Node *n = node(t, i);
if (ttype(val(n)) != LUA_TNIL)
return n;
}
return NULL; /* no more elements */
}
/*
** try to remove a key without value from a table. To avoid problems with
** hash, change `key' for a number with the same hash.
** returns the index for `key' if `key' is an appropriate key to live in
** the array part of the table, -1 otherwise.
*/
void luaH_remove (Hash *t, TObject *key) {
if (ttype(key) == LUA_TNUMBER ||
(ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30))
return; /* do not remove numbers nor small strings */
else {
/* try to find a number `n' with the same hash as `key' */
Node *mp = luaH_mainposition(t, key);
int n = mp - &t->node[0];
/* make sure `n' is not in `t' */
while (luaH_getnum(t, n) != &luaO_nilobject) {
if (n >= MAX_INT - t->size)
return; /* give up; (to avoid overflow) */
n += t->size;
}
ttype(key) = LUA_TNUMBER;
nvalue(key) = n;
LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash");
static int arrayindex (const TValue *key) {
if (ttisnumber(key)) {
lua_Number n = nvalue(key);
int k;
lua_number2int(k, n);
if (luai_numeq(cast_num(k), n))
return k;
}
return -1; /* `key' did not match some condition */
}
static void setnodevector (lua_State *L, Hash *t, lint32 size) {
/*
** returns the index of a `key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
** beginning of a traversal is signaled by -1.
*/
static int findindex (lua_State *L, Table *t, StkId key) {
int i;
if (size > MAX_INT)
lua_error(L, "table overflow");
t->node = luaM_newvector(L, size, Node);
for (i=0; i<(int)size; i++) {
ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL;
t->node[i].next = NULL;
if (ttisnil(key)) return -1; /* first iteration */
i = arrayindex(key);
if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
return i-1; /* yes; that's the index (corrected to C) */
else {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
/* key may be dead already, but it is ok to use it in `next' */
if (luaO_rawequalObj(gkey(n), key) ||
(ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
gcvalue(gkey(n)) == gcvalue(key))) {
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t->sizearray;
}
else n = gnext(n);
} while (n);
luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
return 0; /* to avoid warnings */
}
L->nblocks += gcsize(L, size) - gcsize(L, t->size);
t->size = size;
t->firstfree = &t->node[size-1]; /* first free position to be used */
}
Hash *luaH_new (lua_State *L, int size) {
Hash *t = luaM_new(L, Hash);
t->htag = TagDefault;
t->next = L->roottable;
L->roottable = t;
t->mark = t;
t->size = 0;
L->nblocks += gcsize(L, 0);
t->node = NULL;
setnodevector(L, t, luaO_power2(size));
int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setnvalue(key, cast_num(i+1));
setobj2s(L, key+1, &t->array[i]);
return 1;
}
}
for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(L, key, gkey(gnode(t, i)));
setobj2s(L, key+1, gval(gnode(t, i)));
return 1;
}
}
return 0; /* no more elements */
}
/*
** {=============================================================
** Rehash
** ==============================================================
*/
static int computesizes (int nums[], int *narray) {
int i;
int twotoi; /* 2^i */
int a = 0; /* number of elements smaller than 2^i */
int na = 0; /* number of elements to go to array part */
int n = 0; /* optimal size for array part */
for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
n = twotoi; /* optimal size (till now) */
na = a; /* all elements smaller than n will go to array part */
}
}
if (a == *narray) break; /* all elements already counted */
}
*narray = n;
lua_assert(*narray/2 <= na && na <= *narray);
return na;
}
static int countint (const TValue *key, int *nums) {
int k = arrayindex(key);
if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
nums[luaO_ceillog2(k)]++; /* count as such */
return 1;
}
else
return 0;
}
static int numusearray (const Table *t, int *nums) {
int lg;
int ttlg; /* 2^lg */
int ause = 0; /* summation of `nums' */
int i = 1; /* count to traverse all array keys */
for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
int lc = 0; /* counter */
int lim = ttlg;
if (lim > t->sizearray) {
lim = t->sizearray; /* adjust upper limit */
if (i > lim)
break; /* no more elements to count */
}
/* count elements in range (2^(lg-1), 2^lg] */
for (; i <= lim; i++) {
if (!ttisnil(&t->array[i-1]))
lc++;
}
nums[lg] += lc;
ause += lc;
}
return ause;
}
static int numusehash (const Table *t, int *nums, int *pnasize) {
int totaluse = 0; /* total number of elements */
int ause = 0; /* summation of `nums' */
int i = sizenode(t);
while (i--) {
Node *n = &t->node[i];
if (!ttisnil(gval(n))) {
ause += countint(gkey(n), nums);
totaluse++;
}
}
*pnasize += ause;
return totaluse;
}
static void setarrayvector (lua_State *L, Table *t, int size) {
int i;
luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
for (i=t->sizearray; i<size; i++)
setnilvalue(&t->array[i]);
t->sizearray = size;
}
static void setnodevector (lua_State *L, Table *t, int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common `dummynode' */
lsize = 0;
}
else {
int i;
lsize = luaO_ceillog2(size);
if (lsize > MAXBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
t->node = luaM_newvector(L, size, Node);
for (i=0; i<size; i++) {
Node *n = gnode(t, i);
gnext(n) = NULL;
setnilvalue(gkey(n));
setnilvalue(gval(n));
}
}
t->lsizenode = cast_byte(lsize);
t->lastfree = gnode(t, size); /* all positions are free */
}
void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
int i;
int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
setnodevector(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
for (i=nasize; i<oldasize; i++) {
if (!ttisnil(&t->array[i]))
setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
}
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
if (!ttisnil(gval(old)))
setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
}
if (!isdummy(nold))
luaM_freearray(L, nold, twoto(oldhsize)); /* free old array */
}
void luaH_resizearray (lua_State *L, Table *t, int nasize) {
int nsize = isdummy(t->node) ? 0 : sizenode(t);
luaH_resize(L, t, nasize, nsize);
}
static void rehash (lua_State *L, Table *t, const TValue *ek) {
int nasize, na;
int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
int i;
int totaluse;
for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
/* count extra key */
nasize += countint(ek, nums);
totaluse++;
/* compute new size for array part */
na = computesizes(nums, &nasize);
/* resize the table to new computed sizes */
luaH_resize(L, t, nasize, totaluse - na);
}
/*
** }=============================================================
*/
Table *luaH_new (lua_State *L) {
Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
t->metatable = NULL;
t->flags = cast_byte(~0);
t->array = NULL;
t->sizearray = 0;
setnodevector(L, t, 0);
return t;
}
void luaH_free (lua_State *L, Hash *t) {
L->nblocks -= gcsize(L, t->size);
luaM_free(L, t->node);
void luaH_free (lua_State *L, Table *t) {
if (!isdummy(t->node))
luaM_freearray(L, t->node, sizenode(t));
luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t);
}
static int numuse (const Hash *t) {
Node *v = t->node;
int size = t->size;
int realuse = 0;
int i;
for (i=0; i<size; i++) {
if (ttype(&v[i].val) != LUA_TNIL)
realuse++;
static Node *getfreepos (Table *t) {
while (t->lastfree > t->node) {
t->lastfree--;
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
}
return realuse;
return NULL; /* could not find a free place */
}
static void rehash (lua_State *L, Hash *t) {
int oldsize = t->size;
Node *nold = t->node;
int nelems = numuse(t);
int i;
LUA_ASSERT(nelems<=oldsize, "wrong count");
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
setnodevector(L, t, (lint32)oldsize*2);
else if (nelems <= oldsize/4 && /* less than 1/4? */
oldsize > MINPOWER2)
setnodevector(L, t, oldsize/2);
else
setnodevector(L, t, oldsize);
for (i=0; i<oldsize; i++) {
Node *old = nold+i;
if (ttype(&old->val) != LUA_TNIL)
*luaH_set(L, t, &old->key) = old->val;
/*
** inserts a new key into a hash table; first, check whether key's main
** position is free. If not, check whether colliding node is in its main
** position or not: if it is not, move colliding node to an empty place and
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
return luaH_set(L, t, key); /* re-insert key into grown table */
}
lua_assert(!isdummy(n));
othern = mainposition(t, gkey(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
gnext(mp) = NULL; /* now `mp' is free */
setnilvalue(gval(mp));
}
else { /* colliding node is in its own main position */
/* new node will go into free position */
gnext(n) = gnext(mp); /* chain new position */
gnext(mp) = n;
mp = n;
}
}
luaM_free(L, nold); /* free old array */
setobj2t(L, gkey(mp), key);
luaC_barrierback(L, obj2gco(t), key);
lua_assert(ttisnil(gval(mp)));
return gval(mp);
}
/*
** inserts a key into a hash table; first, check whether key is
** already present; if not, check whether key's main position is free;
** if not, check whether colliding node is in its main position or not;
** if it is not, move colliding node to an empty place and put new key
** in its main position; otherwise (colliding node is in its main position),
** new key goes to an empty position.
** search function for integers
*/
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
Node *mp = luaH_mainposition(t, key);
Node *n = mp;
if (!mp)
lua_error(L, "table index is nil");
const TValue *luaH_getint (Table *t, int key) {
/* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1];
else {
lua_Number nk = cast_num(key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
/*
** search function for strings
*/
const TValue *luaH_getstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_equalObj(key, &n->key))
return &n->val; /* that's all */
else n = n->next;
if (ttisstring(gkey(n)) && eqstr(rawtsvalue(gkey(n)), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
/* `key' not found; must insert it */
if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */
Node *othern; /* main position of colliding node */
n = t->firstfree; /* get a free place */
/* is colliding node out of its main position? (can only happens if
its position is after "firstfree") */
if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) {
/* yes; move colliding node into free position */
while (othern->next != mp) othern = othern->next; /* find previous */
othern->next = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
mp->next = NULL; /* now `mp' is free */
return luaO_nilobject;
}
/*
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
/* else go through */
}
else { /* colliding node is in its own main position */
/* new node will go into free position */
n->next = mp->next; /* chain new position */
mp->next = n;
mp = n;
default: {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(gkey(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
mp->key = *key;
for (;;) { /* correct `firstfree' */
if (ttype(&t->firstfree->key) == LUA_TNIL)
return &mp->val; /* OK; table still has a free place */
else if (t->firstfree == t->node) break; /* cannot decrement from here */
else (t->firstfree)--;
}
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
t->flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
luaG_runerror(L, "table index is NaN");
return newkey(L, t, key);
}
rehash(L, t); /* no more free places */
return luaH_set(L, t, key); /* `rehash' invalidates this insertion */
}
TObject *luaH_setint (lua_State *L, Hash *t, int key) {
TObject index;
ttype(&index) = LUA_TNUMBER;
nvalue(&index) = key;
return luaH_set(L, t, &index);
TValue *luaH_setint (lua_State *L, Table *t, int key) {
const TValue *p = luaH_getint(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
TValue k;
setnvalue(&k, cast_num(key));
return newkey(L, t, &k);
}
}
void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val) {
TObject *value, index;
ttype(&index) = LUA_TSTRING;
tsvalue(&index) = key;
value = luaH_set(L, t, &index);
ttype(value) = LUA_TNUMBER;
nvalue(value) = val;
TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
const TValue *p = luaH_getstr(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
TValue k;
setsvalue(L, &k, key);
return newkey(L, t, &k);
}
}
const TObject *luaH_getglobal (lua_State *L, const char *name) {
return luaH_getstr(L->gt, luaS_new(L, name));
static int unbound_search (Table *t, unsigned int j) {
unsigned int i = j; /* i is zero or a present index */
j++;
/* find `i' and `j' such that i is present and j is not */
while (!ttisnil(luaH_getint(t, j))) {
i = j;
j *= 2;
if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
while (!ttisnil(luaH_getint(t, i))) i++;
return i - 1;
}
}
/* now do a binary search between them */
while (j - i > 1) {
unsigned int m = (i+j)/2;
if (ttisnil(luaH_getint(t, m))) j = m;
else i = m;
}
return i;
}
/*
** Try to find a boundary in table `t'. A `boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
while (j - i > 1) {
unsigned int m = (i+j)/2;
if (ttisnil(&t->array[m - 1])) j = m;
else i = m;
}
return i;
}
/* else must find a boundary in hash part */
else if (isdummy(t->node)) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);
}
int luaH_isdummy (Node *n) { return isdummy(n); }
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.h,v 1.23 2000/06/06 16:31:41 roberto Exp roberto $
** $Id: ltable.h,v 2.13 2009/11/06 17:07:48 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -10,25 +10,30 @@
#include "lobject.h"
#define node(t,i) (&(t)->node[i])
#define key(n) (&(n)->key)
#define val(n) (&(n)->val)
#define gnode(t,i) (&(t)->node[i])
#define gkey(n) (&(n)->i_key.tvk)
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
Hash *luaH_new (lua_State *L, int nhash);
void luaH_free (lua_State *L, Hash *t);
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
const TObject *luaH_getnum (const Hash *t, Number key);
const TObject *luaH_getstr (const Hash *t, TString *key);
void luaH_remove (Hash *t, TObject *key);
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
TObject *luaH_setint (lua_State *L, Hash *t, int key);
void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val);
unsigned long luaH_hash (lua_State *L, const TObject *key);
const TObject *luaH_getglobal (lua_State *L, const char *name);
/* exported only for debugging */
Node *luaH_mainposition (const Hash *t, const TObject *key);
LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, int key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L);
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n);
#endif
#endif

290
ltablib.c Normal file
View File

@@ -0,0 +1,290 @@
/*
** $Id: ltablib.c,v 1.57 2010/10/25 19:01:37 roberto Exp roberto $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define ltablib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#define aux_getn(L,n) \
(luaL_checktype(L, n, LUA_TTABLE), (int)lua_rawlen(L, n))
static int deprecatedfunc (lua_State *L) {
return luaL_error(L, "deprecated function");
}
#if defined(LUA_COMPAT_MAXN)
static int maxn (lua_State *L) {
lua_Number max = 0;
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pop(L, 1); /* remove value */
if (lua_type(L, -1) == LUA_TNUMBER) {
lua_Number v = lua_tonumber(L, -1);
if (v > max) max = v;
}
}
lua_pushnumber(L, max);
return 1;
}
#else
#define maxn deprecatedfunc
#endif
static int tinsert (lua_State *L) {
int e = aux_getn(L, 1) + 1; /* first empty element */
int pos; /* where to insert new element */
switch (lua_gettop(L)) {
case 2: { /* called with only 2 arguments */
pos = e; /* insert new element at the end */
break;
}
case 3: {
int i;
pos = luaL_checkint(L, 2); /* 2nd argument is the position */
if (pos > e) e = pos; /* `grow' array if necessary */
for (i = e; i > pos; i--) { /* move up elements */
lua_rawgeti(L, 1, i-1);
lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
}
break;
}
default: {
return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
}
}
lua_rawseti(L, 1, pos); /* t[pos] = v */
return 0;
}
static int tremove (lua_State *L) {
int e = aux_getn(L, 1);
int pos = luaL_optint(L, 2, e);
if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
return 0; /* nothing to remove */
lua_rawgeti(L, 1, pos); /* result = t[pos] */
for ( ;pos<e; pos++) {
lua_rawgeti(L, 1, pos+1);
lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
}
lua_pushnil(L);
lua_rawseti(L, 1, e); /* t[e] = nil */
return 1;
}
static void addfield (lua_State *L, luaL_Buffer *b, int i) {
lua_rawgeti(L, 1, i);
if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for "
LUA_QL("concat"), luaL_typename(L, -1), i);
luaL_addvalue(b);
}
static int tconcat (lua_State *L) {
luaL_Buffer b;
size_t lsep;
int i, last;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
luaL_checktype(L, 1, LUA_TTABLE);
i = luaL_optint(L, 3, 1);
last = luaL_opt(L, luaL_checkint, 4, (int)lua_rawlen(L, 1));
luaL_buffinit(L, &b);
for (; i < last; i++) {
addfield(L, &b, i);
luaL_addlstring(&b, sep, lsep);
}
if (i == last) /* add last value (if interval was not empty) */
addfield(L, &b, i);
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** Pack/unpack
** =======================================================
*/
static int pack (lua_State *L) {
int top = lua_gettop(L);
lua_createtable(L, top, 1); /* create result table */
lua_pushinteger(L, top); /* number of elements */
lua_setfield(L, -2, "n"); /* t.n = number of elements */
if (top > 0) { /* at least one element? */
lua_pushvalue(L, 1);
lua_rawseti(L, -2, 1); /* insert first element */
lua_replace(L, 1); /* move table into its position (index 1) */
for (; top >= 2; top--) /* assign other elements */
lua_rawseti(L, 1, top);
}
return 1;
}
static int unpack (lua_State *L) {
int i, e, n;
luaL_checktype(L, 1, LUA_TTABLE);
i = luaL_optint(L, 2, 1);
e = luaL_opt(L, luaL_checkint, 3, (int)lua_rawlen(L, 1));
if (i > e) return 0; /* empty range */
n = e - i + 1; /* number of elements */
if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
return luaL_error(L, "too many results to unpack");
lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
while (i++ < e) /* push arg[i + 1...e] */
lua_rawgeti(L, 1, i);
return n;
}
/* }====================================================== */
/*
** {======================================================
** Quicksort
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
** Addison-Wesley, 1993.)
** =======================================================
*/
static void set2 (lua_State *L, int i, int j) {
lua_rawseti(L, 1, i);
lua_rawseti(L, 1, j);
}
static int sort_comp (lua_State *L, int a, int b) {
if (!lua_isnil(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
lua_call(L, 2, 1);
res = lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
else /* a < b? */
return lua_compare(L, a, b, LUA_OPLT);
}
static void auxsort (lua_State *L, int l, int u) {
while (l < u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
lua_rawgeti(L, 1, l);
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
set2(L, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
lua_rawgeti(L, 1, i);
lua_rawgeti(L, 1, l);
if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
set2(L, i, l);
else {
lua_pop(L, 1); /* remove a[l] */
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
set2(L, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
lua_rawgeti(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
lua_rawgeti(L, 1, u-1);
set2(L, i, u-1);
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= P */
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i>=u) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] <= P */
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
if (j<=l) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[j] */
}
if (j<i) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
set2(L, i, j);
}
lua_rawgeti(L, 1, u-1);
lua_rawgeti(L, 1, i);
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller half is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
j=l; i=i-1; l=i+2;
}
else {
j=i+1; i=u; u=j-2;
}
auxsort(L, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
static int sort (lua_State *L) {
int n = aux_getn(L, 1);
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_settop(L, 2); /* make sure there is two arguments */
auxsort(L, 1, n);
return 0;
}
/* }====================================================== */
static const luaL_Reg tab_funcs[] = {
{"concat", tconcat},
{"foreach", deprecatedfunc},
{"foreachi", deprecatedfunc},
{"getn", deprecatedfunc},
{"maxn", maxn},
{"insert", tinsert},
{"pack", pack},
{"unpack", unpack},
{"remove", tremove},
{"sort", sort},
{NULL, NULL}
};
LUAMOD_API int luaopen_table (lua_State *L) {
luaL_newlib(L, tab_funcs);
#if defined(LUA_COMPAT_UNPACK)
/* _G.unpack = table.unpack */
lua_getfield(L, -1, "unpack");
lua_setglobal(L, "unpack");
#endif
return 1;
}

1394
ltests.c

File diff suppressed because it is too large Load Diff

93
ltests.h Normal file
View File

@@ -0,0 +1,93 @@
/*
** $Id: ltests.h,v 2.32 2010/04/19 17:40:13 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
#ifndef ltests_h
#define ltests_h
#include <stdlib.h>
/* do not use compatibility macros in Lua code */
#undef LUA_COMPAT_API
#define LUA_DEBUG
#undef NDEBUG
#include <assert.h>
#define lua_assert(c) assert(c)
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* memory allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
unsigned long objcount[LUA_NUMTAGS];
} Memcontrol;
extern Memcontrol l_memcontrol;
/*
** generic variable for debug tricks
*/
extern void *l_Trick;
void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
typedef struct CallInfo *pCallInfo;
int lua_checkmemory (lua_State *L);
/* test for lock/unlock */
#undef luai_userstateopen
#undef luai_userstatethread
#undef lua_lock
#undef lua_unlock
struct L_EXTRA { int lock; int *plock; };
#define LUAI_EXTRASPACE sizeof(struct L_EXTRA)
#define getlock(l) (cast(struct L_EXTRA *, l) - 1)
#define luai_userstateopen(l) \
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
#define luai_userstatethread(l,l1) (getlock(l1)->plock = getlock(l)->plock)
#define luai_userstatefree(l,l1) \
lua_assert(getlock(l)->plock == getlock(l1)->plock)
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
int luaB_opentests (lua_State *L);
#if defined(lua_c)
#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol)
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); luaL_requiref(L, "T", luaB_opentests, 1); }
#endif
/* change some sizes to give some bugs a chance */
#undef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE 23
#define MINSTRTABSIZE 2
#undef LUAI_USER_ALIGNMENT_T
#define LUAI_USER_ALIGNMENT_T union { char b[32]; }
#endif

174
ltm.c
View File

@@ -1,163 +1,77 @@
/*
** $Id: ltm.c,v 1.55 2000/10/20 16:39:03 roberto Exp roberto $
** $Id: ltm.c,v 2.11 2010/01/13 16:18:25 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#define ltm_c
#define LUA_CORE
#include "lua.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
const char *const luaT_eventname[] = { /* ORDER TM */
"gettable", "settable", "index", "getglobal", "setglobal", "add", "sub",
"mul", "div", "pow", "unm", "lt", "concat", "gc", "function",
"le", "gt", "ge", /* deprecated options!! */
NULL
static const char udatatypename[] = "userdata";
LUAI_DDEF const char *const luaT_typenames_[] = {
"no value",
"nil", "boolean", udatatypename, "number",
"string", "table", "function", udatatypename, "thread",
"proto", "upval"
};
static int findevent (const char *name) {
int i;
for (i=0; luaT_eventname[i]; i++)
if (strcmp(luaT_eventname[i], name) == 0)
return i;
return -1; /* name not found */
}
static int luaI_checkevent (lua_State *L, const char *name, int t) {
int e = findevent(name);
if (e >= TM_N)
luaO_verror(L, "event `%.50s' is deprecated", name);
if (e == TM_GC && t == LUA_TTABLE)
luaO_verror(L, "event `gc' for tables is deprecated");
if (e < 0)
luaO_verror(L, "`%.50s' is not a valid event name", name);
return e;
}
/* events in LUA_TNIL are all allowed, since this is used as a
* 'placeholder' for "default" fallbacks
*/
/* ORDER LUA_T, ORDER TM */
static const char luaT_validevents[NUM_TAGS][TM_N] = {
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
};
int luaT_validevent (int t, int e) { /* ORDER LUA_T */
return (t >= NUM_TAGS) ? 1 : luaT_validevents[t][e];
}
static void init_entry (lua_State *L, int tag) {
int i;
for (i=0; i<TM_N; i++)
luaT_gettm(L, tag, i) = NULL;
L->TMtable[tag].collected = NULL;
}
void luaT_init (lua_State *L) {
int t;
luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT);
L->nblocks += NUM_TAGS*sizeof(struct TM);
L->last_tag = NUM_TAGS-1;
for (t=0; t<=L->last_tag; t++)
init_entry(L, t);
}
LUA_API int lua_newtag (lua_State *L) {
luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM,
"tag table overflow", MAX_INT);
L->nblocks += sizeof(struct TM);
L->last_tag++;
init_entry(L, L->last_tag);
return L->last_tag;
}
static void checktag (lua_State *L, int tag) {
if (!(0 <= tag && tag <= L->last_tag))
luaO_verror(L, "%d is not a valid tag", tag);
}
void luaT_realtag (lua_State *L, int tag) {
if (!validtag(tag))
luaO_verror(L, "tag %d was not created by `newtag'", tag);
}
LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
int e;
checktag(L, tagto);
checktag(L, tagfrom);
for (e=0; e<TM_N; e++) {
if (luaT_validevent(tagto, e))
luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e);
}
return tagto;
}
int luaT_tag (const TObject *o) {
int t = ttype(o);
switch (t) {
case LUA_TUSERDATA: return tsvalue(o)->u.d.tag;
case LUA_TTABLE: return hvalue(o)->htag;
default: return t;
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
"__gc", "__mode", "__len", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__lt", "__le",
"__concat", "__call"
};
int i;
for (i=0; i<TM_N; i++) {
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
luaS_fix(G(L)->tmname[i]); /* never collect these names */
}
}
LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
int e;
e = luaI_checkevent(L, event, t);
checktag(L, t);
if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) {
clvalue(L->top) = luaT_gettm(L, t, e);
ttype(L->top) = LUA_TFUNCTION;
/*
** function to be used with macro "fasttm": optimized for absence of
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm = luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
else
ttype(L->top) = LUA_TNIL;
incr_top;
else return tm;
}
LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
int e = luaI_checkevent(L, event, t);
checktag(L, t);
if (!luaT_validevent(t, e))
luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
luaT_eventname[e], luaO_typenames[t],
(t == LUA_TTABLE || t == LUA_TUSERDATA) ?
" with default tag" : "");
switch (ttype(L->top - 1)) {
case LUA_TNIL:
luaT_gettm(L, t, e) = NULL;
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttype(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TFUNCTION:
luaT_gettm(L, t, e) = clvalue(L->top - 1);
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
lua_error(L, "tag method must be a function (or nil)");
mt = G(L)->mt[ttypenv(o)];
}
L->top--;
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}

50
ltm.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.h,v 1.17 2000/10/05 12:14:08 roberto Exp roberto $
** $Id: ltm.h,v 2.9 2010/01/13 16:18:25 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -9,51 +9,49 @@
#include "lobject.h"
#include "lstate.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM"
*/
typedef enum {
TM_GETTABLE = 0,
TM_SETTABLE,
TM_INDEX,
TM_GETGLOBAL,
TM_SETGLOBAL,
TM_NEWINDEX,
TM_GC,
TM_MODE,
TM_LEN,
TM_EQ, /* last tag method with `fast' access */
TM_ADD,
TM_SUB,
TM_MUL,
TM_DIV,
TM_MOD,
TM_POW,
TM_UNM,
TM_LT,
TM_LE,
TM_CONCAT,
TM_GC,
TM_FUNCTION,
TM_CALL,
TM_N /* number of elements in the enum */
} TMS;
struct TM {
Closure *method[TM_N];
TString *collected; /* list of garbage-collected udata with this tag */
};
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define ttypename(x) luaT_typenames_[(x) + 1]
#define objtypename(x) ttypename(ttypenv(x))
LUAI_DDEC const char *const luaT_typenames_[];
#define luaT_gettm(L,tag,event) (L->TMtable[tag].method[event])
#define luaT_gettmbyObj(L,o,e) (luaT_gettm((L),luaT_tag(o),(e)))
#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag)
extern const char *const luaT_eventname[];
void luaT_init (lua_State *L);
void luaT_realtag (lua_State *L, int tag);
int luaT_tag (const TObject *o);
int luaT_validevent (int t, int e); /* used by compatibility module */
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
TMS event);
LUAI_FUNC void luaT_init (lua_State *L);
#endif

688
lua.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.54 2000/10/17 13:36:24 roberto Exp roberto $
** $Id: lua.c,v 1.193 2010/10/18 16:06:33 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -10,313 +10,475 @@
#include <stdlib.h>
#include <string.h>
#define lua_c
#include "lua.h"
#include "luadebug.h"
#include "lauxlib.h"
#include "lualib.h"
static lua_State *L = NULL;
#ifndef PROMPT
#define PROMPT "> "
#if !defined(LUA_PROMPT)
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
#endif
#ifdef _POSIX_SOURCE
#if !defined(LUA_PROGNAME)
#define LUA_PROGNAME "lua"
#endif
#if !defined(LUA_MAXINPUT)
#define LUA_MAXINPUT 512
#endif
#if !defined(LUA_INIT)
#define LUA_INIT "LUA_INIT"
#endif
#define LUA_INITVERSION \
LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
/*
** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
** is, whether we're running lua interactively).
*/
#if defined(LUA_USE_ISATTY)
#include <unistd.h>
#define lua_stdin_is_tty() isatty(0)
#elif defined(LUA_WIN)
#include <io.h>
#include <stdio.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else
static int isatty (int x) { return x==0; } /* assume stdin is a tty */
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
#endif
/*
** global options
** lua_readline defines how to show a prompt and then read a line from
** the standard input.
** lua_saveline defines how to "save" a read line in a "history".
** lua_freeline defines how to free a line read by lua_readline.
*/
struct Options {
int toclose;
int stacksize;
};
#if defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) ((void)L, free(b))
#elif !defined(lua_readline)
#define lua_readline(L,b,p) \
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif
typedef void (*handler)(int); /* type for signal actions */
static void laction (int i);
static lua_Hook old_linehook = NULL;
static lua_Hook old_callhook = NULL;
static lua_State *globalL = NULL;
static const char *progname = LUA_PROGNAME;
static void userinit (void) {
lua_baselibopen(L);
lua_iolibopen(L);
lua_strlibopen(L);
lua_mathlibopen(L);
lua_dblibopen(L);
/* add your libraries here */
}
static handler lreset (void) {
return signal(SIGINT, laction);
}
static void lstop (void) {
lua_setlinehook(L, old_linehook);
lua_setcallhook(L, old_callhook);
lreset();
lua_error(L, "interrupted!");
static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void laction (int i) {
(void)i; /* to avoid warnings */
signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
int res;
handler h = lreset();
int top = lua_gettop(L);
res = f(L, name); /* dostring | dofile */
lua_settop(L, top); /* remove eventual results */
signal(SIGINT, h); /* restore old action */
/* Lua gives no message in such cases, so lua.c provides one */
if (res == LUA_ERRMEM) {
fprintf(stderr, "lua: memory allocation error\n");
static void print_usage (const char *badoption) {
if (badoption[1] == 'e' || badoption[1] == 'l') {
luai_writestringerror("%s: ", progname);
luai_writestringerror("'%s' needs argument\n", badoption);
} else {
luai_writestringerror("%s: ", progname);
luai_writestringerror("unrecognized option '%s'\n", badoption);
}
else if (res == LUA_ERRERR)
fprintf(stderr, "lua: error in error message\n");
return res;
luai_writestringerror(
"usage: %s [options] [script [args]]\n"
"Available options are:\n"
" -e stat execute string " LUA_QL("stat") "\n"
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -l name require library " LUA_QL("name") "\n"
" -v show version information\n"
" -- stop handling options\n"
" - stop handling options and execute stdin\n"
,
progname);
}
static void print_message (void) {
fprintf(stderr,
"usage: lua [options]. Available options are:\n"
" - execute stdin as a file\n"
" -c close Lua when exiting\n"
" -e stat execute string `stat'\n"
" -f name execute file `name' with remaining arguments in table `arg'\n"
" -i enter interactive mode with prompt\n"
" -q enter interactive mode without prompt\n"
" -sNUM set stack size to NUM (must be the first option)\n"
" -v print version information\n"
" a=b set global `a' to string `b'\n"
" name execute file `name'\n"
);
static void l_message (const char *pname, const char *msg) {
if (pname) luai_writestringerror("%s: ", pname);
luai_writestringerror("%s\n", msg);
}
static void print_version (void) {
printf("%.80s %.80s\n", LUA_VERSION, LUA_COPYRIGHT);
}
static void assign (char *arg) {
char *eq = strchr(arg, '=');
*eq = '\0'; /* spilt `arg' in two strings (name & value) */
lua_pushstring(L, eq+1);
lua_setglobal(L, arg);
}
static void getargs (char *argv[]) {
int i;
lua_newtable(L);
for (i=0; argv[i]; i++) {
/* arg[i] = argv[i] */
lua_pushnumber(L, i);
lua_pushstring(L, argv[i]);
lua_settable(L, -3);
static int report (lua_State *L, int status) {
if (status != LUA_OK && !lua_isnil(L, -1)) {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) msg = "(error object is not a string)";
l_message(progname, msg);
lua_pop(L, 1);
/* force a complete garbage collection in case of errors */
lua_gc(L, LUA_GCCOLLECT, 0);
}
/* arg.n = maximum index in table `arg' */
lua_pushstring(L, "n");
lua_pushnumber(L, i-1);
lua_settable(L, -3);
return status;
}
static int l_getargs (lua_State *l) {
char **argv = (char **)lua_touserdata(l, -1);
getargs(argv);
/* the next function is called unprotected, so it must avoid errors */
static void finalreport (lua_State *L, int status) {
if (status != LUA_OK) {
const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1)
: NULL;
if (msg == NULL) msg = "(error object is not a string)";
l_message(progname, msg);
lua_pop(L, 1);
}
}
static int traceback (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg)
luaL_traceback(L, L, msg, 1);
else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */
if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */
lua_pushliteral(L, "(no error message)");
}
return 1;
}
static int file_input (const char *argv) {
int result = ldo(lua_dofile, argv);
if (result) {
if (result == LUA_ERRFILE) {
fprintf(stderr, "lua: cannot execute file ");
perror(argv);
}
return EXIT_FAILURE;
}
else
return EXIT_SUCCESS;
}
/* maximum length of an input string */
#ifndef MAXINPUT
#define MAXINPUT BUFSIZ
#endif
static void manual_input (int version, int prompt) {
int cont = 1;
if (version) print_version();
while (cont) {
char buffer[MAXINPUT];
int i = 0;
if (prompt) {
const char *s;
lua_getglobal(L, "_PROMPT");
s = lua_tostring(L, -1);
if (!s) s = PROMPT;
fputs(s, stdout);
lua_pop(L, 1); /* remove global */
}
for(;;) {
int c = getchar();
if (c == EOF) {
cont = 0;
break;
}
else if (c == '\n') {
if (i>0 && buffer[i-1] == '\\')
buffer[i-1] = '\n';
else break;
}
else if (i >= MAXINPUT-1) {
fprintf(stderr, "lua: input line too long\n");
break;
}
else buffer[i++] = (char)c;
}
buffer[i] = '\0';
ldo(lua_dostring, buffer);
lua_settop(L, 0); /* remove eventual results */
}
printf("\n");
}
static int handle_argv (char *argv[], struct Options *opt) {
if (opt->stacksize > 0) argv++; /* skip option `-s' (if present) */
if (*argv == NULL) { /* no more arguments? */
if (isatty(0)) {
manual_input(1, 1);
}
else
ldo(lua_dofile, NULL); /* executes stdin as a file */
}
else { /* other arguments; loop over them */
int i;
for (i = 0; argv[i] != NULL; i++) {
if (argv[i][0] != '-') { /* not an option? */
if (strchr(argv[i], '='))
assign(argv[i]);
else
if (file_input(argv[i]) != EXIT_SUCCESS)
return EXIT_FAILURE; /* stop if file fails */
}
else switch (argv[i][1]) { /* option */
case 0: {
ldo(lua_dofile, NULL); /* executes stdin as a file */
break;
}
case 'i': {
manual_input(0, 1);
break;
}
case 'q': {
manual_input(0, 0);
break;
}
case 'c': {
opt->toclose = 1;
break;
}
case 'v': {
print_version();
break;
}
case 'e': {
i++;
if (argv[i] == NULL) {
print_message();
return EXIT_FAILURE;
}
if (ldo(lua_dostring, argv[i]) != 0) {
fprintf(stderr, "lua: error running argument `%.99s'\n", argv[i]);
return EXIT_FAILURE;
}
break;
}
case 'f': {
i++;
if (argv[i] == NULL) {
print_message();
return EXIT_FAILURE;
}
getargs(argv+i); /* collect remaining arguments */
lua_setglobal(L, "arg");
return file_input(argv[i]); /* stop scanning arguments */
}
case 's': {
fprintf(stderr, "lua: stack size (`-s') must be the first option\n");
return EXIT_FAILURE;
}
default: {
print_message();
return EXIT_FAILURE;
}
}
}
}
return EXIT_SUCCESS;
}
static void getstacksize (int argc, char *argv[], struct Options *opt) {
if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 's') {
int stacksize = atoi(&argv[1][2]);
if (stacksize <= 0) {
fprintf(stderr, "lua: invalid stack size ('%.20s')\n", &argv[1][2]);
exit(EXIT_FAILURE);
}
opt->stacksize = stacksize;
}
else
opt->stacksize = 0; /* no stack size */
}
static void register_getargs (char *argv[]) {
lua_pushuserdata(L, argv);
lua_pushcclosure(L, l_getargs, 1);
lua_setglobal(L, "getargs");
}
int main (int argc, char *argv[]) {
struct Options opt;
static int docall (lua_State *L, int narg, int nres) {
int status;
opt.toclose = 0;
getstacksize(argc, argv, &opt); /* handle option `-s' */
L = lua_open(opt.stacksize); /* create state */
userinit(); /* open libraries */
register_getargs(argv); /* create `getargs' function */
status = handle_argv(argv+1, &opt);
if (opt.toclose)
lua_close(L);
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
globalL = L; /* to be available to 'laction' */
signal(SIGINT, laction);
status = lua_pcall(L, narg, nres, base);
signal(SIGINT, SIG_DFL);
lua_remove(L, base); /* remove traceback function */
return status;
}
static void print_version (void) {
printf("%s\n", LUA_COPYRIGHT);
}
static int getargs (lua_State *L, char **argv, int n) {
int narg;
int i;
int argc = 0;
while (argv[argc]) argc++; /* count total number of arguments */
narg = argc - (n + 1); /* number of arguments to the script */
luaL_checkstack(L, narg + 3, "too many arguments to script");
for (i=n+1; i < argc; i++)
lua_pushstring(L, argv[i]);
lua_createtable(L, narg, n + 1);
for (i=0; i < argc; i++) {
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i - n);
}
return narg;
}
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name);
if (status == LUA_OK) status = docall(L, 0, 0);
return report(L, status);
}
static int dostring (lua_State *L, const char *s, const char *name) {
int status = luaL_loadbuffer(L, s, strlen(s), name);
if (status == LUA_OK) status = docall(L, 0, 0);
return report(L, status);
}
static int dolibrary (lua_State *L, const char *name) {
int status;
lua_pushglobaltable(L);
lua_getfield(L, -1, "require");
lua_pushstring(L, name);
status = docall(L, 1, 1);
if (status == LUA_OK) {
lua_setfield(L, -2, name); /* global[name] = require return */
lua_pop(L, 1); /* remove global table */
}
else
lua_remove(L, -2); /* remove global table (below error msg.) */
return report(L, status);
}
static const char *get_prompt (lua_State *L, int firstline) {
const char *p;
lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
p = lua_tostring(L, -1);
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
lua_pop(L, 1); /* remove global */
return p;
}
/* mark in error messages for incomplete statements */
#define mark "<eof>"
#define marklen (sizeof(mark) - 1)
static int incomplete (lua_State *L, int status) {
if (status == LUA_ERRSYNTAX) {
size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg);
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, mark) == 0) {
lua_pop(L, 1);
return 1;
}
}
return 0; /* else... */
}
static int pushline (lua_State *L, int firstline) {
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
if (lua_readline(L, b, prmt) == 0)
return 0; /* no input */
l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[l-1] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* first line starts with `=' ? */
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
else
lua_pushstring(L, b);
lua_freeline(L, b);
return 1;
}
static int loadline (lua_State *L) {
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
for (;;) { /* repeat until gets a complete line */
size_t l;
const char *line = lua_tolstring(L, 1, &l);
status = luaL_loadbuffer(L, line, l, "=stdin");
if (!incomplete(L, status)) break; /* cannot try to add lines? */
if (!pushline(L, 0)) /* no more input? */
return -1;
lua_pushliteral(L, "\n"); /* add a new line... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
lua_saveline(L, 1);
lua_remove(L, 1); /* remove line */
return status;
}
static void dotty (lua_State *L) {
int status;
const char *oldprogname = progname;
progname = NULL;
while ((status = loadline(L)) != -1) {
if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET);
report(L, status);
if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */
luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
luai_writestring("\n", 1);
progname = oldprogname;
}
static int handle_script (lua_State *L, char **argv, int n) {
int status;
const char *fname;
int narg = getargs(L, argv, n); /* collect arguments */
lua_setglobal(L, "arg");
fname = argv[n];
if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
fname = NULL; /* stdin */
status = luaL_loadfile(L, fname);
lua_insert(L, -(narg+1));
if (status == LUA_OK)
status = docall(L, narg, LUA_MULTRET);
else
lua_pop(L, narg);
return report(L, status);
}
/* check that argument has no extra characters at the end */
#define noextrachars(x) {if ((x)[2] != '\0') return -1;}
static int collectargs (char **argv, int *pi, int *pv, int *pe) {
int i;
for (i = 1; argv[i] != NULL; i++) {
if (argv[i][0] != '-') /* not an option? */
return i;
switch (argv[i][1]) { /* option */
case '-':
noextrachars(argv[i]);
return (argv[i+1] != NULL ? i+1 : 0);
case '\0':
return i;
case 'i':
noextrachars(argv[i]);
*pi = 1; /* go through */
case 'v':
noextrachars(argv[i]);
*pv = 1;
break;
case 'e':
*pe = 1; /* go through */
case 'l': /* both options need an argument */
if (argv[i][2] == '\0') { /* no concatenated argument? */
i++; /* try next 'argv' */
if (argv[i] == NULL || argv[i][0] == '-')
return -(i - 1); /* no next argument or it is another option */
}
break;
default: /* invalid option; return its index... */
return -i; /* ...as a negative value */
}
}
return 0;
}
static int runargs (lua_State *L, char **argv, int n) {
int i;
for (i = 1; i < n; i++) {
lua_assert(argv[i][0] == '-');
switch (argv[i][1]) { /* option */
case 'e': {
const char *chunk = argv[i] + 2;
if (*chunk == '\0') chunk = argv[++i];
lua_assert(chunk != NULL);
if (dostring(L, chunk, "=(command line)") != LUA_OK)
return 0;
break;
}
case 'l': {
const char *filename = argv[i] + 2;
if (*filename == '\0') filename = argv[++i];
lua_assert(filename != NULL);
if (dolibrary(L, filename) != LUA_OK)
return 0; /* stop if file fails */
break;
}
default: break;
}
}
return 1;
}
static int handle_luainit (lua_State *L) {
const char *name = "=" LUA_INITVERSION;
const char *init = getenv(name + 1);
if (init == NULL) {
name = "=" LUA_INIT;
init = getenv(name + 1); /* try alternative name */
}
if (init == NULL) return LUA_OK;
else if (init[0] == '@')
return dofile(L, init+1);
else
return dostring(L, init, name);
}
static int pmain (lua_State *L) {
int argc = (int)lua_tointeger(L, 1);
char **argv = (char **)lua_touserdata(L, 2);
int script;
int has_i = 0, has_v = 0, has_e = 0;
if (argv[0] && argv[0][0]) progname = argv[0];
script = collectargs(argv, &has_i, &has_v, &has_e);
if (script < 0) { /* invalid arg? */
print_usage(argv[-script]);
return 0;
}
if (has_v) print_version();
/* open standard libraries */
luaL_checkversion(L);
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0);
/* run LUA_INIT */
if (handle_luainit(L) != LUA_OK) return 0;
/* execute arguments -e and -l */
if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
/* execute main script (if there is one) */
if (script && handle_script(L, argv, script) != LUA_OK) return 0;
if (has_i) /* -i option? */
dotty(L);
else if (script == 0 && !has_e && !has_v) { /* no arguments? */
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
lua_pushboolean(L, 1); /* signal no errors */
return 1;
}
int main (int argc, char **argv) {
int status, result;
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
/* call 'pmain' in protected mode */
lua_pushcfunction(L, &pmain);
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0);
result = lua_toboolean(L, -1); /* get result */
finalreport(L, status);
lua_close(L);
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}

493
lua.h
View File

@@ -1,9 +1,7 @@
/*
** $Id: lua.h,v 1.78 2000/10/30 12:38:50 roberto Exp roberto $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
** www: http://www.tecgraf.puc-rio.br/lua/
** $Id: lua.h,v 1.275 2010/10/25 20:31:11 roberto Exp roberto $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
*/
@@ -11,238 +9,433 @@
#ifndef lua_h
#define lua_h
/* definition of `size_t' */
#include <stdarg.h>
#include <stddef.h>
/* mark for all API functions */
#ifndef LUA_API
#define LUA_API extern
#endif
#include "luaconf.h"
#define LUA_VERSION "Lua 4.0"
#define LUA_COPYRIGHT "Copyright (C) 1994-2000 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "2"
#define LUA_VERSION_RELEASE "0"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_VERSION_NUM 502
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2010 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
/* name of global variable with error handler */
#define LUA_ERRORMESSAGE "_ERRORMESSAGE"
/* mark for precompiled code ('<esc>Lua') */
#define LUA_SIGNATURE "\033Lua"
/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
#define LUA_REFREGISTRY 0
/* pre-defined tags */
#define LUA_ANYTAG (-1)
#define LUA_NOTAG (-2)
/* option for multiple returns in lua_call */
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
#define LUA_MULTRET (-1)
/* minimum stack available for a C function */
#define LUA_MINSTACK 20
/*
** pseudo-indices
*/
#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
/* error codes for lua_do* */
#define LUA_ERRRUN 1
#define LUA_ERRFILE 2
/* thread status */
#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
#define LUA_ERRERR 5
#define LUA_ERRGCMM 5
#define LUA_ERRERR 6
typedef struct lua_State lua_State;
typedef int (*lua_CFunction) (lua_State *L);
/*
** types returned by `lua_type'
*/
#define LUA_TNONE (-1)
#define LUA_TUSERDATA 0
#define LUA_TNIL 1
#define LUA_TNUMBER 2
#define LUA_TSTRING 3
#define LUA_TTABLE 4
#define LUA_TFUNCTION 5
/*
** functions that read/write blocks when loading/dumping Lua chunks
*/
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
/*
** prototype for memory-allocation functions
*/
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_NUMTAGS 9
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
/* predefined values in the registry */
#define LUA_RIDX_MAINTHREAD 1
#define LUA_RIDX_GLOBALS 2
#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;
/* type for integer functions */
typedef LUA_INTEGER lua_Integer;
/* unsigned integer type */
typedef LUA_UNSIGNED lua_Unsigned;
/*
** generic extra include file
*/
#if defined(LUA_USER_H)
#include LUA_USER_H
#endif
/*
** state manipulation
*/
LUA_API lua_State *lua_open (int stacksize);
LUA_API void lua_close (lua_State *L);
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
LUA_API const lua_Number *(lua_version) (lua_State *L);
/*
** basic stack manipulation
*/
LUA_API int lua_gettop (lua_State *L);
LUA_API void lua_settop (lua_State *L, int index);
LUA_API void lua_pushvalue (lua_State *L, int index);
LUA_API void lua_remove (lua_State *L, int index);
LUA_API void lua_insert (lua_State *L, int index);
LUA_API int lua_stackspace (lua_State *L);
LUA_API int (lua_absindex) (lua_State *L, int idx);
LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
LUA_API void (lua_remove) (lua_State *L, int idx);
LUA_API void (lua_insert) (lua_State *L, int idx);
LUA_API void (lua_replace) (lua_State *L, int idx);
LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx);
LUA_API int (lua_checkstack) (lua_State *L, int sz);
LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
/*
** access functions (stack -> C)
*/
LUA_API int lua_type (lua_State *L, int index);
LUA_API const char *lua_typename (lua_State *L, int t);
LUA_API int lua_isnumber (lua_State *L, int index);
LUA_API int lua_isstring (lua_State *L, int index);
LUA_API int lua_iscfunction (lua_State *L, int index);
LUA_API int lua_tag (lua_State *L, int index);
LUA_API int (lua_isnumber) (lua_State *L, int idx);
LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);
LUA_API int lua_equal (lua_State *L, int index1, int index2);
LUA_API int lua_lessthan (lua_State *L, int index1, int index2);
LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
LUA_API const void *(lua_topointer) (lua_State *L, int idx);
LUA_API double lua_tonumber (lua_State *L, int index);
LUA_API const char *lua_tostring (lua_State *L, int index);
LUA_API size_t lua_strlen (lua_State *L, int index);
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index);
LUA_API void *lua_touserdata (lua_State *L, int index);
LUA_API const void *lua_topointer (lua_State *L, int index);
/*
** Comparison and arithmetic functions
*/
#define LUA_OPADD 0 /* ORDER TM */
#define LUA_OPSUB 1
#define LUA_OPMUL 2
#define LUA_OPDIV 3
#define LUA_OPMOD 4
#define LUA_OPPOW 5
#define LUA_OPUNM 6
LUA_API void (lua_arith) (lua_State *L, int op);
#define LUA_OPEQ 0
#define LUA_OPLT 1
#define LUA_OPLE 2
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
/*
** push functions (C -> stack)
*/
LUA_API void lua_pushnil (lua_State *L);
LUA_API void lua_pushnumber (lua_State *L, double n);
LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len);
LUA_API void lua_pushstring (lua_State *L, const char *s);
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
LUA_API void lua_pushusertag (lua_State *L, void *u, int tag);
LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
LUA_API void lua_getglobal (lua_State *L, const char *name);
LUA_API void lua_gettable (lua_State *L, int index);
LUA_API void lua_rawget (lua_State *L, int index);
LUA_API void lua_rawgeti (lua_State *L, int index, int n);
LUA_API void lua_getglobals (lua_State *L);
LUA_API void lua_gettagmethod (lua_State *L, int tag, const char *event);
LUA_API int lua_getref (lua_State *L, int ref);
LUA_API void lua_newtable (lua_State *L);
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
LUA_API void (lua_getuservalue) (lua_State *L, int idx);
/*
** set functions (stack -> Lua)
*/
LUA_API void lua_setglobal (lua_State *L, const char *name);
LUA_API void lua_settable (lua_State *L, int index);
LUA_API void lua_rawset (lua_State *L, int index);
LUA_API void lua_rawseti (lua_State *L, int index, int n);
LUA_API void lua_setglobals (lua_State *L);
LUA_API void lua_settagmethod (lua_State *L, int tag, const char *event);
LUA_API int lua_ref (lua_State *L, int lock);
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API void (lua_setuservalue) (lua_State *L, int idx);
/*
** "do" functions (run Lua code)
** 'load' and 'call' functions (load and run Lua code)
*/
LUA_API int lua_call (lua_State *L, int nargs, int nresults);
LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults);
LUA_API int lua_dofile (lua_State *L, const char *filename);
LUA_API int lua_dostring (lua_State *L, const char *str);
LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name);
LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
lua_CFunction k);
#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
LUA_API int (lua_getctx) (lua_State *L, int *ctx);
LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
int ctx, lua_CFunction k);
#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
/*
** Garbage-collection functions
** coroutine functions
*/
LUA_API int lua_getgcthreshold (lua_State *L);
LUA_API int lua_getgccount (lua_State *L);
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx,
lua_CFunction k);
#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
LUA_API int (lua_resume) (lua_State *L, int narg);
LUA_API int (lua_status) (lua_State *L);
/*
** garbage-collection function and options
*/
#define LUA_GCSTOP 0
#define LUA_GCRESTART 1
#define LUA_GCCOLLECT 2
#define LUA_GCCOUNT 3
#define LUA_GCCOUNTB 4
#define LUA_GCSTEP 5
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7
#define LUA_GCSETMAJORINC 8
#define LUA_GCISRUNNING 9
#define LUA_GCGEN 10
#define LUA_GCINC 11
LUA_API int (lua_gc) (lua_State *L, int what, int data);
/*
** miscellaneous functions
*/
LUA_API int lua_newtag (lua_State *L);
LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
LUA_API void lua_settag (lua_State *L, int tag);
LUA_API void lua_error (lua_State *L, const char *s);
LUA_API int (lua_error) (lua_State *L);
LUA_API void lua_unref (lua_State *L, int ref);
LUA_API int (lua_next) (lua_State *L, int idx);
LUA_API int lua_next (lua_State *L, int index);
LUA_API int lua_getn (lua_State *L, int index);
LUA_API void (lua_concat) (lua_State *L, int n);
LUA_API void (lua_len) (lua_State *L, int idx);
LUA_API void lua_concat (lua_State *L, int n);
LUA_API void *lua_newuserdata (lua_State *L, size_t size);
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
/*
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL)
#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL)
#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL)
#define lua_pop(L,n) lua_settop(L, -(n)-1)
#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0)
#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t))
#define lua_newtable(L) lua_createtable(L, 0, 0)
#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA)
#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE)
#define lua_setglobal(L,s) \
(lua_pushglobaltable(L), lua_pushvalue(L, -2), \
lua_setfield(L, -2, (s)), lua_pop(L, 2))
#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)
#define lua_getglobal(L,s) \
(lua_pushglobaltable(L), lua_getfield(L, -1, (s)), lua_remove(L, -2))
#endif
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
#define lua_pushliteral(L, s) \
lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
#define lua_pushglobaltable(L) \
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
/*
** {======================================================================
** Debug API
** =======================================================================
*/
/*
** Event codes
*/
#define LUA_HOOKCALL 0
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
#define LUA_HOOKTAILCALL 4
/*
** Event masks
*/
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
#define LUA_MASKRET (1 << LUA_HOOKRET)
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
typedef struct lua_Debug lua_Debug; /* activation record */
/* Functions to be called by the debugger in specific events */
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
int fidx2, int n2);
LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
LUA_API lua_Hook (lua_gethook) (lua_State *L);
LUA_API int (lua_gethookmask) (lua_State *L);
LUA_API int (lua_gethookcount) (lua_State *L);
struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
const char *source; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) number of upvalues */
unsigned char nparams;/* (u) number of parameters */
char isvararg; /* (u) */
char istailcall; /* (t) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
struct CallInfo *i_ci; /* active function */
};
/* }====================================================================== */
/******************************************************************************
* Copyright (C) 1994-2000 TeCGraf, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its
* documentation for any purpose, including commercial applications, subject to
* the following conditions:
*
* - The above copyright notice and this permission notice shall appear in all
* copies or substantial portions of this software.
*
* - The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in a
* product, an acknowledgment in the product documentation would be greatly
* appreciated (but it is not required).
*
* - Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* The authors specifically disclaim any warranties, including, but not limited
* to, the implied warranties of merchantability and fitness for a particular
* purpose. The software provided hereunder is on an "as is" basis, and the
* authors have no obligation to provide maintenance, support, updates,
* enhancements, or modifications. In no event shall TeCGraf, PUC-Rio, or the
* authors be held liable to any party for direct, indirect, special,
* incidental, or consequential damages arising out of the use of this software
* and its documentation.
*
* The Lua language and this implementation have been entirely designed and
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
* Copyright (C) 1994-2010 Lua.org, PUC-Rio. All rights reserved.
*
* This implementation contains no third-party code.
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
#endif

473
luaconf.h Normal file
View File

@@ -0,0 +1,473 @@
/*
** $Id: luaconf.h,v 1.150 2010/11/10 17:38:10 roberto Exp roberto $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
#ifndef lconfig_h
#define lconfig_h
#include <limits.h>
#include <stddef.h>
/*
** ==================================================================
** Search for "@@" to find all configurable definitions.
** ===================================================================
*/
/*
@@ LUA_ANSI controls the use of non-ansi features.
** CHANGE it (define it) if you want Lua to avoid the use of any
** non-ansi feature or library.
*/
#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__)
#define LUA_ANSI
#endif
#if !defined(LUA_ANSI) && defined(_WIN32)
#define LUA_WIN
#endif
#if defined(LUA_WIN)
#define LUA_DL_DLL
#endif
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#define LUA_USE_READLINE /* needs some extra libraries */
#endif
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* does not need -ldl */
#define LUA_USE_READLINE /* needs an extra library: -lreadline */
#endif
/*
@@ LUA_USE_POSIX includes all functionality listed as X/Open System
@* Interfaces Extension (XSI).
** CHANGE it (define it) if your system is XSI compatible.
*/
#if defined(LUA_USE_POSIX)
#define LUA_USE_MKSTEMP
#define LUA_USE_ISATTY
#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP
#endif
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@* Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
@* C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
#if defined(_WIN32) /* { */
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#define LUA_LDIR "!\\lua\\"
#define LUA_CDIR "!\\"
#define LUA_PATH_DEFAULT \
LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua"
#define LUA_CPATH_DEFAULT \
LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
#else /* }{ */
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/"
#define LUA_ROOT "/usr/local/"
#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR
#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR
#define LUA_PATH_DEFAULT \
LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua"
#define LUA_CPATH_DEFAULT \
LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
#endif /* } */
/*
@@ LUA_DIRSEP is the directory separator (for submodules).
** CHANGE it if your machine does not use "/" as the directory separator
** and is not Windows. (On Windows Lua automatically uses "\".)
*/
#if defined(_WIN32)
#define LUA_DIRSEP "\\"
#else
#define LUA_DIRSEP "/"
#endif
/*
@@ LUA_ENV is the name of the variable that holds the current
@@ environment, used to access global names.
** CHANGE it if you do not like this name.
*/
#define LUA_ENV "_ENV"
/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all auxiliary library functions.
@@ LUAMOD_API is a mark for all standard library opening functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL) /* { */
#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
#define LUA_API __declspec(dllexport)
#else /* }{ */
#define LUA_API __declspec(dllimport)
#endif /* } */
#else /* }{ */
#define LUA_API extern
#endif /* } */
/* more often than not the libs go together with the core */
#define LUALIB_API LUA_API
#define LUAMOD_API LUALIB_API
/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
@* exported to outside modules.
@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
@* that are not to be exported to outside modules (LUAI_DDEF for
@* definitions and LUAI_DDEC for declarations).
** CHANGE them if you need to mark them in some special way. Elf/gcc
** (versions 3.2 and later) mark them as "hidden" to optimize access
** when Lua is compiled as a shared library. Not all elf targets support
** this attribute. Unfortunately, gcc does not offer a way to check
** whether the target offers that support, and those without support
** give a warning about it. To avoid these warnings, change to the
** default definition.
*/
#if defined(luaall_c) /* { */
#define LUAI_FUNC static
#define LUAI_DDEC static
#define LUAI_DDEF static
#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
defined(__ELF__)
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
#define LUAI_DDEC LUAI_FUNC
#define LUAI_DDEF /* empty */
#else /* }{ */
#define LUAI_FUNC extern
#define LUAI_DDEC extern
#define LUAI_DDEF /* empty */
#endif /* } */
/*
@@ LUA_QL describes how error messages quote program elements.
** CHANGE it if you want a different appearance.
*/
#define LUA_QL(x) "'" x "'"
#define LUA_QS LUA_QL("%s")
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@* of a function in debug information.
** CHANGE it if you want a different size.
*/
#define LUA_IDSIZE 60
/*
@@ luai_writestring defines how 'print' prints its results.
*/
#include <stdio.h>
#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
/*
@@ luai_writestringerror defines how to print error messages.
** (A format string with one argument is enough for Lua...)
*/
#define luai_writestringerror(s,p) \
(fprintf(stderr, (s), (p)), fflush(stderr))
/*
** {==================================================================
** Compatibility with previous versions
** ===================================================================
*/
/*
@@ LUA_COMPAT_ALL controls all compatibility options.
** You can define it to get all options, or change specific options
** to fit your specific needs.
*/
#if defined(LUA_COMPAT_ALL) /* { */
/*
@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
** You can replace it with 'table.unpack'.
*/
#define LUA_COMPAT_UNPACK
/*
@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
** You can call your C function directly (with light C functions).
*/
#define lua_cpcall(L,f,u) \
(lua_pushcfunction(L, (f)), \
lua_pushlightuserdata(L,(u)), \
lua_pcall(L,1,0,0))
/*
@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
** You can rewrite 'log10(x)' as 'log(x, 10)'.
*/
#define LUA_COMPAT_LOG10
/*
@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
*/
#define LUA_COMPAT_MAXN
/*
@@ The following macros supply trivial compatibility for some
** changes in the API. The macros themselves document how to
** change your code to avoid using them.
*/
#define lua_strlen(L,i) lua_rawlen(L, (i))
#define lua_objlen(L,i) lua_rawlen(L, (i))
#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
/*
@@ LUA_COMPAT_MODULE controls compatibility with previous
** module functions 'module' (Lua) and 'luaL_register' (C).
*/
#define LUA_COMPAT_MODULE
#endif /* } */
/* }================================================================== */
/*
@@ LUAI_BITSINT defines the number of bits in an int.
** CHANGE here if Lua cannot automatically detect the number of bits of
** your machine. Probably you do not need to change this.
*/
/* avoid overflows in comparison */
#if INT_MAX-20 < 32760 /* { */
#define LUAI_BITSINT 16
#elif INT_MAX > 2147483640L /* }{ */
/* int has at least 32 bits */
#define LUAI_BITSINT 32
#else /* }{ */
#error "you must define LUA_BITSINT with number of bits in an integer"
#endif /* } */
/*
@@ LUA_INT32 is an signed integer with exactly 32 bits.
@@ LUAI_UMEM is an unsigned integer big enough to count the total
@* memory used by Lua.
@@ LUAI_MEM is a signed integer big enough to count the total memory
@* used by Lua.
** CHANGE here if for some weird reason the default definitions are not
** good enough for your machine. Probably you do not need to change
** this.
*/
#if LUAI_BITSINT >= 32 /* { */
#define LUA_INT32 int
#define LUAI_UMEM size_t
#define LUAI_MEM ptrdiff_t
#else /* }{ */
/* 16-bit ints */
#define LUA_INT32 long
#define LUAI_UMEM unsigned long
#define LUAI_MEM long
#endif /* } */
/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua to consume unlimited stack
** space (and to reserve some numbers for pseudo-indices).
*/
#if LUAI_BITSINT >= 32
#define LUAI_MAXSTACK 1000000
#else
#define LUAI_MAXSTACK 15000
#endif
/* reserve some space for error handling */
#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
** CHANGE it if it uses too much C-stack space.
*/
#define LUAL_BUFFERSIZE BUFSIZ
/*
** {==================================================================
@@ LUA_NUMBER is the type of numbers in Lua.
** CHANGE the following definitions only if you want to build Lua
** with a number type different from double. You may also need to
** change lua_number2int & lua_number2integer.
** ===================================================================
*/
#define LUA_NUMBER_DOUBLE
#define LUA_NUMBER double
/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number.
*/
#define LUAI_UACNUMBER double
/*
@@ LUA_NUMBER_SCAN is the format for reading numbers.
@@ LUA_NUMBER_FMT is the format for writing numbers.
@@ lua_number2str converts a number to a string.
@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
@@ lua_str2number converts a string to a number.
*/
#define LUA_NUMBER_SCAN "%lf"
#define LUA_NUMBER_FMT "%.14g"
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
#define lua_str2number(s,p) strtod((s), (p))
/*
@@ The luai_num* macros define the primitive operations over numbers.
*/
/* the following operations need the math library */
#if defined(lobject_c) || defined(lvm_c) || defined(luaall_c)
#include <math.h>
#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
#define luai_numpow(L,a,b) (pow(a,b))
#endif
/* these are quite standard operations */
#if defined(LUA_CORE)
#define luai_numadd(L,a,b) ((a)+(b))
#define luai_numsub(L,a,b) ((a)-(b))
#define luai_nummul(L,a,b) ((a)*(b))
#define luai_numdiv(L,a,b) ((a)/(b))
#define luai_numunm(L,a) (-(a))
#define luai_numeq(a,b) ((a)==(b))
#define luai_numlt(L,a,b) ((a)<(b))
#define luai_numle(L,a,b) ((a)<=(b))
#define luai_numisnan(L,a) (!luai_numeq((a), (a)))
#endif
/*
@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
** machines, ptrdiff_t gives a good choice between int or long.)
*/
#define LUA_INTEGER ptrdiff_t
/*
@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
** It must have at least 32 bits.
*/
#define LUA_UNSIGNED unsigned LUA_INT32
#if defined(LUA_CORE) /* { */
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
with a DirectX idiosyncrasy */
#if defined(_MSC_VER) && defined(M_IX86) /* { */
#define MS_ASMTRICK
#else /* }{ */
/* the next definition uses a trick that should work on any machine
using IEEE754 with a 32-bit integer type */
#define LUA_IEEE754TRICK
/*
@@ LUA_IEEEENDIAN is the endianness of doubles in your machine
@@ (0 for little endian, 1 for big endian); if not defined, Lua will
@@ check it dynamically.
*/
/* check for known architectures */
#if defined(__i386__) || defined(__i386) || defined(i386) || \
defined (__x86_64)
#define LUA_IEEEENDIAN 0
#elif defined(__POWERPC__) || defined(__ppc__)
#define LUA_IEEEENDIAN 1
#endif
#endif /* } */
#endif /* } */
#endif /* } */
/* }================================================================== */
/* =================================================================== */
/*
** Local configuration. You can use this space to add your redefinitions
** without modifying the main part of the file.
*/
#endif

View File

@@ -1,46 +0,0 @@
/*
** $Id: luadebug.h,v 1.16 2000/10/20 16:39:03 roberto Exp roberto $
** Debugging API
** See Copyright Notice in lua.h
*/
#ifndef luadebug_h
#define luadebug_h
#include "lua.h"
typedef struct lua_Debug lua_Debug; /* activation record */
typedef struct lua_Localvar lua_Localvar;
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
#define LUA_IDSIZE 60
struct lua_Debug {
const char *event; /* `call', `return' */
int currentline; /* (l) */
const char *name; /* (n) */
const char *namewhat; /* (n) `global', `tag method', `local', `field' */
int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
const char *source; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
struct lua_TObject *_func; /* active function */
};
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.13 2000/10/20 16:39:03 roberto Exp roberto $
** $Id: lualib.h,v 1.40 2010/06/10 21:29:47 roberto Exp roberto $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -11,24 +11,48 @@
#include "lua.h"
#ifndef LUALIB_API
#define LUALIB_API extern
/* Key to file-handle type */
#define LUA_FILEHANDLE "FILE*"
LUAMOD_API int (luaopen_base) (lua_State *L);
#define LUA_COLIBNAME "coroutine"
LUAMOD_API int (luaopen_coroutine) (lua_State *L);
#define LUA_TABLIBNAME "table"
LUAMOD_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
LUAMOD_API int (luaopen_io) (lua_State *L);
#define LUA_OSLIBNAME "os"
LUAMOD_API int (luaopen_os) (lua_State *L);
#define LUA_STRLIBNAME "string"
LUAMOD_API int (luaopen_string) (lua_State *L);
#define LUA_BITLIBNAME "bit32"
LUAMOD_API int (luaopen_bit32) (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUAMOD_API int (luaopen_math) (lua_State *L);
#define LUA_DBLIBNAME "debug"
LUAMOD_API int (luaopen_debug) (lua_State *L);
#define LUA_LOADLIBNAME "package"
LUAMOD_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);
#ifndef lua_assert
#define lua_assert(x) ((void)0)
#endif
#define LUA_ALERT "_ALERT"
LUALIB_API void lua_baselibopen (lua_State *L);
LUALIB_API void lua_iolibopen (lua_State *L);
LUALIB_API void lua_strlibopen (lua_State *L);
LUALIB_API void lua_mathlibopen (lua_State *L);
LUALIB_API void lua_dblibopen (lua_State *L);
/* Auxiliary functions (private) */
const char *luaI_classend (lua_State *L, const char *p);
int luaI_singlematch (int c, const char *p, const char *ep);
#endif

330
lundump.c
View File

@@ -1,244 +1,224 @@
/*
** $Id: lundump.c,v 1.33 2000/10/31 16:57:23 lhf Exp $
** load bytecodes from files
** $Id: lundump.c,v 1.67 2010/10/13 21:04:52 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#define lundump_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lobject.h"
#include "lstring.h"
#include "lundump.h"
#include "lzio.h"
#define LoadByte ezgetc
typedef struct {
lua_State* L;
ZIO* Z;
Mbuffer* b;
const char* name;
} LoadState;
static const char* ZNAME (ZIO* Z)
static void error(LoadState* S, const char* why)
{
const char* s=zname(Z);
return (*s=='@') ? s+1 : s;
luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
luaD_throw(S->L,LUA_ERRSYNTAX);
}
static void unexpectedEOZ (lua_State* L, ZIO* Z)
#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
#define LoadByte(S) (lu_byte)LoadChar(S)
#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
static void LoadBlock(LoadState* S, void* b, size_t size)
{
luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z));
if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted");
}
static int ezgetc (lua_State* L, ZIO* Z)
static int LoadChar(LoadState* S)
{
int c=zgetc(Z);
if (c==EOZ) unexpectedEOZ(L,Z);
return c;
char x;
LoadVar(S,x);
return x;
}
static void ezread (lua_State* L, ZIO* Z, void* b, int n)
{
int r=zread(Z,b,n);
if (r!=0) unexpectedEOZ(L,Z);
}
static void LoadBlock (lua_State* L, void* b, size_t size, ZIO* Z, int swap)
{
if (swap)
{
char *p=(char *) b+size-1;
int n=size;
while (n--) *p--=(char)ezgetc(L,Z);
}
else
ezread(L,Z,b,size);
}
static void LoadVector (lua_State* L, void* b, int m, size_t size, ZIO* Z, int swap)
{
if (swap)
{
char *q=(char *) b;
while (m--)
{
char *p=q+size-1;
int n=size;
while (n--) *p--=(char)ezgetc(L,Z);
q+=size;
}
}
else
ezread(L,Z,b,m*size);
}
static int LoadInt (lua_State* L, ZIO* Z, int swap)
static int LoadInt(LoadState* S)
{
int x;
LoadBlock(L,&x,sizeof(x),Z,swap);
LoadVar(S,x);
return x;
}
static size_t LoadSize (lua_State* L, ZIO* Z, int swap)
static lua_Number LoadNumber(LoadState* S)
{
size_t x;
LoadBlock(L,&x,sizeof(x),Z,swap);
lua_Number x;
LoadVar(S,x);
return x;
}
static Number LoadNumber (lua_State* L, ZIO* Z, int swap)
static TString* LoadString(LoadState* S)
{
Number x;
LoadBlock(L,&x,sizeof(x),Z,swap);
return x;
}
static TString* LoadString (lua_State* L, ZIO* Z, int swap)
{
size_t size=LoadSize(L,Z,swap);
size_t size;
LoadVar(S,size);
if (size==0)
return NULL;
else
{
char* s=luaO_openspace(L,size);
LoadBlock(L,s,size,Z,0);
return luaS_newlstr(L,s,size-1); /* remove trailing '\0' */
char* s=luaZ_openspace(S->L,S->b,size);
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
}
}
static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
static void LoadCode(LoadState* S, Proto* f)
{
int size=LoadInt(L,Z,swap);
tf->code=luaM_newvector(L,size,Instruction);
LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap);
if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
luaF_protook(L,tf,size);
int n=LoadInt(S);
f->code=luaM_newvector(S->L,n,Instruction);
f->sizecode=n;
LoadVector(S,f->code,n,sizeof(Instruction));
}
static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
static Proto* LoadFunction(LoadState* S);
static void LoadConstants(LoadState* S, Proto* f)
{
int i,n;
tf->nlocvars=n=LoadInt(L,Z,swap);
tf->locvars=luaM_newvector(L,n,LocVar);
n=LoadInt(S);
f->k=luaM_newvector(S->L,n,TValue);
f->sizek=n;
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
for (i=0; i<n; i++)
{
tf->locvars[i].varname=LoadString(L,Z,swap);
tf->locvars[i].startpc=LoadInt(L,Z,swap);
tf->locvars[i].endpc=LoadInt(L,Z,swap);
TValue* o=&f->k[i];
int t=LoadChar(S);
switch (t)
{
case LUA_TNIL:
setnilvalue(o);
break;
case LUA_TBOOLEAN:
setbvalue(o,LoadChar(S));
break;
case LUA_TNUMBER:
setnvalue(o,LoadNumber(S));
break;
case LUA_TSTRING:
setsvalue2n(S->L,o,LoadString(S));
break;
}
}
n=LoadInt(S);
f->p=luaM_newvector(S->L,n,Proto*);
f->sizep=n;
for (i=0; i<n; i++) f->p[i]=NULL;
for (i=0; i<n; i++) f->p[i]=LoadFunction(S);
}
static void LoadUpvalues(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
f->sizeupvalues=n;
for (i=0; i<n; i++) f->upvalues[i].name=NULL;
for (i=0; i<n; i++)
{
f->upvalues[i].instack=LoadChar(S);
f->upvalues[i].idx=LoadChar(S);
}
}
static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
{
int n;
tf->nlineinfo=n=LoadInt(L,Z,swap);
tf->lineinfo=luaM_newvector(L,n,int);
LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap);
}
static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);
static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
static void LoadDebug(LoadState* S, Proto* f)
{
int i,n;
tf->nkstr=n=LoadInt(L,Z,swap);
tf->kstr=luaM_newvector(L,n,TString*);
f->source=LoadString(S);
n=LoadInt(S);
f->lineinfo=luaM_newvector(S->L,n,int);
f->sizelineinfo=n;
LoadVector(S,f->lineinfo,n,sizeof(int));
n=LoadInt(S);
f->locvars=luaM_newvector(S->L,n,LocVar);
f->sizelocvars=n;
for (i=0; i<n; i++) f->locvars[i].varname=NULL;
for (i=0; i<n; i++)
tf->kstr[i]=LoadString(L,Z,swap);
tf->nknum=n=LoadInt(L,Z,swap);
tf->knum=luaM_newvector(L,n,Number);
LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap);
tf->nkproto=n=LoadInt(L,Z,swap);
tf->kproto=luaM_newvector(L,n,Proto*);
for (i=0; i<n; i++)
tf->kproto[i]=LoadFunction(L,Z,swap);
{
f->locvars[i].varname=LoadString(S);
f->locvars[i].startpc=LoadInt(S);
f->locvars[i].endpc=LoadInt(S);
}
n=LoadInt(S);
for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
}
static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap)
static Proto* LoadFunction(LoadState* S)
{
Proto* tf=luaF_newproto(L);
tf->source=LoadString(L,Z,swap);
tf->lineDefined=LoadInt(L,Z,swap);
tf->numparams=LoadInt(L,Z,swap);
tf->is_vararg=LoadByte(L,Z);
tf->maxstacksize=LoadInt(L,Z,swap);
LoadLocals(L,tf,Z,swap);
LoadLines(L,tf,Z,swap);
LoadConstants(L,tf,Z,swap);
LoadCode(L,tf,Z,swap);
return tf;
Proto* f=luaF_newproto(S->L);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->linedefined=LoadInt(S);
f->lastlinedefined=LoadInt(S);
f->numparams=LoadByte(S);
f->is_vararg=LoadByte(S);
f->maxstacksize=LoadByte(S);
LoadCode(S,f);
LoadConstants(S,f);
LoadUpvalues(S,f);
LoadDebug(S,f);
S->L->top--;
return f;
}
static void LoadSignature (lua_State* L, ZIO* Z)
static void LoadHeader(LoadState* S)
{
const char* s=SIGNATURE;
while (*s!=0 && ezgetc(L,Z)==*s)
++s;
if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z));
}
static void TestSize (lua_State* L, int s, const char* what, ZIO* Z)
{
int r=ezgetc(L,Z);
if (r!=s)
luaO_verror(L,"virtual machine mismatch in `%.99s':\n"
" %.20s is %d but read %d",ZNAME(Z),what,s,r);
}
#define TESTSIZE(s) TestSize(L,s,#s,Z)
#define V(v) v/16,v%16
static int LoadHeader (lua_State* L, ZIO* Z)
{
int version,swap;
Number f=0,tf=TEST_NUMBER;
LoadSignature(L,Z);
version=ezgetc(L,Z);
if (version>VERSION)
luaO_verror(L,"`%.99s' too new:\n"
" read version %d.%d; expected at most %d.%d",
ZNAME(Z),V(version),V(VERSION));
if (version<VERSION0) /* check last major change */
luaO_verror(L,"`%.99s' too old:\n"
" read version %d.%d; expected at least %d.%d",
ZNAME(Z),V(version),V(VERSION));
swap=(luaU_endianess()!=ezgetc(L,Z)); /* need to swap bytes? */
TESTSIZE(sizeof(int));
TESTSIZE(sizeof(size_t));
TESTSIZE(sizeof(Instruction));
TESTSIZE(SIZE_INSTRUCTION);
TESTSIZE(SIZE_OP);
TESTSIZE(SIZE_B);
TESTSIZE(sizeof(Number));
f=LoadNumber(L,Z,swap);
if ((long)f!=(long)tf) /* disregard errors in last bit of fraction */
luaO_verror(L,"unknown number format in `%.99s':\n"
" read " NUMBER_FMT "; expected " NUMBER_FMT, ZNAME(Z),f,tf);
return swap;
}
static Proto* LoadChunk (lua_State* L, ZIO* Z)
{
return LoadFunction(L,Z,LoadHeader(L,Z));
char h[LUAC_HEADERSIZE];
char s[LUAC_HEADERSIZE];
luaU_header(h);
LoadBlock(S,s,LUAC_HEADERSIZE);
if (memcmp(h,s,LUAC_HEADERSIZE)!=0) error(S,"incompatible");
}
/*
** load one chunk from a file or buffer
** return main if ok and NULL at EOF
** load precompiled chunk
*/
Proto* luaU_undump (lua_State* L, ZIO* Z)
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
{
Proto* tf=NULL;
int c=zgetc(Z);
if (c==ID_CHUNK)
tf=LoadChunk(L,Z);
c=zgetc(Z);
if (c!=EOZ)
luaO_verror(L,"`%.99s' apparently contains more than one chunk",ZNAME(Z));
return tf;
LoadState S;
if (*name=='@' || *name=='=')
S.name=name+1;
else if (*name==LUA_SIGNATURE[0])
S.name="binary string";
else
S.name=name;
S.L=L;
S.Z=Z;
S.b=buff;
LoadHeader(&S);
return LoadFunction(&S);
}
/*
** find byte order
* make header
* if you make any changes in the header or in LUA_SIGNATURE,
* be sure to update LUAC_HEADERSIZE accordingly in lundump.h.
*/
int luaU_endianess (void)
void luaU_header (char* h)
{
int x=1;
return *(char*)&x;
memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
h+=sizeof(LUA_SIGNATURE)-1;
*h++=(char)LUAC_VERSION;
*h++=(char)LUAC_FORMAT;
*h++=(char)*(char*)&x; /* endianness */
*h++=(char)sizeof(int);
*h++=(char)sizeof(size_t);
*h++=(char)sizeof(Instruction);
*h++=(char)sizeof(lua_Number);
*h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
}

View File

@@ -1,6 +1,6 @@
/*
** $Id: lundump.h,v 1.21 2000/10/31 16:57:23 lhf Exp $
** load pre-compiled Lua chunks
** $Id: lundump.h,v 1.39 2005/11/01 17:04:55 lhf Exp lhf $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -10,26 +10,27 @@
#include "lobject.h"
#include "lzio.h"
/* load one chunk */
Proto* luaU_undump (lua_State* L, ZIO* Z);
/* load one chunk; from lundump.c */
LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
/* find byte order */
int luaU_endianess (void);
/* make header; from lundump.c */
LUAI_FUNC void luaU_header (char* h);
/* definitions for headers of binary files */
#define VERSION 0x40 /* last format change was in 4.0 */
#define VERSION0 0x40 /* last major change was in 4.0 */
#define ID_CHUNK 27 /* binary files start with ESC... */
#define SIGNATURE "Lua" /* ...followed by this signature */
/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
/* formats for error messages */
#define SOURCE_FMT "<%d:%.99s>"
#define SOURCE tf->lineDefined,tf->source->str
#define IN_FMT " in %p " SOURCE_FMT
#define IN tf,SOURCE
#ifdef luac_c
/* print one chunk; from print.c */
LUAI_FUNC void luaU_print (const Proto* f, int full);
#endif
/* a multiple of PI for testing native format */
/* multiplying by 1E8 gives non-trivial integer values */
#define TEST_NUMBER 3.14159265358979323846E8
/* for header of binary files -- this is Lua 5.1 */
#define LUAC_VERSION 0x51
/* for header of binary files -- this is the official format */
#define LUAC_FORMAT 0
/* size of header of binary files */
#define LUAC_HEADERSIZE 12
#endif

1310
lvm.c

File diff suppressed because it is too large Load Diff

38
lvm.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.h,v 1.26 2000/09/05 19:33:32 roberto Exp roberto $
** $Id: lvm.h,v 2.13 2009/11/19 19:04:58 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -13,20 +13,30 @@
#include "ltm.h"
#define tonumber(o) ((ttype(o) != LUA_TNUMBER) && (luaV_tonumber(o) != 0))
#define tostring(L,o) ((ttype(o) != LUA_TSTRING) && (luaV_tostring(L, o) != 0))
#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
#define equalobj(L,o1,o2) \
(ttype(o1) == ttype(o2) && luaV_equalval_(L, o1, o2))
int luaV_tonumber (TObject *obj);
int luaV_tostring (lua_State *L, TObject *obj);
const TObject *luaV_gettable (lua_State *L, StkId t);
void luaV_settable (lua_State *L, StkId t, StkId key);
const TObject *luaV_getglobal (lua_State *L, TString *s);
void luaV_setglobal (lua_State *L, TString *s);
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
void luaV_strconc (lua_State *L, int total, StkId top);
/* not to called directly */
LUAI_FUNC int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_finishOp (lua_State *L);
LUAI_FUNC void luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);
LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
const TValue *rc, TMS op);
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
#endif

96
lzio.c
View File

@@ -1,78 +1,65 @@
/*
** $Id: lzio.c,v 1.12 2000/05/24 13:54:49 roberto Exp roberto $
** $Id: lzio.c,v 1.30 2005/05/17 19:49:15 roberto Exp roberto $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <string.h>
#define lzio_c
#define LUA_CORE
#include "lua.h"
#include "llimits.h"
#include "lmem.h"
#include "lstate.h"
#include "lzio.h"
/* ----------------------------------------------------- memory buffers --- */
static int zmfilbuf (ZIO* z) {
(void)z; /* to avoid warnings */
return EOZ;
int luaZ_fill (ZIO *z) {
size_t size;
lua_State *L = z->L;
const char *buff;
lua_unlock(L);
buff = z->reader(L, z->data, &size);
lua_lock(L);
if (buff == NULL || size == 0) return EOZ;
z->n = size - 1;
z->p = buff;
return char2int(*(z->p++));
}
ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name) {
if (b==NULL) return NULL;
z->n = size;
z->p = (const unsigned char *)b;
z->filbuf = zmfilbuf;
z->u = NULL;
z->name = name;
return z;
}
/* ------------------------------------------------------------ strings --- */
ZIO* zsopen (ZIO* z, const char* s, const char *name) {
if (s==NULL) return NULL;
return zmopen(z, s, strlen(s), name);
}
/* -------------------------------------------------------------- FILEs --- */
static int zffilbuf (ZIO* z) {
size_t n;
if (feof((FILE *)z->u)) return EOZ;
n = fread(z->buffer, 1, ZBSIZE, (FILE *)z->u);
if (n==0) return EOZ;
z->n = n-1;
z->p = z->buffer;
return *(z->p++);
int luaZ_lookahead (ZIO *z) {
if (z->n == 0) {
if (luaZ_fill(z) == EOZ)
return EOZ;
else {
z->n++; /* luaZ_fill removed first byte; put back it */
z->p--;
}
}
return char2int(*z->p);
}
ZIO* zFopen (ZIO* z, FILE* f, const char *name) {
if (f==NULL) return NULL;
void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
z->L = L;
z->reader = reader;
z->data = data;
z->n = 0;
z->p = z->buffer;
z->filbuf = zffilbuf;
z->u = f;
z->name = name;
return z;
z->p = NULL;
}
/* --------------------------------------------------------------- read --- */
size_t zread (ZIO *z, void *b, size_t n) {
size_t luaZ_read (ZIO *z, void *b, size_t n) {
while (n) {
size_t m;
if (z->n == 0) {
if (z->filbuf(z) == EOZ)
return n; /* return number of missing bytes */
zungetc(z); /* put result from `filbuf' in the buffer */
}
if (luaZ_lookahead(z) == EOZ)
return n; /* return number of missing bytes */
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
z->n -= m;
@@ -82,3 +69,14 @@ size_t zread (ZIO *z, void *b, size_t n) {
}
return 0;
}
/* ------------------------------------------------------------------------ */
char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
if (n > buff->buffsize) {
if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
luaZ_resizebuffer(L, buff, n);
}
return buff->buffer;
}

71
lzio.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lzio.h,v 1.6 2000/05/24 13:54:49 roberto Exp roberto $
** $Id: lzio.h,v 1.21 2005/05/17 19:49:15 roberto Exp roberto $
** Buffered streams
** See Copyright Notice in lua.h
*/
@@ -8,46 +8,63 @@
#ifndef lzio_h
#define lzio_h
#include <stdio.h>
#include "lua.h"
#include "lmem.h"
/* For Lua only */
#define zFopen luaZ_Fopen
#define zsopen luaZ_sopen
#define zmopen luaZ_mopen
#define zread luaZ_read
#define EOZ (-1) /* end of stream */
typedef struct zio ZIO;
typedef struct Zio ZIO;
ZIO* zFopen (ZIO* z, FILE* f, const char *name); /* open FILEs */
ZIO* zsopen (ZIO* z, const char* s, const char *name); /* string */
ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name); /* memory */
#define char2int(c) cast(int, cast(unsigned char, (c)))
size_t zread (ZIO* z, void* b, size_t n); /* read next n bytes */
#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
#define zgetc(z) (((z)->n--)>0 ? ((int)*(z)->p++): (z)->filbuf(z))
#define zungetc(z) (++(z)->n,--(z)->p)
#define zname(z) ((z)->name)
#define zungetc(z) ((z)->n++, (z)->p--)
typedef struct Mbuffer {
char *buffer;
size_t n;
size_t buffsize;
} Mbuffer;
#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
#define luaZ_buffer(buff) ((buff)->buffer)
#define luaZ_sizebuffer(buff) ((buff)->buffsize)
#define luaZ_bufflen(buff) ((buff)->n)
#define luaZ_resetbuffer(buff) ((buff)->n = 0)
#define luaZ_resizebuffer(L, buff, size) \
(luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
(buff)->buffsize = size)
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
void *data);
LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
LUAI_FUNC int luaZ_lookahead (ZIO *z);
/* --------- Private Part ------------------ */
#ifndef ZBSIZE
#define ZBSIZE 256 /* buffer size */
#endif
struct zio {
size_t n; /* bytes still unread */
const unsigned char* p; /* current position in buffer */
int (*filbuf)(ZIO* z);
void* u; /* additional data */
const char *name;
unsigned char buffer[ZBSIZE]; /* buffer */
struct Zio {
size_t n; /* bytes still unread */
const char *p; /* current position in buffer */
lua_Reader reader;
void* data; /* additional data */
lua_State *L; /* Lua state (for reader) */
};
LUAI_FUNC int luaZ_fill (ZIO *z);
#endif

293
makefile
View File

@@ -1,160 +1,181 @@
#
## $Id: makefile,v 1.29 2000/10/30 17:50:00 roberto Exp roberto $
## Makefile
## See Copyright Notice in lua.h
#
# makefile for building Lua
# see INSTALL for installation instructions
# see ../Makefile and luaconf.h for further customization
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
#CONFIGURATION
# define (undefine) POPEN if your system (does not) support piped I/O
#
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
#
# define (undefine) OLD_ANSI if your system does NOT have some new ANSI
# facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
# so, add "-DOLD_ANSI" on SunOS
#
# define LUA_NUM_TYPE if you need numbers to be different from double
# (for instance, -DLUA_NUM_TYPE=float)
# you may need to adapat the code, too.
#
# define LUA_COMPAT_READPATTERN if you need read patterns
# (only for compatibility with previous versions)
# define LUA_COMPAT_ARGRET for compatibility in the way function results
# are passed as arguments
# define LUA_DEPRECATEDFUNCS to include obsolete functions
CONFIG = -DPOPEN -D_POSIX_SOURCE
#CONFIG = -DOLD_ANSI -DLUA_DEBUG -DLUA_COMPAT_READPATTERN -DLUA_COMPAT_ARGRET
# -DLUA_DEPRECATEDFUNCS
# Compilation parameters
CC = gcc
CWARNS = -Wall -W -pedantic \
CWARNSC=-pedantic -Wextra \
-Waggregate-return \
-Wcast-align \
-Wmissing-prototypes \
-Wnested-externs \
-Wdisabled-optimization \
-Wpointer-arith \
-Wshadow \
-Wwrite-strings
# -Wcast-qual
# -Wtraditional
-Wsign-compare \
-Wundef \
-Wwrite-strings \
-Wredundant-decls \
-Wdisabled-optimization \
-Wstrict-aliasing \
# the next warnings generate to much noise, so they are disabled
# -Wlogical-op \
# -Wformat=2 \
# -Wstrict-overflow=5 \
# -Wcast-qual \
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
# The next warnings are not valid for C++
CWARNS= $(CWARNSC) \
-Wdeclaration-after-statement \
-Wmissing-prototypes \
-Wnested-externs \
-Wstrict-prototypes \
-Wc++-compat \
-Wold-style-definition \
# To make early versions
CO_OPTIONS =
# -DEXTERNMEMCHECK -DHARDSTACKTESTS -DHARDMEMTESTS -DTRACEMEM='"tempmem"'
# -g -DLUA_USER_H='"ltests.h"'
# -fomit-frame-pointer #-pg -malign-double
TESTS= -DLUA_USER_H='"ltests.h"' # -g -O0
LOCAL = $(TESTS) $(CWARNS)
AR = ar
ARFLAGS = rvl
# enable Linux goodies
MYCFLAGS= $(LOCAL) -DLUA_USE_LINUX -DLUA_COMPAT_ALL -g
MYLDFLAGS= -Wl,-E -g
MYLIBS= -ldl -lreadline -lhistory -lncurses
# Aplication modules
LUAOBJS = \
lstate.o \
lapi.o \
lmem.o \
lstring.o \
ltable.o \
ltm.o \
lvm.o \
ldo.o \
lobject.o \
lfunc.o \
lgc.o \
lcode.o \
lparser.o \
llex.o \
lundump.o \
lzio.o \
ldebug.o \
ltests.o
LIBOBJS = \
lauxlib.o \
lbaselib.o \
liolib.o \
lmathlib.o \
lstrlib.o \
ldblib.o
CC= gcc
CFLAGS= -Wall -O2 $(MYCFLAGS)
# CC= ~lhf/sunstudio12/bin/cc
# CFLAGS= -xO5 -v -Xc -native -xstrconst
AR= ar rcu
RANLIB= ranlib
RM= rm -f
lua : lua.o liblua.a liblualib.a
$(CC) $(CFLAGS) -o $@ lua.o -L. -llua -llualib -lm
liblua.a : $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
liblualib.a : $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib $@
liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS)
# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
clear :
rcsclean
rm -f *.o *.a
LIBS = -lm
CORE_T= liblua.a
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
ltm.o lundump.o lvm.o lzio.o ltests.o
AUX_O= lauxlib.o
LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \
lbitlib.o loadlib.o lcorolib.o linit.o
%.h : RCS/%.h,v
co $(CO_OPTIONS) $@
LUA_T= lua
LUA_O= lua.o
%.c : RCS/%.c,v
co $(CO_OPTIONS) $@
# LUAC_T= luac
# LUAC_O= luac.o print.o
ALL_T= $(CORE_T) $(LUA_T) $(LUAC_T)
ALL_O= $(CORE_O) $(LUA_O) $(LUAC_O) $(AUX_O) $(LIB_O)
ALL_A= $(CORE_T)
lapi.o: lapi.c lua.h lapi.h lobject.h llimits.h ldo.h lstate.h \
luadebug.h lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h lvm.h
lauxlib.o: lauxlib.c lua.h lauxlib.h luadebug.h
lbaselib.o: lbaselib.c lua.h lauxlib.h luadebug.h lualib.h
lcode.o: lcode.c /usr/include/stdlib.h lua.h lcode.h llex.h lobject.h \
llimits.h lzio.h lopcodes.h lparser.h ldo.h lstate.h luadebug.h \
lmem.h
ldblib.o: ldblib.c lua.h lauxlib.h luadebug.h lualib.h
ldebug.o: ldebug.c lua.h lapi.h lobject.h llimits.h lcode.h llex.h \
lzio.h lopcodes.h lparser.h ldebug.h lstate.h luadebug.h ldo.h \
lfunc.h lstring.h ltable.h ltm.h
ldo.o: ldo.c lua.h ldebug.h lstate.h lobject.h llimits.h luadebug.h \
ldo.h lgc.h lmem.h lparser.h lzio.h lstring.h ltable.h ltm.h \
lundump.h lvm.h
lfunc.o: lfunc.c lua.h lfunc.h lobject.h llimits.h lmem.h lstate.h \
luadebug.h
lgc.o: lgc.c lua.h ldo.h lobject.h llimits.h lstate.h luadebug.h \
lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h
liolib.o: liolib.c lua.h lauxlib.h luadebug.h lualib.h
llex.o: llex.c lua.h llex.h lobject.h llimits.h lzio.h lmem.h \
lparser.h lstate.h luadebug.h lstring.h ltable.h
lmathlib.o: lmathlib.c lua.h lauxlib.h lualib.h
lmem.o: lmem.c lua.h ldo.h lobject.h llimits.h lstate.h luadebug.h \
lmem.h
lobject.o: lobject.c lua.h lmem.h llimits.h lobject.h lstate.h \
luadebug.h
lparser.o: lparser.c lua.h lcode.h llex.h lobject.h llimits.h lzio.h \
lopcodes.h lparser.h lfunc.h lmem.h lstate.h luadebug.h lstring.h
lstate.o: lstate.c lua.h ldo.h lobject.h llimits.h lstate.h luadebug.h \
lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h
lstring.o: lstring.c lua.h lmem.h llimits.h lobject.h lstate.h \
luadebug.h lstring.h
lstrlib.o: lstrlib.c lua.h lauxlib.h lualib.h
ltable.o: ltable.c lua.h lmem.h llimits.h lobject.h lstate.h \
luadebug.h lstring.h ltable.h
ltests.o: ltests.c lua.h lapi.h lobject.h llimits.h lauxlib.h lcode.h \
llex.h lzio.h lopcodes.h lparser.h ldebug.h lstate.h luadebug.h ldo.h \
lfunc.h lmem.h lstring.h ltable.h lualib.h
ltm.o: ltm.c lua.h ldo.h lobject.h llimits.h lstate.h luadebug.h \
lmem.h ltm.h
lua.o: lua.c lua.h luadebug.h lualib.h
lundump.o: lundump.c lfunc.h lobject.h llimits.h lua.h lmem.h \
lopcodes.h lstring.h lstate.h luadebug.h lundump.h lzio.h
lvm.o: lvm.c lua.h lapi.h lobject.h llimits.h ldebug.h lstate.h \
luadebug.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h ltm.h \
all: $(ALL_T)
o: $(ALL_O)
a: $(ALL_A)
$(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O)
$(AR) $@ $?
$(RANLIB) $@
$(LUA_T): $(LUA_O) $(CORE_T)
$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(CORE_T) $(LIBS) $(MYLIBS) $(DL)
$(LUAC_T): $(LUAC_O) $(CORE_T)
$(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(CORE_T) $(LIBS) $(MYLIBS)
clean:
rcsclean -u
$(RM) $(ALL_T) $(ALL_O)
depend:
@$(CC) $(CFLAGS) -MM *.c
echo:
@echo "CC = $(CC)"
@echo "CFLAGS = $(CFLAGS)"
@echo "AR = $(AR)"
@echo "RANLIB = $(RANLIB)"
@echo "RM = $(RM)"
@echo "MYCFLAGS = $(MYCFLAGS)"
@echo "MYLDFLAGS = $(MYLDFLAGS)"
@echo "MYLIBS = $(MYLIBS)"
@echo "DL = $(DL)"
$(ALL_O): makefile
# DO NOT DELETE
lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \
lvm.h
lzio.o: lzio.c lua.h lzio.h
lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h
lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h
lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
lstring.h ltable.h
lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h
lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h
ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \
lfunc.h lstring.h lgc.h ltable.h lvm.h
ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \
lstring.h ltable.h lundump.h lvm.h
ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
lzio.h lmem.h lundump.h
lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \
lstate.h ltm.h lzio.h lmem.h
lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \
lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h
loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h
lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \
lstring.h lgc.h ltable.h
lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \
ltable.h
lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
ltm.h lzio.h lstring.h lgc.h
lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h
ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
ltests.o: ltests.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
ltm.h lzio.h lmem.h lauxlib.h lcode.h llex.h lopcodes.h lparser.h \
lctype.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lualib.h
ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
lmem.h lstring.h lgc.h ltable.h
lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
lzio.h
# (end of Makefile)

3981
manual.tex

File diff suppressed because it is too large Load Diff