lua-users home
lua-l archive

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


Mark Hamburg wrote:
> Side note to Mike Pall on that subject: You mentioned the
> possibility of teaching LuaJIT about a matrix userdata type so
> that it could optimize it. How hard is it to teach LuaJIT about
> specific userdata types?

This is dependent on the last work item on the status page: access
to structured binary data plus the FFI. Once this is in place, it
should be quite easy. You can just cut'n'paste your C struct
definitions and allocate userdata objects holding such a struct
(or a union, an array or a nested mix of them).

I haven't given much thought to the API yet, but it might look
something like this:

  ffi.def[[
    struct foo {
      uint16_t bar, baz;
      int i;
      double d;
    };
    struct foo *foo_in(void);
    void foo_out(struct foo *);
  ]]
  local lib = ffi.bindlib("myfoolib")

  local a = lib.foo_in()
  local b = ffi.new("struct foo")
  b.i = a.i + 10
  b.bar = bit.bxor(a.bar, a.baz)
  b.baz = 0x1234
  b.d = a.d - 1.5
  lib.foo_out(b)

  -- Nice side-effect: efficient, mutable buffers for Lua.
  local buf = ffi.new("uint8_t[?]", n)
  for i=0,n-1 do
    buf[i] = i
  end
  io.write(buf) -- Extended to understand binary data.

As you can see, this allows one to access C structs just like Lua
tables. Obviously these structs can be exchanged with the C side
via the FFI. All operations on these structures can be reduced by
the JIT compiler to essentially the same machine code a C compiler
would produce.

Objects allocated on the Lua side are special userdatas and
garbage collected as usual. Data passed in from the C side gets a
tiny userdata wrapper (which may be optimized away by the JIT
compiler). The userdata wrapper is GCed, but the data itself is
owned by the C side and needs manual lifetime management. You can
associate a __gc metamethod to signal the C side.

These special userdatas have no metatable by default, but redirect
index/newindex to internal accessor functions. You can augment
them with your own index/newindex or other metamethods to get
OO-like behavior.

This is just the basic infrastructure. Automatic C library wrappers
or higher-level bindings can be implemented on top of it in pure
Lua. This could even be extended to create (mostly) automatic and
highly-efficient C++ bindings, but this is notoriously difficult.

At least that's the plan ...

--Mike