lua-users home
lua-l archive

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

Traditionally, lightuserdata has been intended as a way to represent C
pointers (or even handles [2]) in Lua, often as keys in a Lua table
[1], but another way we might think of lightuserdata is as a
lightweight, not-garbage-collected value type that can fit entirely in
register.  nil, boolean, and number are in this same class, and it's
similar to the concept of primitive POD types in C/C++ (e.g. int,
char, enum, etc.).  lightuserdata differs from the other types above
in that the bit pattern has no meaning to Lua.  The Lua API also
suggests that the size of a lightuserdata is equal to size(void *),
but this may be overly restrictive: on a 32-bit machine with 64-bit
floating point numbers, the Value type (Lua register) has enough room
for 64-bit lightuserdata's.  Such large lightuserdata can support, for
example, 64-bit bitwise operations [3] or any other 64-bit value
storage.  Although it's technically possible to use double-precision
lua_Number's to store arbitrary 64-bit data values as well, beyond
53-bits these values will no longer be interpretable as numbers and
may not be usable as table keys or support comparison (since NaN ~=
NaN).  (Additional caveat: in LuaJIT the upper "NaN" bits of 64-bit
Value's are reserved for special purposes, and this limitation likely
prohibits using all bits of 64-bit lightuserdata's.)

The attached patch makes lightuserdata more of a first-class type in
Lua.  It's written only as a quick proof of concept.  Number literals
postfixed by "u" are treated as lightuserdata constants, and unsigned
arithmetic operations are supported over lightuserdata's.  Bitwise
operations like XOR could be supported via a library function.  You
can do things like

  assert(type(0x123u) == 'userdata')
  print(0x123u) --> userdata: 0x123
  local x = 0x123u + 0x1u
  assert(x == 0x124u)
  print(tolightuserdata(0x123)) --> userdata: 0x123
  assert(tonumber(0x123u) == 0x123)

This is just some food for thought.  64-bit (or 128-bit or 256-bit
values for that matter) can of course represented as multiple 32-bit
values if needed.  A common need, for example, is representing (x,y,z)
vector values (192-bit) or complex numbers, and the typical solution
is to represent each component in its own register rather than try to
stuff in all in a single register.


Attachment: lua-5.1.4-lud-patch
Description: Binary data