lua-users home
lua-l archive

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


2009/12/9 Mike Pall <mikelu-0912@mike.de>:
> Jerome Vuarand wrote:
>> > You can pass it any pointer value that is legal on x64 in
>> > user-mode under the currently supported 48 bit memory model. In
>> > practice this means it's accepted by lua_pushlightuserdata() if
>> > the highest 16 bits are zero (user-mode pointers can only point to
>> > addresses 0 .. 2^47-1).
>>
>> Does that mean that C modules that use light userdata to store size_t
>> integers (for example for bitfields) will have the upper 16bits
>> clamped ? For the moment I'm mostly concerned by the win32 API, which
>> uses the UINT_PTR type quite often. However in the partial bindings I
>> have so far all enum and bitfield types are 32bits (mostly DWORD).
>
> What you're intending to do is not covered by any C standard.
>
> Yes, you may cast a pointer into an intptr_t and get it back later
> (*2). But the inverse is generally not allowed (*1). You can't
> cast arbitrary bit patterns to a pointer and assume this doesn't
> cause an exception or that you get them back unmodified later.
> You'll get away with it on most platforms, but your code would
> rely on undefined behavior.
>
> The signature of lua_pushlightuserdata(lua_State *L, void *p)
> makes it quite clear that you need to pass a pointer. Arbitrary
> bit patterns that happen to fit into a pointer-sized object do not
> qualify. It must be a valid pointer per the memory model (see above).
>
> [AFAIK the WIN32 API only relies on ptr->UINT_PTR->ptr, but not
> the inverse.]

The point is that I was able (without being backed by "any C
standard") to store integer constants and values that do not fit a
double in the 64bits win32 ABI (e.g. INVALID_SOCKET, TVI_FIRST) in a
Lua light userdata. To be compatible with LuaJIT2 I'll have to put
these objects in a full userdata, and make sure my lua_toUINT_PTR
accept these.

Assuming I properly understood what you explain, a size_t can contain
a void*, but not the contrary. With that in mind I'd rather have
lua_pushlightuserdata take a size_t than a void*. But obviously that
would break your value packing model, so I guess I can't have a fully
satisfactory solution.