فهرست منبع

type 'Udata' refers directly to structure inside the union (union
used only for aligning purposes now)

Roberto Ierusalimschy 11 سال پیش
والد
کامیت
bb12903120
7فایلهای تغییر یافته به همراه48 افزوده شده و 35 حذف شده
  1. 5 5
      lapi.c
  2. 2 2
      lgc.c
  3. 29 16
      lobject.h
  4. 3 4
      lstate.h
  5. 5 5
      lstring.c
  6. 2 1
      lstring.h
  7. 2 2
      ltests.c

+ 5 - 5
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);
 }
 
 

+ 2 - 2
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;

+ 29 - 16
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); }
 
 

+ 3 - 4
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)  \

+ 5 - 5
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;
 }

+ 2 - 1
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))

+ 2 - 2
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;
       }