[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Custom extensions to Lua
- From: Lisa Parratt <lisa@...>
- Date: Wed, 10 Aug 2005 16:11:26 +0100
I've been developing a number of libraries for Lua (currently on 5.1w6)
for the company I work for (this unfortunately means I can't go into too
much detail about them or their uses).
My current main project is a glue code system for allowing Lua scripts
to access C variables and functions. Rather than taking the approach to
tolua, etc. of directly binding these elements into the Lua namespace,
it instead takes a more dynamic object oriented approach.
Proxy objects (tables at their core) intercept attempts to get and set
values, look up indices, look up structure/union members and call
functions. These appear to the user to be native Lua data types, but
instead apply operations to the underlying C equivalent. These proxies
are generated on the fly through the use of the __index metamethod.
Unfortunately, I've had to add some metamethods to give them the truly
__type: Overrides the return value of the Lua function type().
__set: Overrides an attempt to set the value of a Lua value. This is
used to make assignment set the value of the underlying C value, rather
than replacing the proxy object with the new value. See below for some
__tonumber: Overrides an attempt to convert a Lua value to a number.
This is invoked by the C function lua_tonumber(), among other methods.
This, along with some modifications to the VM arithmetic operations,
allows proxies to be used in mathematical operations as though they were
native Lua numbers.
__tostring: Overrides an attempt to convert a Lua value to a number.
This is invoked by the C function lua_tostring(), among other methods.
This allows proxies to be used as though they were native Lua strings.
__ueq: Untype checked equals comparison. The normal comparison
metamethods do not allow mixed types, preventing numbers from being
compared against proxies. This metamethod is invoked when an attempt is
made to compare different types.
__ult: Untype checked less than comparison.
__ule: Untype checked less than or equals comparison.
__not: Overrides the not operator. A proxy is really a table, meaning
that "not proxy" will always return false. This allows the result to be
dependent on the underlying value of the proxy.
Can anybody suggest any ways of providing similar functionality that
appears seamless to the end user without having to make these modifications?
There are a couple of troubling issues:
Occasionally, intermittent errors such as "attempt to compare number
with boolean" occur. I'm currently putting these down to subtle stack
corruption issues, but they squirm away from beneath me when I try to
instrument my code. Does anyone have any hints for debugging such issues?
Locals and the __set metamethod - essentially, for every VM cycle, the
interpreter has to check whether RA represents a local. If it does, then
it will check if the __set metamethod needs to be used. If this check is
not done, then everything breaks horribly because the VM attempts to
reuse a register and mistakenly triggers the __set metamethod.
Currently, I'm walking through the call info stack to determine which
registers are locals and which aren't at the start of each cycle, but
this is horribly inefficient. I've tried adding a second stack of flags
which indicates which registers are locals and which aren't, and this is
maintained when the stack is resized, when a Lua function is called,
when a Lua function returns, and when a Lua function tail returns.
However, this doesn't work - the flags do not mirror the results of the
call info stack walk. I suspect this may be related to upvalues and
other similar issues. Can anybody shed any light on this issue?
Personally, I don't like having to have made these changes - they make
upgrading to new versions of Lua more difficult and slow Lua down - but
Any assistance people can provide to help me remove my custom
metamethods and restore the performance and reliability of the VM would
be appreciated. If you need any clarifications, don't hesitate to ask,
I'm well aware that I can blabber on a bit :)