[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: A coding challenge: was: luaD_precall() question
- From: Coda Highland <chighland@...>
- Date: Sun, 2 Jul 2017 11:21:37 -0500
On Sun, Jul 2, 2017 at 10:29 AM, Coda Highland <chighland@gmail.com> wrote:
> On Sun, Jul 2, 2017 at 6:07 AM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
>> Hi,
>>
>> On 2 July 2017 at 01:50, Coda Highland <chighland@gmail.com> wrote:
>>> 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.
>>>
>>
>> Indeed - using a single byte allows me to encode 255 signatures. The
>> challenge is more how to map the signature and the actual types to a
>> function pointer without gong through a lot of branchy type checks. So
>> I want a hashing function that is as follows:
>>
>> map(function_signature_code, actual_parameter_types[]) -> function pointer.
>>
>> The idea is that good values map to appropriate function pointer that
>> can be invoked. Bad values (i.e. wrong parameters on Lua stack) - map
>> to a special error function.
>>
>> I want to do this mapping almost as a lookup table ... but the problem
>> with a lookup table is that it would have to handle all possible
>> values and have to be multi-dimensional. But conceptually this is what
>> I would like to do.
>>
>> Thanks and Regards
>> Dibyendu
>>
>
> My point (which I failed to make clear, my fault, I got carried away
> in speculation without giving the actual concrete idea I had) is that
> you can encode the stuff numerically without using too many branches.
>
> if arity == 0 then
> signature = 1 + returnType + 42
> elseif arity < 4 and not hasVoidPointer then
> signature = 1 + returnType + (parameterType * 7) + ((arity - 1) * 42)
> elseif arity < 3 then
> signature = 1 + returnType + (parameterType * 7) + ((arity + 3) * 42)
> else
> -- now you can use a small sparse lookup table for the rest of the exceptions
> end
I make no warranty about the specific constants in this code. >.> I
know I screwed at least one of them up, but you get the idea.
/s/ Adam