2006-03-20 20:49:30 +08:00
|
|
|
|
--[=[
|
1997-12-02 20:46:15 +08:00
|
|
|
|
** lua.stx / llex.c
|
|
|
|
|
Tue Dec 2 10:45:48 EDT 1997
|
|
|
|
|
>> BUG: "lastline" was not reset on function entry, so debug information
|
|
|
|
|
>> started only in the 2nd line of a function.
|
1998-01-20 03:49:22 +08:00
|
|
|
|
|
|
|
|
|
|
1999-04-30 22:12:05 +08:00
|
|
|
|
|
2000-04-26 00:45:39 +08:00
|
|
|
|
=================================================================
|
1998-01-20 03:49:22 +08:00
|
|
|
|
--- Version 3.1 alpha
|
|
|
|
|
|
|
|
|
|
** lua.c
|
|
|
|
|
Thu Jan 15 14:34:58 EDT 1998
|
|
|
|
|
>> must include "stdlib.h" (for "exit()").
|
|
|
|
|
|
|
|
|
|
** lbuiltin.c / lobject.h
|
|
|
|
|
Thu Jan 15 14:34:58 EDT 1998
|
|
|
|
|
>> MAX_WORD may be bigger than MAX_INT
|
1999-04-30 22:12:05 +08:00
|
|
|
|
(by lhf)
|
1998-01-20 04:18:02 +08:00
|
|
|
|
|
|
|
|
|
** llex.c
|
|
|
|
|
Mon Jan 19 18:17:18 EDT 1998
|
|
|
|
|
>> wrong line number (+1) in error report when file starts with "#..."
|
1998-01-28 03:11:36 +08:00
|
|
|
|
|
|
|
|
|
** lstrlib.c
|
|
|
|
|
Tue Jan 27 15:27:49 EDT 1998
|
1998-01-29 00:50:33 +08:00
|
|
|
|
>> formats like "%020d" were considered too big (3 digits); moreover,
|
1998-01-28 03:11:36 +08:00
|
|
|
|
>> some sistems limit printf to at most 500 chars, so we can limit sizes
|
|
|
|
|
>> to 2 digits (99).
|
1998-01-28 03:13:45 +08:00
|
|
|
|
|
|
|
|
|
** lapi.c
|
|
|
|
|
Tue Jan 27 17:12:36 EDT 1998
|
|
|
|
|
>> "lua_getstring" may create a new string, so should check GC
|
|
|
|
|
|
1998-01-29 00:50:33 +08:00
|
|
|
|
** lstring.c / ltable.c
|
|
|
|
|
Wed Jan 28 14:48:12 EDT 1998
|
1998-09-08 02:59:59 +08:00
|
|
|
|
>> tables can become full of "empty" slots, and keep growing without limits.
|
1998-01-29 00:50:33 +08:00
|
|
|
|
|
1998-03-10 02:28:08 +08:00
|
|
|
|
** lstrlib.c
|
|
|
|
|
Mon Mar 9 15:26:09 EST 1998
|
|
|
|
|
>> gsub('a', '(b?)%1*' ...) loops (because the capture is empty).
|
|
|
|
|
|
1998-05-19 06:21:55 +08:00
|
|
|
|
** lstrlib.c
|
|
|
|
|
Mon May 18 19:20:00 EST 1998
|
|
|
|
|
>> arguments for "format" 'x', 'X', 'o' and 'u' must be unsigned int.
|
|
|
|
|
|
1998-09-08 02:59:59 +08:00
|
|
|
|
|
1999-04-30 22:12:05 +08:00
|
|
|
|
|
2000-04-26 00:45:39 +08:00
|
|
|
|
=================================================================
|
1998-09-08 02:59:59 +08:00
|
|
|
|
--- Version 3.1
|
|
|
|
|
|
|
|
|
|
** liolib.c / lauxlib.c
|
|
|
|
|
Mon Sep 7 15:57:02 EST 1998
|
|
|
|
|
>> function "luaL_argerror" prints wrong argument number (from a user's point
|
|
|
|
|
of view) when functions have upvalues.
|
1998-11-11 03:38:12 +08:00
|
|
|
|
|
|
|
|
|
** lstrlib.c
|
|
|
|
|
Tue Nov 10 17:29:36 EDT 1998
|
|
|
|
|
>> gsub/strfind do not check whether captures are properly finished.
|
1999-04-30 22:12:05 +08:00
|
|
|
|
(by roberto/tomas)
|
1998-12-18 21:26:43 +08:00
|
|
|
|
|
|
|
|
|
** lbuiltin.c
|
|
|
|
|
Fri Dec 18 11:22:55 EDT 1998
|
|
|
|
|
>> "tonumber" goes crazy with negative numbers in other bases (not 10),
|
|
|
|
|
because "strtol" returns long, not unsigned long.
|
1999-04-30 22:12:05 +08:00
|
|
|
|
(by Visual C++)
|
1998-12-18 21:26:43 +08:00
|
|
|
|
|
1999-01-04 20:53:24 +08:00
|
|
|
|
** lstrlib.c
|
|
|
|
|
Mon Jan 4 10:41:40 EDT 1999
|
|
|
|
|
>> "format" does not check size of format item (such as "%00000...00000d").
|
1999-02-04 00:42:42 +08:00
|
|
|
|
|
|
|
|
|
** lapi.c
|
|
|
|
|
Wed Feb 3 14:40:21 EDT 1999
|
|
|
|
|
>> getlocal cannot return the local itself, since lua_isstring and
|
|
|
|
|
lua_isnumber can modify it.
|
|
|
|
|
|
1999-02-05 03:29:51 +08:00
|
|
|
|
** lstrlib.c
|
|
|
|
|
Thu Feb 4 17:08:50 EDT 1999
|
|
|
|
|
>> format "%s" may break limit of "sprintf" on some machines.
|
1999-04-30 22:12:05 +08:00
|
|
|
|
(by Marcelo Sales)
|
1999-03-04 22:50:26 +08:00
|
|
|
|
|
|
|
|
|
** lzio.c
|
|
|
|
|
Thu Mar 4 11:49:37 EST 1999
|
|
|
|
|
>> file stream cannot call fread after EOF.
|
1999-04-30 22:12:05 +08:00
|
|
|
|
(by lhf)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-04-26 00:45:39 +08:00
|
|
|
|
=================================================================
|
1999-04-30 22:12:05 +08:00
|
|
|
|
--- Version 3.2 (beta)
|
|
|
|
|
|
|
|
|
|
** lstrlib.c
|
|
|
|
|
Fri Apr 30 11:10:20 EST 1999
|
|
|
|
|
>> '$' at end of pattern was matching regular '$', too.
|
1999-06-16 21:35:01 +08:00
|
|
|
|
(by anna; since 2.5)
|
1999-04-30 22:12:05 +08:00
|
|
|
|
|
1999-05-25 01:53:49 +08:00
|
|
|
|
** lbuiltin.c
|
|
|
|
|
Fri May 21 17:15:11 EST 1999
|
|
|
|
|
>> foreach, foreachi, foreachvar points to function in stack when stack
|
|
|
|
|
can be reallocated.
|
1999-06-16 21:35:01 +08:00
|
|
|
|
(by tomas; since 3.2 beta)
|
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Wed Jun 16 10:32:46 EST 1999
|
|
|
|
|
>> cannot assign to unlimited variables, because it causes overflow in
|
|
|
|
|
the number of returns of a function.
|
|
|
|
|
(since 3.1)
|
1999-05-25 01:53:49 +08:00
|
|
|
|
|
1999-08-18 22:40:51 +08:00
|
|
|
|
|
|
|
|
|
|
2000-04-26 00:45:39 +08:00
|
|
|
|
=================================================================
|
1999-08-18 22:40:51 +08:00
|
|
|
|
--- Version 3.2
|
|
|
|
|
|
|
|
|
|
** lmathlib.c
|
|
|
|
|
Wed Aug 18 11:28:38 EST 1999
|
|
|
|
|
>> random(0) and random(x,0) are wrong (0 is read as no argument!).
|
|
|
|
|
(by Dave Bollinger; since 3.1)
|
1999-09-02 21:13:22 +08:00
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Thu Sep 2 10:07:20 EST 1999
|
|
|
|
|
>> in the (old) expression << ls->fs->f->consts[checkname(ls)] >>, checkname
|
|
|
|
|
could realloc f->consts.
|
|
|
|
|
(by Supratik Champati; since 3.2 beta)
|
|
|
|
|
|
1999-09-09 04:45:18 +08:00
|
|
|
|
** lobject.c / lbuiltin.c
|
|
|
|
|
Wed Sep 8 17:41:54 EST 1999
|
|
|
|
|
>> tonumber'e1' and tonumber(' ', x), for x!=10, gave 0 instead of nil.
|
|
|
|
|
(since 3.1)
|
1999-11-12 00:45:04 +08:00
|
|
|
|
|
|
|
|
|
** lstrlib.c
|
|
|
|
|
Thu Nov 11 14:36:30 EDT 1999
|
|
|
|
|
>> `strfind' does not handle \0 in plain search.
|
|
|
|
|
(by Jon Kleiser; since 3.1)
|
1999-12-30 02:07:10 +08:00
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Wed Dec 29 16:05:43 EDT 1999
|
|
|
|
|
>> return gives wrong line in debug information
|
|
|
|
|
(by lhf; since 3.2 [at least])
|
|
|
|
|
|
1999-12-31 02:40:57 +08:00
|
|
|
|
** ldo.c
|
|
|
|
|
Thu Dec 30 16:39:33 EDT 1999
|
|
|
|
|
>> cannot reopen stdin (for binary mode)
|
|
|
|
|
(by lhf & roberto; since 3.1)
|
2000-03-02 20:44:29 +08:00
|
|
|
|
|
|
|
|
|
** lapi.c
|
|
|
|
|
Thu Mar 2 09:41:53 EST 2000
|
|
|
|
|
>> lua_settable should check stack space (it could call a T.M.)
|
|
|
|
|
(by lhf & celes; since 3.2; it was already fixed by fixed stack)
|
|
|
|
|
|
2000-04-03 21:20:33 +08:00
|
|
|
|
** lparser.c
|
|
|
|
|
Mon Apr 3 09:59:06 EST 2000
|
|
|
|
|
>> '%' should be in expfollow
|
|
|
|
|
(by Edgar Toernig; since 3.1; it was already fixed)
|
|
|
|
|
|
|
|
|
|
** lbuiltin.c
|
|
|
|
|
Mon Apr 3 10:05:05 EST 2000
|
|
|
|
|
>> tostring() without arguments gives seg. fault.
|
|
|
|
|
(by Edgar Toernig; since 3.0)
|
|
|
|
|
|
2000-04-26 00:45:39 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=================================================================
|
|
|
|
|
--- Version 4.0 alpha
|
|
|
|
|
|
|
|
|
|
Tested with full test suites (as locked in Mon Apr 24 14:23:11 EST 2000)
|
|
|
|
|
in the following platforms:
|
|
|
|
|
* Linux - gcc, g++
|
|
|
|
|
* AIX - gcc
|
|
|
|
|
* Solaris - gcc, cc
|
|
|
|
|
* IRIX - cc, cc-purify
|
|
|
|
|
* Windows - Visual C++ (.c e .cpp, warning level=4)
|
|
|
|
|
|
2000-05-03 02:32:22 +08:00
|
|
|
|
|
|
|
|
|
** lstrlib.c
|
|
|
|
|
Tue May 2 15:27:58 EST 2000
|
|
|
|
|
>> `strfind' gets wrong subject length when there is an offset
|
|
|
|
|
(by Jon Kleiser; since 4.0a)
|
2000-05-13 02:12:04 +08:00
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Fri May 12 15:11:12 EST 2000
|
|
|
|
|
>> first element in a list constructor is not adjusted to one value
|
2000-05-25 02:04:17 +08:00
|
|
|
|
>> (e.g. <20>a = {gsub('a','a','')}<7D>)
|
2000-05-13 02:12:04 +08:00
|
|
|
|
(by Tomas; since 4.0a)
|
2000-05-25 02:04:17 +08:00
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Wed May 24 14:50:16 EST 2000
|
|
|
|
|
>> record-constructor starting with an upvalue name gets an error
|
|
|
|
|
>> (e.g. <20>local a; function f() x = {a=1} end<6E>)
|
|
|
|
|
(by Edgar Toernig; since 3.1)
|
|
|
|
|
|
2000-08-30 03:00:57 +08:00
|
|
|
|
** lparser.c
|
|
|
|
|
Tue Aug 29 15:56:05 EST 2000
|
|
|
|
|
>> error message for `for' uses `while'
|
|
|
|
|
(since 4.0a; already corrected)
|
|
|
|
|
|
|
|
|
|
** lgc.c
|
|
|
|
|
Tue Aug 29 15:57:41 EST 2000
|
|
|
|
|
>> gc tag method for nil could call line hook
|
|
|
|
|
(by ry; since ?)
|
|
|
|
|
|
2000-09-23 02:14:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=================================================================
|
|
|
|
|
--- Version 4.0 Beta
|
|
|
|
|
|
|
|
|
|
** liolib.c
|
|
|
|
|
Fri Sep 22 15:12:37 EST 2000
|
|
|
|
|
>> `read("*w")' should return nil at EOF
|
|
|
|
|
(by roberto; since 4.0b)
|
|
|
|
|
|
2000-09-25 22:48:42 +08:00
|
|
|
|
** lvm.c
|
|
|
|
|
Mon Sep 25 11:47:48 EST 2000
|
|
|
|
|
>> lua_gettable does not get key from stack top
|
|
|
|
|
(by Philip Yi; since 4.0b)
|
|
|
|
|
|
2000-09-25 22:52:10 +08:00
|
|
|
|
** lgc.c
|
|
|
|
|
Mon Sep 25 11:50:48 EST 2000
|
2000-09-27 20:51:39 +08:00
|
|
|
|
>> GC may crash when checking locked C closures
|
2000-09-25 22:52:10 +08:00
|
|
|
|
(by Philip Yi; since 4.0b)
|
2000-09-27 20:51:39 +08:00
|
|
|
|
|
|
|
|
|
** lapi.c
|
|
|
|
|
Wed Sep 27 09:50:19 EST 2000
|
|
|
|
|
>> lua_tag should return LUA_NOTAG for non-valid indices
|
|
|
|
|
(by Paul Hankin; since 4.0b)
|
|
|
|
|
|
2000-09-28 01:41:58 +08:00
|
|
|
|
** llex.h / llex.c / lparser.c
|
|
|
|
|
Wed Sep 27 13:39:45 EST 2000
|
|
|
|
|
>> parser overwrites semantic information when looking ahead
|
|
|
|
|
>> (e.g. <20>a = {print'foo'}<7D>)
|
|
|
|
|
(by Edgar Toernig; since 4.0b, deriving from previous bug)
|
|
|
|
|
|
2000-10-26 20:53:55 +08:00
|
|
|
|
** liolib.c
|
|
|
|
|
Thu Oct 26 10:50:46 EDT 2000
|
|
|
|
|
>> in function `read_file', realloc() doesn't free the buffer if it can't
|
|
|
|
|
>> allocate new memory
|
|
|
|
|
(by Mauro Vezzosi; since 4.0b)
|
|
|
|
|
|
2000-11-29 19:57:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=================================================================
|
|
|
|
|
--- Version 4.0
|
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Wed Nov 29 09:51:44 EDT 2000
|
|
|
|
|
>> parser does not accept a `;' after a `return'
|
|
|
|
|
(by lhf; since 4.0b)
|
|
|
|
|
|
2000-12-23 01:32:28 +08:00
|
|
|
|
** liolib.c
|
|
|
|
|
Fri Dec 22 15:30:42 EDT 2000
|
|
|
|
|
>> when `read' fails it must return nil (and not no value)
|
|
|
|
|
(by cassino; since at least 3.1)
|
|
|
|
|
|
2001-02-01 21:56:49 +08:00
|
|
|
|
** lstring.c/lapi.c
|
|
|
|
|
Thu Feb 1 11:55:45 EDT 2001
|
|
|
|
|
>> lua_pushuserdata(L, NULL) is buggy
|
|
|
|
|
(by Edgar Toernig; since 4.0)
|
|
|
|
|
|
2001-02-03 00:23:20 +08:00
|
|
|
|
** ldo.c
|
|
|
|
|
Fri Feb 2 14:06:40 EDT 2001
|
|
|
|
|
>> <20>while 1 dostring[[print('hello\n')]] end<6E> never reclaims memory
|
|
|
|
|
(by Andrew Paton; since 4.0b)
|
2001-02-06 21:59:29 +08:00
|
|
|
|
|
|
|
|
|
** lbaselib.c
|
|
|
|
|
Tue Feb 6 11:57:13 EDT 2001
|
|
|
|
|
>> ESC (which starts precompiled code) in C is \33, not \27
|
|
|
|
|
(by Edgar Toernig and lhf; since 4.0b)
|
2001-07-11 04:02:22 +08:00
|
|
|
|
|
|
|
|
|
** lparser.c
|
|
|
|
|
Tue Jul 10 16:59:18 EST 2001
|
|
|
|
|
>> error message for `%a' gave wrong line number
|
|
|
|
|
(by Leonardo Constantino; since 4.0)
|
|
|
|
|
|
2001-12-22 01:30:31 +08:00
|
|
|
|
** lbaselib.c
|
|
|
|
|
Fri Dec 21 15:21:05 EDT 2001
|
|
|
|
|
>> seg. fault when rawget/rawset get extra arguments
|
|
|
|
|
(by Eric Mauger; since 4.0b)
|
|
|
|
|
|
2002-06-26 03:23:55 +08:00
|
|
|
|
** lvm.c
|
|
|
|
|
Wed Jun 19 13:28:20 EST 2002
|
|
|
|
|
>> line hook gets wrong `ar'
|
|
|
|
|
(by Daniel C. Sinclair; since 4.0.b)
|
2001-12-22 01:30:31 +08:00
|
|
|
|
|
2002-06-26 03:23:55 +08:00
|
|
|
|
** ldo.c
|
|
|
|
|
Wed Jun 19 13:31:49 EST 2002
|
|
|
|
|
>> `protectedparser' may run GC, and then collect `filename'
|
|
|
|
|
>> (in function `parse_file')
|
|
|
|
|
(by Alex Bilyk; since 4.0)
|
2001-12-22 01:30:31 +08:00
|
|
|
|
|
2002-08-31 03:08:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=================================================================
|
|
|
|
|
--- Version 5.0 alpha
|
|
|
|
|
|
|
|
|
|
** lgc.c
|
|
|
|
|
Fri Aug 30 13:49:14 EST 2002
|
|
|
|
|
>> GC metamethod stored in a weak metatable being collected together with
|
|
|
|
|
>> userdata may not be cleared properly
|
|
|
|
|
(by Roberto; since 5.0a)
|
|
|
|
|
|
2003-02-22 03:00:14 +08:00
|
|
|
|
** lapi.c
|
|
|
|
|
Thu Nov 21 11:00:00 EST 2002
|
|
|
|
|
>> ULONG_MAX>>10 may not fit into an int
|
|
|
|
|
(by Jeff Petkau; since 4.0)
|
|
|
|
|
|
2002-12-07 01:09:00 +08:00
|
|
|
|
** lparser.c
|
|
|
|
|
Fri Dec 6 17:06:40 UTC 2002
|
|
|
|
|
>> scope of generic for variables is not sound
|
|
|
|
|
(by Gavin Wraith; since 5.0a)
|
|
|
|
|
|
2002-12-20 17:55:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=================================================================
|
|
|
|
|
--- Version 5.0 beta
|
|
|
|
|
** lbaselib.c
|
|
|
|
|
Fri Dec 20 09:53:19 UTC 2002
|
|
|
|
|
>> `resume' was checking the wrong value for stack overflow
|
|
|
|
|
(by Maik Zimmermann; since 5.0b)
|
|
|
|
|
|
2003-01-23 19:31:38 +08:00
|
|
|
|
** ldo.c
|
|
|
|
|
Thu Jan 23 11:29:06 UTC 2003
|
|
|
|
|
>> error during garbage collection in luaD_protectedparser is not being
|
|
|
|
|
>> protected
|
|
|
|
|
(by Benoit Germain; since 5.0a)
|
|
|
|
|
|
2003-03-01 03:45:15 +08:00
|
|
|
|
** ldo.c (and others)
|
|
|
|
|
Fri Feb 28 14:20:33 EST 2003
|
|
|
|
|
>> GC metamethod calls could mess C/Lua stack syncronization
|
|
|
|
|
(by Roberto; since 5.0b)
|
|
|
|
|
|
2003-03-21 00:00:56 +08:00
|
|
|
|
** lzio.h/zlio.c
|
|
|
|
|
Thu Mar 20 11:40:12 EST 2003
|
|
|
|
|
>> zio mixes a 255 as first char in a buffer with EOZ
|
|
|
|
|
(by lhf; since 5.0a)
|
|
|
|
|
|
2003-07-30 03:27:46 +08:00
|
|
|
|
|
|
|
|
|
|
2006-03-20 20:49:30 +08:00
|
|
|
|
--]=]
|
2003-07-30 03:27:46 +08:00
|
|
|
|
-----------------------------------------------------------------
|
|
|
|
|
-- Lua 5.0 (final)
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[lua_closethread exists only in the manual]],
|
|
|
|
|
report = [[by Nguyen Binh, 28/04/2003]],
|
|
|
|
|
patch = [[no patch; the manual is wrong]],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[attempt to resume a running coroutine crashes Lua]],
|
|
|
|
|
example = [[
|
|
|
|
|
function co_func (current_co)
|
|
|
|
|
coroutine.resume(co)
|
|
|
|
|
end
|
|
|
|
|
co = coroutine.create(co_func)
|
|
|
|
|
coroutine.resume(co)
|
|
|
|
|
coroutine.resume(co) --> seg. fault
|
|
|
|
|
]],
|
|
|
|
|
report = [[by Alex Bilyk, 09/05/2003]],
|
2003-09-30 00:41:35 +08:00
|
|
|
|
patch = [[
|
|
|
|
|
* ldo.c:
|
|
|
|
|
325,326c325
|
|
|
|
|
< if (nargs >= L->top - L->base)
|
|
|
|
|
< luaG_runerror(L, "cannot resume dead coroutine");
|
|
|
|
|
---
|
|
|
|
|
> lua_assert(nargs < L->top - L->base);
|
|
|
|
|
329c328,329
|
|
|
|
|
< else if (ci->state & CI_YIELD) { /* inside a yield? */
|
|
|
|
|
---
|
|
|
|
|
> else { /* inside a yield */
|
|
|
|
|
> lua_assert(ci->state & CI_YIELD);
|
|
|
|
|
344,345d343
|
|
|
|
|
< else
|
|
|
|
|
< luaG_runerror(L, "cannot resume non-suspended coroutine");
|
|
|
|
|
351a350,358
|
|
|
|
|
> static int resume_error (lua_State *L, const char *msg) {
|
|
|
|
|
> L->top = L->ci->base;
|
|
|
|
|
> setsvalue2s(L->top, luaS_new(L, msg));
|
|
|
|
|
> incr_top(L);
|
|
|
|
|
> lua_unlock(L);
|
|
|
|
|
> return LUA_ERRRUN;
|
|
|
|
|
> }
|
|
|
|
|
>
|
|
|
|
|
>
|
2003-10-07 20:34:21 +08:00
|
|
|
|
355a363,368
|
|
|
|
|
> if (L->ci == L->base_ci) {
|
|
|
|
|
> if (nargs >= L->top - L->base)
|
2003-09-30 00:41:35 +08:00
|
|
|
|
> return resume_error(L, "cannot resume dead coroutine");
|
2003-10-07 20:34:21 +08:00
|
|
|
|
> }
|
2003-09-30 00:41:35 +08:00
|
|
|
|
> else if (!(L->ci->state & CI_YIELD)) /* not inside a yield? */
|
|
|
|
|
> return resume_error(L, "cannot resume non-suspended coroutine");
|
|
|
|
|
]],
|
2003-07-30 03:27:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[file:close cannot be called without a file. (results in seg fault)]],
|
|
|
|
|
example = [[
|
|
|
|
|
> io.stdin.close() -- correct call shold be io.stdin:close()
|
|
|
|
|
]],
|
|
|
|
|
report = [[by Tuomo Valkonen, 27/05/2003]],
|
|
|
|
|
patch = [[
|
|
|
|
|
* liolib.c:
|
|
|
|
|
161c161
|
|
|
|
|
< if (lua_isnone(L, 1)) {
|
|
|
|
|
---
|
|
|
|
|
> if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {
|
|
|
|
|
]], --}}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[C functions also may have stacks larger than current top]],
|
|
|
|
|
example = [[
|
|
|
|
|
Must recompile lua with a change in lua.c and with lua_assert defined:
|
|
|
|
|
* lua.c:
|
|
|
|
|
381a382
|
|
|
|
|
> lua_checkstack(l, 1000);
|
|
|
|
|
]],
|
|
|
|
|
report = [[Alex Bilyk, 09/06/2003]],
|
|
|
|
|
patch = [[
|
|
|
|
|
* lgc.c:
|
|
|
|
|
247c247
|
|
|
|
|
< if (!(ci->state & CI_C) && lim < ci->top)
|
|
|
|
|
---
|
|
|
|
|
> if (lim < ci->top)
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-20 01:03:47 +08:00
|
|
|
|
|
2003-07-30 03:27:46 +08:00
|
|
|
|
Bug{
|
|
|
|
|
what = [[`pc' address is invalidated when a coroutine is suspended]],
|
|
|
|
|
example = [[
|
|
|
|
|
function g(x)
|
|
|
|
|
coroutine.yield(x)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function f (i)
|
|
|
|
|
debug.sethook(print, "l")
|
|
|
|
|
for j=1,1000 do
|
|
|
|
|
g(i+j)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
co = coroutine.wrap(f)
|
|
|
|
|
co(10)
|
|
|
|
|
pcall(co)
|
|
|
|
|
pcall(co)
|
|
|
|
|
]],
|
|
|
|
|
report = [[Nick Trout, 07/07/2003]],
|
|
|
|
|
patch = [[
|
|
|
|
|
* lvm.c:
|
2004-03-16 05:09:55 +08:00
|
|
|
|
402,403c402,403
|
2003-07-30 03:27:46 +08:00
|
|
|
|
< L->ci->u.l.pc = &pc;
|
2004-03-16 05:09:55 +08:00
|
|
|
|
< if (L->hookmask & LUA_MASKCALL)
|
|
|
|
|
---
|
|
|
|
|
> if (L->hookmask & LUA_MASKCALL) {
|
|
|
|
|
> L->ci->u.l.pc = &pc;
|
|
|
|
|
404a405
|
|
|
|
|
> }
|
|
|
|
|
405a407
|
2003-07-30 03:27:46 +08:00
|
|
|
|
> L->ci->u.l.pc = &pc;
|
2004-03-16 05:09:55 +08:00
|
|
|
|
676,678c678
|
2003-07-30 03:27:46 +08:00
|
|
|
|
< lua_assert(ci->u.l.pc == &pc &&
|
|
|
|
|
< ttisfunction(ci->base - 1) &&
|
|
|
|
|
< (ci->state & CI_SAVEDPC));
|
|
|
|
|
---
|
|
|
|
|
> lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));
|
|
|
|
|
]]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[userdata to be collected still counts into new GC threshold,
|
|
|
|
|
increasing memory consumption]],
|
|
|
|
|
report = [[Roberto, 25/07/2003]],
|
|
|
|
|
example = [[
|
|
|
|
|
a = newproxy(true)
|
|
|
|
|
getmetatable(a).__gc = function () end
|
|
|
|
|
for i=1,10000000 do
|
|
|
|
|
newproxy(a)
|
|
|
|
|
if math.mod(i, 10000) == 0 then print(gcinfo()) end
|
|
|
|
|
end
|
|
|
|
|
]],
|
|
|
|
|
patch = [[
|
2003-08-30 00:50:02 +08:00
|
|
|
|
* lgc.h:
|
2003-07-30 03:27:46 +08:00
|
|
|
|
18c18
|
|
|
|
|
< void luaC_separateudata (lua_State *L);
|
|
|
|
|
---
|
|
|
|
|
> size_t luaC_separateudata (lua_State *L);
|
|
|
|
|
|
2003-08-30 00:50:02 +08:00
|
|
|
|
* lgc.c:
|
2003-07-30 03:27:46 +08:00
|
|
|
|
113c113,114
|
|
|
|
|
< void luaC_separateudata (lua_State *L) {
|
|
|
|
|
---
|
|
|
|
|
> size_t luaC_separateudata (lua_State *L) {
|
|
|
|
|
> size_t deadmem = 0;
|
|
|
|
|
127a129
|
|
|
|
|
> deadmem += sizeudata(gcotou(curr)->uv.len);
|
|
|
|
|
136a139
|
|
|
|
|
> return deadmem;
|
|
|
|
|
390c393
|
|
|
|
|
< static void checkSizes (lua_State *L) {
|
|
|
|
|
---
|
|
|
|
|
> static void checkSizes (lua_State *L, size_t deadmem) {
|
|
|
|
|
400c403
|
|
|
|
|
< G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
|
|
|
|
|
---
|
|
|
|
|
> G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */
|
|
|
|
|
454c457,458
|
|
|
|
|
< static void mark (lua_State *L) {
|
|
|
|
|
---
|
|
|
|
|
> static size_t mark (lua_State *L) {
|
|
|
|
|
> size_t deadmem;
|
|
|
|
|
467c471
|
|
|
|
|
< luaC_separateudata(L); /* separate userdata to be preserved */
|
|
|
|
|
---
|
|
|
|
|
> deadmem = luaC_separateudata(L); /* separate userdata to be preserved */
|
|
|
|
|
475a480
|
|
|
|
|
> return deadmem;
|
|
|
|
|
480c485
|
|
|
|
|
< mark(L);
|
|
|
|
|
---
|
|
|
|
|
> size_t deadmem = mark(L);
|
|
|
|
|
482c487
|
|
|
|
|
< checkSizes(L);
|
|
|
|
|
---
|
|
|
|
|
> checkSizes(L, deadmem);
|
|
|
|
|
]]
|
2003-08-30 00:50:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what=[[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-07-30 03:27:46 +08:00
|
|
|
|
|
2003-08-30 00:50:02 +08:00
|
|
|
|
report = [[David Burgess, 25/08/2003]],
|
|
|
|
|
|
|
|
|
|
example = [[print{}; (in an AS400 machine)]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* liolib.c:
|
|
|
|
|
178c178
|
|
|
|
|
< char buff[32];
|
|
|
|
|
---
|
|
|
|
|
> char buff[128];
|
|
|
|
|
|
|
|
|
|
* lbaselib.c:
|
|
|
|
|
327c327
|
|
|
|
|
< char buff[64];
|
|
|
|
|
---
|
|
|
|
|
> char buff[128];
|
|
|
|
|
]]
|
|
|
|
|
}
|
2003-09-30 00:41:35 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[syntax `local function' does not increment stack size]],
|
|
|
|
|
|
|
|
|
|
report = [[Rici Lake, 26/09/2003]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
-- must run this with precompiled code
|
|
|
|
|
local a,b,c
|
|
|
|
|
local function d () end
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lparser.c:
|
2003-10-10 01:56:23 +08:00
|
|
|
|
1143a1144
|
|
|
|
|
> FuncState *fs = ls->fs;
|
|
|
|
|
1145c1146,1147
|
2003-09-30 00:41:35 +08:00
|
|
|
|
< init_exp(&v, VLOCAL, ls->fs->freereg++);
|
|
|
|
|
---
|
2003-10-10 01:56:23 +08:00
|
|
|
|
> init_exp(&v, VLOCAL, fs->freereg);
|
|
|
|
|
> luaK_reserveregs(fs, 1);
|
|
|
|
|
1148c1150,1152
|
|
|
|
|
< luaK_storevar(ls->fs, &v, &b);
|
|
|
|
|
---
|
|
|
|
|
> luaK_storevar(fs, &v, &b);
|
|
|
|
|
> /* debug information will only see the variable after this point! */
|
|
|
|
|
> getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
|
2003-09-30 00:41:35 +08:00
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-07 20:34:21 +08:00
|
|
|
|
|
2004-03-16 05:09:55 +08:00
|
|
|
|
Bug{
|
2003-10-07 20:34:21 +08:00
|
|
|
|
|
|
|
|
|
what = [[count hook may be called without being set]],
|
|
|
|
|
|
|
|
|
|
report = [[Andreas Stenius, 06/10/2003]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
set your hooks with
|
|
|
|
|
|
|
|
|
|
lua_sethook(L, my_hook, LUA_MASKLINE | LUA_MASKRET, 1);
|
|
|
|
|
|
|
|
|
|
(It is weird to use a count > 0 without setting the count hook,
|
|
|
|
|
but it is not wrong.)
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lvm.c:
|
|
|
|
|
69c69
|
|
|
|
|
< if (mask > LUA_MASKLINE) { /* instruction-hook set? */
|
|
|
|
|
---
|
|
|
|
|
> if (mask & LUA_MASKCOUNT) { /* instruction-hook set? */
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
}
|
2004-03-16 05:09:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
|
|
|
|
|
what = [[`dofile' eats one return value when called without arguments]],
|
|
|
|
|
|
|
|
|
|
report = [[Frederico Abraham, 15/01/2004]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
a,b = dofile() --< here you enter `return 1,2,3 <eof>'
|
|
|
|
|
print(a,b) --> 2 3 (should be 1 and 2)
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lbaselib.c:
|
|
|
|
|
313a314
|
|
|
|
|
> int n = lua_gettop(L);
|
|
|
|
|
317c318
|
|
|
|
|
< return lua_gettop(L) - 1;
|
|
|
|
|
---
|
|
|
|
|
> return lua_gettop(L) - n;
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
}
|
2004-06-09 00:23:58 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-----------------------------------------------------------------
|
|
|
|
|
-- Lua 5.0.2
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[string concatenation may cause arithmetic overflow, leading
|
|
|
|
|
to a buffer overflow]],
|
|
|
|
|
|
|
|
|
|
report = [[Rici Lake, 20/05/2004]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
longs = string.rep("\0", 2^25)
|
|
|
|
|
function catter(i)
|
|
|
|
|
return assert(loadstring(
|
|
|
|
|
string.format("return function(a) return a%s end",
|
|
|
|
|
string.rep("..a", i-1))))()
|
|
|
|
|
end
|
|
|
|
|
rep129 = catter(129)
|
|
|
|
|
rep129(longs)
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lvm.c:
|
2004-11-03 20:22:39 +08:00
|
|
|
|
@@ -321,15 +321,15 @@
|
|
|
|
|
luaG_concaterror(L, top-2, top-1);
|
|
|
|
|
} else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */
|
|
|
|
|
/* at least two string values; get as many as possible */
|
|
|
|
|
- lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) +
|
|
|
|
|
- cast(lu_mem, tsvalue(top-2)->tsv.len);
|
|
|
|
|
+ size_t tl = tsvalue(top-1)->tsv.len;
|
|
|
|
|
char *buffer;
|
|
|
|
|
int i;
|
|
|
|
|
- while (n < total && tostring(L, top-n-1)) { /* collect total length */
|
|
|
|
|
- tl += tsvalue(top-n-1)->tsv.len;
|
|
|
|
|
- n++;
|
|
|
|
|
+ /* collect total length */
|
|
|
|
|
+ for (n = 1; n < total && tostring(L, top-n-1); n++) {
|
|
|
|
|
+ size_t l = tsvalue(top-n-1)->tsv.len;
|
|
|
|
|
+ if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
|
|
|
|
|
+ tl += l;
|
|
|
|
|
}
|
|
|
|
|
- if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
|
|
|
|
|
buffer = luaZ_openspace(L, &G(L)->buff, tl);
|
|
|
|
|
tl = 0;
|
|
|
|
|
for (i=n; i>0; i--) { /* concat all strings */
|
2004-06-09 00:23:58 +08:00
|
|
|
|
]]
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-18 01:45:45 +08:00
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[lua_getupvalue and setupvalue do not check for index too small]],
|
|
|
|
|
|
|
|
|
|
report = [[Mike Pall, ?/2004]],
|
|
|
|
|
|
|
|
|
|
example = [[debug.getupvalue(function() end, 0)]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lapi.c
|
|
|
|
|
941c941
|
|
|
|
|
< if (n > f->c.nupvalues) return NULL;
|
|
|
|
|
---
|
|
|
|
|
> if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
|
|
|
|
|
947c947
|
|
|
|
|
< if (n > p->sizeupvalues) return NULL;
|
|
|
|
|
---
|
|
|
|
|
> if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
|
|
|
|
|
]]
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-20 01:03:47 +08:00
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[values holded in open upvalues of suspended threads may be
|
|
|
|
|
incorrectly collected]],
|
|
|
|
|
|
|
|
|
|
report = [[Spencer Schumann, 31/12/2004]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
local thread_id = 0
|
|
|
|
|
local threads = {}
|
|
|
|
|
|
|
|
|
|
function fn(thread)
|
|
|
|
|
thread_id = thread_id + 1
|
|
|
|
|
threads[thread_id] = function()
|
|
|
|
|
thread = nil
|
|
|
|
|
end
|
|
|
|
|
coroutine.yield()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
while true do
|
|
|
|
|
local thread = coroutine.create(fn)
|
|
|
|
|
coroutine.resume(thread, thread)
|
|
|
|
|
end
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lgc.c:
|
|
|
|
|
221,224c221,222
|
|
|
|
|
< if (!u->marked) {
|
|
|
|
|
< markobject(st, &u->value);
|
|
|
|
|
< u->marked = 1;
|
|
|
|
|
< }
|
|
|
|
|
---
|
|
|
|
|
> markobject(st, u->v);
|
|
|
|
|
> u->marked = 1;
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-11 23:51:08 +08:00
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[rawset/rawget do not ignore extra arguments]],
|
|
|
|
|
|
|
|
|
|
report = [[Romulo Bahiense, 11/03/2005]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
a = {}
|
|
|
|
|
rawset(a, 1, 2, 3)
|
|
|
|
|
print(a[1], a[2]) -- should be 2 and nil
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lbaselib.c:
|
|
|
|
|
175a176
|
|
|
|
|
> lua_settop(L, 2);
|
|
|
|
|
183a185
|
|
|
|
|
> lua_settop(L, 3);
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-20 20:49:30 +08:00
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[weak tables that survive one collection are never collected]],
|
|
|
|
|
|
|
|
|
|
report = [[Chromix, 02/01/2006]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
a = {}
|
|
|
|
|
print(gcinfo())
|
|
|
|
|
for i = 1, 10000 do
|
|
|
|
|
a[i] = setmetatable({}, {__mode = "v"})
|
|
|
|
|
end
|
|
|
|
|
collectgarbage()
|
|
|
|
|
a = nil
|
|
|
|
|
collectgarbage()
|
|
|
|
|
print(gcinfo())
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lgc.c
|
|
|
|
|
@@ -366,7 +366,7 @@
|
|
|
|
|
GCObject *curr;
|
|
|
|
|
int count = 0; /* number of collected items */
|
|
|
|
|
while ((curr = *p) != NULL) {
|
|
|
|
|
- if (curr->gch.marked > limit) {
|
|
|
|
|
+ if ((curr->gch.marked & ~(KEYWEAK | VALUEWEAK)) > limit) {
|
|
|
|
|
unmark(curr);
|
|
|
|
|
p = &curr->gch.next;
|
|
|
|
|
}
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-22 03:28:49 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-----------------------------------------------------------------
|
|
|
|
|
-- Lua 5.1
|
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[In 16-bit machines, expressions and/or with numeric constants as the
|
|
|
|
|
right operand may result in weird values]],
|
|
|
|
|
|
|
|
|
|
report = [[Andreas Stenius, 15/03/2006]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
print(false or 0) -- on 16-bit machines
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lcode.c:
|
|
|
|
|
@@ -731,17 +731,15 @@
|
|
|
|
|
case OPR_AND: {
|
|
|
|
|
lua_assert(e1->t == NO_JUMP); /* list must be closed */
|
|
|
|
|
luaK_dischargevars(fs, e2);
|
|
|
|
|
- luaK_concat(fs, &e1->f, e2->f);
|
|
|
|
|
- e1->k = e2->k; e1->u.s.info = e2->u.s.info;
|
|
|
|
|
- e1->u.s.aux = e2->u.s.aux; e1->t = e2->t;
|
|
|
|
|
+ luaK_concat(fs, &e2->f, e1->f);
|
|
|
|
|
+ *e1 = *e2;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case OPR_OR: {
|
|
|
|
|
lua_assert(e1->f == NO_JUMP); /* list must be closed */
|
|
|
|
|
luaK_dischargevars(fs, e2);
|
|
|
|
|
- luaK_concat(fs, &e1->t, e2->t);
|
|
|
|
|
- e1->k = e2->k; e1->u.s.info = e2->u.s.info;
|
|
|
|
|
- e1->u.s.aux = e2->u.s.aux; e1->f = e2->f;
|
|
|
|
|
+ luaK_concat(fs, &e2->t, e1->t);
|
|
|
|
|
+ *e1 = *e2;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-22 03:31:09 +08:00
|
|
|
|
|
|
|
|
|
Bug{
|
|
|
|
|
what = [[luaL_checkudata may produce wrong error message]],
|
|
|
|
|
|
|
|
|
|
report = [[Greg Falcon, 21/03/2006]],
|
|
|
|
|
|
|
|
|
|
example = [[
|
|
|
|
|
getmetatable(io.stdin).__gc()
|
|
|
|
|
--> bad argument #1 to '__gc' (FILE* expected, got table)
|
|
|
|
|
]],
|
|
|
|
|
|
|
|
|
|
patch = [[
|
|
|
|
|
* lauxlib.c:
|
|
|
|
|
@@ -123,11 +123,17 @@
|
|
|
|
|
|
|
|
|
|
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
|
|
|
|
|
void *p = lua_touserdata(L, ud);
|
|
|
|
|
- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
|
|
|
|
|
- if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
|
|
|
|
|
- luaL_typerror(L, ud, tname);
|
|
|
|
|
- lua_pop(L, 2); /* remove both metatables */
|
|
|
|
|
- return p;
|
|
|
|
|
+ if (p != NULL) { /* value is a userdata? */
|
|
|
|
|
+ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
|
|
|
|
|
+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
|
|
|
|
|
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
|
|
|
|
|
+ lua_pop(L, 2); /* remove both metatables */
|
|
|
|
|
+ return p;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ luaL_typerror(L, ud, tname); /* else error */
|
|
|
|
|
+ return NULL; /* to avoid warnings */
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|