lua-users home
lua-l archive

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

Florian Weimer wrote:
> > Right now the call chain 'FFI -> C -> lua_*()' with the same
> > lua_State is a big no-no. I'm planning to add an extra GCC-like
> > attribute that could be used to mark C functions which do that.
> > So you can still call these functions from Lua, but it's only done
> > from the interpreter (e.g. for the entry into a GUI main loop).
> Would the approach work right now?


> Could you bail out the interpreter only if a callback actually
> happens, or would that overhead apply in all cases?

Nope, that's too late. The full state cannot be easily restored
without, well, always restoring it before calling into C. This is
too expensive and pointless most of the time.

> > This is quite tricky and has some inherent issues, e.g. dynamically
> > generated trampolines cannot be deallocated. So I've postponed this
> > for now.
> The usual void * parameter makes the per-closure trampoline
> superfluous.

There's no way the FFI could infer that.

> Would it be possible to put the auxiliary data into some
> special cdata object, and require that the programmer keeps the object
> live while the callback can be called?

That would imply explicit callback management:

  local cb = ffi.callback(function() ... end) -- hypothetical
  saved[cb] = true

I find that rather tedious and I don't want to inflict this on
developers. I'm sure the first thing they'll try, is this:

  somegui.onclick(ffi.callback(function() ... end)) -- WRONG!


> > Another option would be to add a ffi.osdef convenience module,
> > which has all of the generic POSIX types, or the LPCTSTR mess for
> > Windows. The latter wouldn't be too bad, because the Windows types
> > are cast in stone. But the former requires tricky pre-processing
> > to get the needed OS-specific types without including lots of
> > extra cruft.
> I have done this to generate Ada bindings.  Currently, if you know
> that something is an integral type, you only need to check the value
> of sizeof and the signedness of the type.  This gives you enough
> information to reconstruct an equivalent typedef.

Gets tricky for structs. Not that POSIX defines that many.

And it's going to mess up C++ name mangling, too. Because 'long'
is considered a separate type from 'int', even when they are the
same size. AFAIR there are inconsistencies wrt. POSIX types and
'long', depending on when the OS/libc got a 64 bit variant or how
they deal with Y2K38 issues.

> For my Ada stuff, I called a get_errno function like this one:
>   #include <errno.h>
>   int
>   get_errno(void)
>   {
>     return errno;
>   }

Good idea. But the errno value needs to be fetched every time,
just in case it's checked later on. That would slow down things
quite a bit. One could define __errno_if_minus_1 or such, to fetch
it on demand. Hmm.

> (Apparently, Oracle still ships code with "extern int errno;" in it,
> which makes things much easier, but puts the affected software firmly
> into the past.)

Someone thought about that. It turns into a dummy declaration. :-)

Here's the result for GLIBC after pre-processing:

  extern int (*__errno_location ());       // was: extern int errno;
  printf("%d\n", (*__errno_location ()));  // was: printf("%d\n", errno);