diff --git a/lapi.c b/lapi.c index 63e0e750..2f0a35cc 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.226 2014/07/17 13:53:37 roberto Exp roberto $ +** $Id: lapi.c,v 2.227 2014/07/18 12:17:54 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -420,7 +420,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { LUA_API void *lua_touserdata (lua_State *L, int idx) { StkId o = index2addr(L, idx); switch (ttnov(o)) { - case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TUSERDATA: return getudatamem(uvalue(o)); case LUA_TLIGHTUSERDATA: return pvalue(o); default: return NULL; } @@ -706,7 +706,7 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) { lua_lock(L); o = index2addr(L, idx); api_check(ttisfulluserdata(o), "full userdata expected"); - getuservalue(L, rawuvalue(o), L->top); + getuservalue(L, uvalue(o), L->top); api_incr_top(L); lua_unlock(L); return ttnov(L->top - 1); @@ -842,7 +842,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { api_checknelems(L, 1); o = index2addr(L, idx); api_check(ttisfulluserdata(o), "full userdata expected"); - setuservalue(L, rawuvalue(o), L->top - 1); + setuservalue(L, uvalue(o), L->top - 1); luaC_barrier(L, gcvalue(o), L->top - 1); L->top--; lua_unlock(L); @@ -1142,7 +1142,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { setuvalue(L, L->top, u); api_incr_top(L); lua_unlock(L); - return u + 1; + return getudatamem(u); } diff --git a/lgc.c b/lgc.c index 87d6ca6c..574a66cc 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.186 2014/07/18 12:17:54 roberto Exp roberto $ +** $Id: lgc.c,v 2.187 2014/07/18 13:36:14 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -237,7 +237,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { markobject(g, gco2u(o)->metatable); /* mark its metatable */ gray2black(o); g->GCmemtrav += sizeudata(gco2u(o)); - getuservalue(g->mainthread, rawgco2u(o), &uvalue); + getuservalue(g->mainthread, gco2u(o), &uvalue); if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */ o = gcvalue(&uvalue); goto reentry; diff --git a/lobject.h b/lobject.h index 3bf7045a..a5827f84 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.97 2014/07/18 12:17:54 roberto Exp roberto $ +** $Id: lobject.h,v 2.98 2014/07/18 13:36:14 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -157,8 +157,7 @@ typedef struct lua_TValue TValue; #define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) #define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) -#define rawuvalue(o) check_exp(ttisfulluserdata(o), rawgco2u(val_(o).gc)) -#define uvalue(o) (&rawuvalue(o)->uv) +#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) #define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) #define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) #define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) @@ -214,7 +213,7 @@ typedef struct lua_TValue TValue; #define setuvalue(L,obj,x) \ { TValue *io = (obj); Udata *x_ = (x); \ - val_(io).gc = obj2gco(&x_->uv); settt_(io, ctb(LUA_TUSERDATA)); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \ checkliveness(G(L),io); } #define setthvalue(L,obj,x) \ @@ -324,7 +323,7 @@ typedef union UTString { */ #define getaddrstr(ts) (cast(char *, (ts)) + sizeof(UTString)) #define getstr(ts) \ - ((void)(ts)->extra, cast(const char*, getaddrstr(ts))) + check_exp(sizeof((ts)->extra), cast(const char*, getaddrstr(ts))) /* get the actual string (array of bytes) from a Lua value */ #define svalue(o) getstr(tsvalue(o)) @@ -332,28 +331,42 @@ typedef union UTString { /* ** Header for userdata; memory area follows the end of this structure +** (aligned according to 'UUdata'; see next). */ -typedef union Udata { - L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ - struct { - CommonHeader; - lu_byte ttuv_; /* user value's tag */ - struct Table *metatable; - size_t len; /* number of bytes */ - union Value user_; /* user value */ - } uv; +typedef struct Udata { + CommonHeader; + lu_byte ttuv_; /* user value's tag */ + struct Table *metatable; + size_t len; /* number of bytes */ + union Value user_; /* user value */ } Udata; +/* +** Ensures that address after this type is always fully aligned. +*/ +typedef union UUdata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + Udata uv; +} UUdata; + + +/* +** Get the address of memory block inside 'Udata'. +** (Access to 'ttuv_' ensures that value is really a 'Udata'.) +*/ +#define getudatamem(u) \ + check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata))) + #define setuservalue(L,u,o) \ { const TValue *io=(o); Udata *iu = (u); \ - iu->uv.user_ = io->value_; iu->uv.ttuv_ = io->tt_; \ + iu->user_ = io->value_; iu->ttuv_ = io->tt_; \ checkliveness(G(L),io); } #define getuservalue(L,u,o) \ { TValue *io=(o); const Udata *iu = (u); \ - io->value_ = iu->uv.user_; io->tt_ = iu->uv.ttuv_; \ + io->value_ = iu->user_; io->tt_ = iu->ttuv_; \ checkliveness(G(L),io); } diff --git a/lstate.h b/lstate.h index 662e925a..6e411317 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.111 2014/07/18 12:17:54 roberto Exp roberto $ +** $Id: lstate.h,v 2.112 2014/07/18 13:36:14 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -175,7 +175,7 @@ struct lua_State { union GCUnion { GCObject gc; /* common header */ struct TString ts; - union Udata u; + struct Udata u; union Closure cl; struct Table h; struct Proto p; @@ -188,8 +188,7 @@ union GCUnion { /* macros to convert a GCObject into a specific value */ #define gco2ts(o) \ check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) -#define rawgco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) -#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) #define gco2cl(o) \ diff --git a/lstring.c b/lstring.c index fdd76300..cb8d1e2a 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.41 2014/07/18 12:17:54 roberto Exp roberto $ +** $Id: lstring.c,v 2.42 2014/07/18 13:36:14 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -170,10 +170,10 @@ Udata *luaS_newudata (lua_State *L, size_t s) { GCObject *o; if (s > MAX_SIZE - sizeof(Udata)) luaM_toobig(L); - o = luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s); - u = rawgco2u(o); - u->uv.len = s; - u->uv.metatable = NULL; + o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s)); + u = gco2u(o); + u->len = s; + u->metatable = NULL; setuservalue(L, u, luaO_nilobject); return u; } diff --git a/lstring.h b/lstring.h index f4f60a20..e515bf30 100644 --- a/lstring.h +++ b/lstring.h @@ -15,7 +15,8 @@ #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) #define sizestring(s) sizelstring((s)->len) -#define sizeudata(u) (sizeof(union Udata)+(u)->len) +#define sizeludata(l) (sizeof(union UUdata) + (l)) +#define sizeudata(u) sizeludata((u)->len) #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ (sizeof(s)/sizeof(char))-1)) diff --git a/ltests.c b/ltests.c index fde7fdcd..a24117a2 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.178 2014/07/18 12:17:54 roberto Exp roberto $ +** $Id: ltests.c,v 2.179 2014/07/18 13:36:14 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -319,7 +319,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) { TValue uservalue; Table *mt = gco2u(o)->metatable; checkobjref(g, o, mt); - getuservalue(g->mainthread, rawgco2u(o), &uservalue); + getuservalue(g->mainthread, gco2u(o), &uservalue); checkvalref(g, o, &uservalue); break; }