[gambit-list] Converting uint32 to scheme object

Marc Feeley feeley at iro.umontreal.ca
Wed Jan 6 23:00:26 EST 2016


I can see a few problems with the glue code you wrote to interface your C function to Lua:

- it isn’t checking that the number of parameters received by the function is correct
- it isn’t checking that the first parameter is a pointer of type TIFF*
- it isn’t checking that the first parameter is not NULL
- it doesn’t appear to do the right thing when val is a uint32 with the upper bit set (I suspect it will return a negative integer)
- if there is a type error (say the second parameter is not an integer), will there be a precise error message or exception indicating that the second parameter was not of the right type? can the exception be caught in Lua?
- I suspect that lua_pushinteger may allocate memory (for a bignum or flonum?), so what happens if this allocation causes the heap to overflow? can this be caught in Lua?

In this particular example, Gambit’s glue code is not much longer than the one for Lua, but it doesn’t suffer from these issues.  For a typical function with simple types for parameters and result, Gambit’s FFI does not require any glue code.

So as you can probably tell, I’m more enclined to qualify Lua’s FFI as “simple” and not “brilliant”… :-)

Marc

> On Jan 6, 2016, at 5:59 PM, Alex Queiroz <asandroq at gmail.com> wrote:
> 
> Hi Marc,
> 
> On 6 January 2016 at 16:10, Marc Feeley <feeley at iro.umontreal.ca> wrote:
>> Could you show the actual code required for Lua?  Is it able to catch heap overflows in Lua code?  When there is a conversion error, does the error message indicate which parameter is causing the problem?  How must the glue code be written to avoid space leaks and dangling references?  Does it support bignums?
>> 
>> The Gambit FFI was designed to interface to C libraries directly (without having to write glue code).  Is this possible with Lua’s FFI?
>> 
> 
> The Lua C API always require glue functions. In fact, all C functions
> callable by the VM have the same fixed prototype. The same code would
> be:
> 
> ```
> static int uint32_tag(lua_State *L)
> {
>   TIFF *tiff = (TIFF*)lua_touserdata(L, 1);
>   ttag_t tag = (ttag_t)lua_tointeger(L, 2);
> 
>   uint32 val;
>   if(TIFFGetField(tiff, tag, &val) == 1)
>   {
>      lua_pushinteger(L, val);
>   }
>   else
>   {
>      lua_pushnil(L);
>   }
> 
>   return 1;
> }
> ```
> The Lua API is based around a stack where arguments and return values
> are passed back and forth. The `lua_to*` and `lua_push*` functions
> take care of casting, boxing and memory management. Although the FFI
> code may be a little verbose for simpler functions, I never found a
> situation where I had to work around something. There are also check
> functions that help checking the type of arguments are throwing
> exceptions if the types are wrong.
> 
> Cheers,
> -- 
> -alex
> http://unendli.ch/




More information about the Gambit-list mailing list