Re: FFI methods for userdata objects

  • From: Simon Cooke <sjcfwd@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 6 Sep 2012 11:54:15 -0400

Mike Pall <mike-1209@xxxxxxxxxx> wrote:
> Simon Cooke wrote:
>> However, __newindex gives the following error:
>>
>>     'void ()' cannot be indexed with 'number'
>
> Ah, I forgot: __index and __newindex needs to make a decision
> whether to call or to index its value. It's hard to distinguish
> between generically callable vs. indexable objects. So the rule in
> Lua 5.1 is that plain functions are callable, but everything else
> (including cdata) is indexed. That's why you get this error.
>
> [Also, even if one would make an exception for cdata functions,
> these would need an extra __call dispatch, which runs into the
> same problem as for a __call metamethod itself.]
>

The error makes sense now - and fits with the pseudocode for these
metamethods in the Lua Reference Manual.

>> My specific use case is a class for large arrays (basically a C++
>> std::vector<T>) using __call to read elements and __newindex to write.
>
> Ok, if you need this is for interoperability. But you realize it
> would be much faster to use a plain FFI data structure? This
> doesn't need any C calls to index it.
>

This is strictly a quick fix to get significantly better indexing
performance from the Lua side while maintaining interoperability with
existing C++ data structures and calls to wrapped C++ extension
modules. For new developments I'm using FFI exclusively as you
suggest, but this application predates the release of the FFI library
and adapting to use it fully will require significantly more effort.

> The simple workaround would be to use parentheses to prevent the
> tailcall:
>
> mt.__call = function(self,k) return (clib.get_double(self,k)) end -- line 13

That fixed it! Everything now works perfectly.

Thanks,
Simon

Other related posts: