lua-users home
lua-l archive

Re: Feature request: userdata slice

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2015年08月20日 8:49 GMT+02:00 Dirk Laurie <dirk.laurie@gmail.com>:
> I think I understand it now,
...
> I agree that a tool of this power will quickly inspire many ways of
> using it.
If anyone wants to try it out, the module is attached.
Tested under 5.2.4 and 5.3.1. Does not work under 5.1.
/* typetag.c © Dirk Laurie 2015 MIT license, see Lua source code
 Extends debug library with two new methods.
 debug.gettypetag(val): returns the type tag of `val`
 debug.settypetag(val,tag): returns a new value with the same value 
 field as `val` but with the given type tag, which must be compatible
 with the type of `val`. The return value is not raw-equal to `val`.
 For example, a value that satisfies type(v)==nil but tests true
 can be created this way.
 If TYPETAG_NOBRAKES is not defined, `val` must be of type userdata. 
 See thread starting with
 http://lua-users.org/lists/lua-l/2015-08/msg00256.html
 especially my contribution at 20 Aug 2015 08:49:35 +0200.
 Linux compilation: change `#define LUA_SRC`, then on 64-bit machine
 cc -shared -fPIC -D TAGTYPE_NOBRAKES gettypetag.c -o gettypetag.so
*/
#define LUA_SRC(file) </usr/local/src/lua-5.3.1/src/file>
#include LUA_SRC(lobject.h)
#include LUA_SRC(lstate.h)
#include LUA_SRC(lauxlib.h)
static int lua_settypetag(lua_State *L) {
 int newtype = luaL_checkinteger(L,2);
#ifndef TAGTYPE_NOBRAKES
 luaL_checktype (L, 1, LUA_TUSERDATA);
#endif
 luaL_checktype (L, 1, novariant(newtype));
 lua_settop(L,1);
 (L->top-1)->tt_ = newtype;
 return 1;
}
static int lua_gettypetag(lua_State *L) {
 luaL_checkany(L,1);
 lua_settop(L,1); 
 lua_pushinteger(L,(L->top-1)->tt_);
 return 1;
}
LUAMOD_API int luaopen_typetag(lua_State *L) {
 lua_getglobal(L,"debug");
 lua_pushcfunction(L,lua_settypetag);
 lua_setfield(L,-2,"settypetag");
 lua_pushcfunction(L,lua_gettypetag);
 lua_setfield(L,-2,"gettypetag");
 return 0;
}
/* Test suite with -D TYPETAG_NOBRAKES
y=debug.settypetag(nil,16)
print(y,type(y)) --> nil nil
print(y==nil) --> false
if y then print(debug.gettypetag(y)) else print(nil) end --> 16
x=debug.settypetag(1.0,16) --> type error
x=debug.settypetag(1.0,debug.gettypetag(1))
print(x) --> 4607182418800017408 (5.3 only)
print(("%X"):format(x)) --> 3FF0000000000000 (5.3 only)
*/
 

AltStyle によって変換されたページ (->オリジナル) /