lua-users home
lua-l archive

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


On Sat, Jul 1, 2017 at 7:22 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
> On 30 June 2017 at 16:56, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote:
>> I am looking at an optimization scenario. My goal is to allow certain
>> native C functions that take one or two primitive arguments and return
>> a primitive, to be called directly by the VM bypassing the normal Lua
>> function call sequence. Examples of functions that can be handled this
>> way are the maths functions.
>>
>> My plan is to enhance the CClosure structure with an additional field
>> - that will encode the C function's argument types and the return
>> type.
>>
>
> Assuming that I have a byte to hold extra data for a light C function,
> I want to be able to:
>
> a) Work out what the expected arguments and return value are from this
> extra byte of data - assuming only up to 2-3 arguments are allowed and
> all arguments and return values are primitive types.
>
> b) I need to be able to check that all the actual parameter values on
> the Lua stack have the correct types.
>
> c) Call the C function with appropriate signature.
>
> d) Check that the returned value is the right type.
>
> And I want to do all this without having lots of branchy code using
> if/else conditions.
>
> Vaguely the strategy I have is to be able to map the information in
> the extra byte and the actual types of the parameters to a _vtable_
> that has functions with the right signature. To explain, lets say we
> only support a function with single double argument, returning a
> double. And lets say such a function is denoted by the numeric code 1.
> So then I want to map this 1 + the type of value in Lua stack to the
> vtable location 1 (first function) if valid - else to 0 if invalid.
>
> I don't know if I have been able to explain ... please let me know if
> this is unclear and I will try again.
>
> Regards
> Dibyendu
>

Well, let's see here.

If you support four integer types, two floating-point types, void, and
nothing else, then you can handle no parameters or one parameter and
one return type easily enough, but you can't fit two parameters (that
would need 343 distinct values and you only have 255).

If you require all of the parameters to be of the same type (this
would let you use most math functions) and explicitly encode the
function's arity, then you only need six input data types instead of
seven; you could support up to five parameters this way using a total
of 217 values. This leaves 38 more slots available, which you can use
to encode some common other signatures, such as (void*), (void*,
size_t), and so on. (Since this is C and not C++ you don't have to
worry about encoding the specific type of the pointer.)

You could also support up to three parameters of the same type, or a
void* and up to two parameters of the same type, and that would use
224 values, leaving 31 slots for special-case parameter lists.

If you put some restrictions on available return types (e.g. restrict
the choices to "void", "same as the parameter list", and "pointer")
then you can squeeze out even more options but I don't feel like doing
the math for how many that is, and you might need to use some special
cases for 0-ary functions that return a value anyway.

/s/ Adam