lua-users home
lua-l archive

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


It was thus said that the Great Dibyendu Majumdar once stated:
> Hi,
> 
> Apologies if this is going over old ground ... I have been thinking
> about how to allow fast metamethods for userdata objects. As userdata
> objects are created by C code then it is possible for C code to
> provide an array of C functions (like a C++ vtable) for the userdata
> object - the C functions to be used as metamethods.
> 
> What would be reason for not doing it this way?

  I assume you are talking about functions like __add() or __concat().

  Well, not all metamethods are functions.  __mode, __metatable and __name
(Lua 5.3) are never functions, while __index and __newindex can either be a
function or a table.  Most, however, are functions [1].

  For insance, "x = lpeg.P(1)" has the following metatable:

__mul    function: 0x77adf8   
__add    function: 0x77ad08   
__pow    function: 0x77ab04   
__div    function: 0x77a8c8   
__name   "lpeg-pattern"       
__unm    function: 0x77a84c   
__gc     function: 0x77b384   
__index  table: 0x9664278     
__sub    function: 0x77a6e8   
__len    function: 0x77aa94   

__index could just as easily have been a function (maybe not for LPeg but in
the general case).

  Also, metatables are used to provide functions (or fields) other than the
defined metamethod ones.  For instance, the metatable for io.stdout (again,
Lua 5.3):

__tostring  function: 0x8060888   
flush       function: 0x8061a00   
lines       function: 0x8060df0   
__name      "FILE*"               
seek        function: 0x80618a8   
write       function: 0x8061870   
setvbuf     function: 0x8061960   
__gc        function: 0x80609d8   
__index     table: 0x9654428      
close       function: 0x806098c   
read        function: 0x80615cc   

  The metatable is a nice place to cache all this.  

> I am interested in this as I want to achieve high performance for
> certain operations involving userdata types - which otherwise means I
> have to make the VM recognize these types so that it can perform
> operations on these types natively. However that approach isn't
> scalable as enhancing the VM to recognize new types is a lot of work.

  What type of high performance are you expecting?  Outside of numbers and
strings, trying to get high performance out of metamethods with userdata
just doesn't seem to make sense to me.  LPeg is perhaps the worse-case
scenario here (which to me, makes it the best place to start) as the '*'
operator isn't multiplcation (it's more of an "and" operation but not
commutative).

  -spc

[1]	A table I constructed for my own use, and may be useful here:

               5.1     5.2     5.3     function
__add           *       *       *       a + b
__sub           *       *       *       a - b
__mul           *       *       *       a * b
__div           *       *       *       a / b
__mod           *       *       *       a % b
__pow           *       *       *       a ^ b
__umn           *       *       *       -a
__idiv                          *       a // b
__band                          *       a & b
__bor                           *       a | b
__bxor                          *       a ~ b
__bnot                          *       ~a
__shl                           *       a << b
__shr                           *       a >> b
__concat        *       *       *       a .. b
__len           *       *       *       #a
__eq            *       *       *       a == b
__lt            *       *       *       a < b
__le            *       *       *       a > b
__index         *       *       *       a = b[]         can be table
__newindex      *       *       *       a[] = b         can be table
__call          *       *       *       a()
__gc            *       *       *
__mode          *       *       *                       string
__metatable     *       *       *                       table
__tostring      *       *       *
__ipairs                *
__pairs                 *       *
__name                          *                       string