lua-users home
lua-l archive

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



  AN ADDRESS IS NOT AN INTEGER!

  I remember this crap going from 16 bit to 32 bit systems [1] and frankly,
I'd rather not have to live through that again going to 64 bit [3][4].

An address in not an integer, but a handle can be.
For example, in posix , file handle is an integer , and file is an object ,too.

We don't need create more than 2^32 userdata in one lua vm, so we can create an array in lua global state ( G(L) ),  and use an integer index to indicate the userdata object's address.

It would be like this:

union Value {
  GCObject *gc;    /* collectable objects */
  void *p;         /* light userdata */
  int b;           /* booleans */
  lua_CFunction f; /* light C functions */
  lua_Integer i;   /* integer numbers */
  lua_Number n;    /* float numbers */
  struct {
      int handle;  
      int slice ;
   } u;   /* full userdata with an integer */
};

and add an array in global_State 

typedef struct global_State {
    int userdata_cap;
    struct Udata *userdata_array;
    ....
};

The lua_touserdata could be:

LUA_API void *lua_touserdata (lua_State *L, int idx) {
  StkId o = index2addr(L, idx);
  switch (ttnov(o)) {
    case LUA_TUSERDATA: return G(L)->userdata_array[o->u.handle];
    case LUA_TLIGHTUSERDATA: return pvalue(o);
    default: return NULL;
  }
}

  Also, I don't think I'm following your API there.  I have this structure:

        typedef union sockaddr_all
        {
          struct sockaddr     sa;
          struct sockaddr_in  sin;
          struct sockaddr_in6 sin6;
          struct sockaddr_un  ssun;
        } sockaddr_all__t;

which I'm using for a userdata.  I have a custom __index method associated
with this that gives me the following "fields":

        addr            - text representation of IPv4/IPv6 address
        daddr           - other text representation of IPv4/IPv6 address [5]
        addrbits        - The raw binary bits that make up an IPv4/IPv6 address
        port            - port number
        family          - string, either 'ip', 'ip6' or 'unix'.
        display         - textual representation of address and port.

  How would your system with with that?

[1]     Want to know how false this is?  I can name a mainstream system that
        used C, that could have both 16 *AND* 32 bit pointers *IN THE SAME
        PROGRAM* and where ints were 16 *BITS* long. [2]
 

You can use 1 for sa, 2 for sin, 3 for sin6 , and 4 for ssun. 0 means the sockaddr_all.

In lua, you  can use

local sall = create_sockaddr(...) -- sa is an userdata that store sockaddr_all__t
local sin = sall.sin  
print(sin.port) 

How to implement these by new api lua_getuserslice and lua_setuserslice ?

#define SOCKADDR 0
#define SOCKADDR_SIN 1
#define SOCKADDR_SIN6 2
#define SOCKADDR_UN 3

int sa_root_index(lua_State *L) {
  const char * f = luaL_checkstring(L, 2);
  int slice = 0;
  if (strcmp(f, "sin")== 0)
    slice = 1;
  else  if (strcmp(f, "sin6") == 0)
    slice = 2;
  else if (strcmp(f, "un") == 0)
    slice = 3;
  else
    return luaL_error(L, "never here");
  lua_settop(L,1);
  lua_setuserslice(L,1,slice);
  return 1;
}

int sa_sin_index(lua_State *L) {
  const char * f = luaL_checkstring(L, 2);
  sockaddr_all_t *obj = lua_touserdata(L,1);
  if (strcmp(f, "port") == 0)
    lua_pushinteger(L, obj->sin.sin_port);
  else {
    // todo: supoort sin.sin_family ... etc
  }
  return 1;
}

int sockaddr_index(lua_State *L) {
  // todo: do more type check
  sockaddr_all_t *obj = lua_touserdata(L,1);
  int slice = lua_getuserslice(L,1);
  switch (slice) {
  case SOCKADDR :
    return sa_root_index(L);
  case SOCKADDR_SIN:
    return sa_sin_index(L);
  case SOCKADDR_SIN6:
    return sa_sin6_index(L);
  case SOCKADDR_UN:
    return sa_un_index(L);
  }
  return luaL_error(L, "never here");
}


[3]     One my my pet peeves with LuaJIT is the 2G limit on memory
        allocation, because of tricks played with pointers.

I don't like 2G limit of LuaJIT, too. and I spent months to remove the limit , but failed.