Adding modifiers to NCI
Allison Randal
allison at parrot.org
Sat Dec 27 04:12:00 UTC 2008
chromatic wrote:
>
>> Okay, quick pass conversion:
I just took a copy of the list of NCI syntax in src/call_list.txt. The
draft NCI PDD has the same set of signature types. I don't see a more
complete documentation of NCI signatures anywhere. So, if there's
anything missing from the current NCI syntax, please add it.
When I say "(same)" I mean "no change to existing NCI signature syntax".
I'm also not making any changes to the existing NCI semantics here.
>> # INT register stuff
>> # I (same) - INTVAL
>
> Useless for anything other than calling existing Parrot functions, unless you
> know that Parrot's INTVAL maps directly onto some sort of integer in the
> shared library -- and that's only valid for libparrots which share the same
> compile-time configuration on similar architectures.
Don't forget, NCI isn't only used to interface with external libraries,
it's also used internally, which is why it represents the Parrot types,
the interpreter arg, slurpy arrays, etc.
>> # c (C) - char
>
> Signed? Unsigned?
>
>> # s (H) - short
>
> Signed? Unsigned?
>
>> # i (T) - int
>
> How many bits? 8? 16? 32? 64? 128? Signed? Unsigned?
>
>> # l (L) - long
>
> How many bits? Signed? Unsigned? How about long long?
Modifier 'u' for unsigned, and numeric modifier for bits ('32' for 32
bits, rather than, '4' for 32 bits, to keep similarity to C types).
Short, long, and long long could also be modifiers, instead of separate
types. So:
I - INTVAL
Ih - short
It - int
Il - long
Ill - long long
>> # NUM register stuff
>> # N (same) - FLOATVAL
>
> Again, useful only for calling existing Parrot functions, and functionally
> useless for calling non-Parrot shared libraries. (It *may* work in some
> cases, but parrotport.pod will rightly warn against it.)
See above (internal use).
>> # f (F) - float
>> # d (D) - double
>
> How many bits? Signed or unsigned?
See above (modifiers).
>> # STR register stuff
>> # S (same) - pointer to a STRING-register
>
> Useful only for calling existing Parrot functions.
See above (internal use)
>> # t (C*) - character string (0-terminated)
>
> Allocated by whom? What's its lifespan? Is there an associated free()
> function?
>
> For example, you set the context of an HTTP request through libcurl by passing
> C strings to configuration functions. These strings must persist through the
> entirety of the request. If you (or the thunking layer) frees the C strings
> prematurely, your program will crash.
See above (same semantics).
>> # Buffers are not valid return parameters,
>> # use 'p' when the native function returns a pointer value
>> # b (V*) - void *
>> # B (V**) - void **
>
>> # PMC register stuff
>> # P (same) - pointer to a PMC-register
>
> Useful only for calling existing Parrot functions.
>
>> # O ('Pi' for *P*MC *i*nvocant) - pointer to PMC-register (object)
>
> Useful only for calling existing Parrot methods.
See above (internal use).
>> # p (A) - data pointer from PMC (on store into a new UnManagedStruct
>> PMC) [Note: generic pointer type, i.e. "pointer to *A*nything" ]
>
> How big are pointers on this platform?
See above (same semantics).
>> # 2 (H*) - pointer to short
>> # 3 (T*) - pointer to int
>> # 4 (L*) - pointer to long
>
> How many bits wide? Signed or not?
See above (modifiers).
>> # void stuff
>> # v (V) - void
>>
>> # special stuff
>> # 0 (Z) - insert a NULL (pointer) - doesn't consume a register
>> # J (same) - Parrot_Interp param
>
> Useful
>
>> # @ ('Ps' for *P*MC *s*lurpy) - slurpy array
>
> C doesn't have slurpy arrays. The closest thing it has are varargs, and you
> have to treat these very, very differently -- on some platforms you may be
> able to get by by marshalling a list of arguments in to a va_list and passing
> the resulting pointer directly, but I'm not sure how well that works across
> compilers, platforms, and C ABIs.
See above (internal use).
> I also don't see any examples of out parameters.
Toss me some examples and I'll do a first pass at fitting them into the
hypothetical new syntax.
chromatic wrote:
>> For the sake of unifying the parsers of signatures of two completely different
>> calling conventions with separate goals, a C signature of a form well-
>> understood for almost 40 years as:
>>
>> int squash_coords_to_int(uint16 x, uint16 y);
>>
>> .. becomes somewhat less obvious:
>>
>> Tu2 Tu2 -> T1
Well, the NCI version isn't particularly obvious either. I suppose we
could go to "int uint16, uint16" or some such, but the short signature
strings seem to have worked well.
On the whole, the definition of "usability" isn't "intuitively obvious"
because nothing is ever intuitively obvious to the outsider. What we're
looking for is a consistent system, and to make it easier to learn than
what we have now.
>> .. and we tell all of the people writing PCC signature strings to ignore all
>> of the type sizes and signedness modifiers and all of the people writing NCI
>> signature strings to *know for certain* how big an INTVAL is on every
>> platform, because if they accidentally leave off a number they'll get weird
>> crashes and ask me to spend my day poking at code with GDB,
That distinction has to do with what you're calling, not what syntax
you're using. The same distinction exists now for NCI used internally
and NCI used externally.
>> oh and also they
>> should just ignore all of the Parrot specific signature types which mean
>> nothing to shared libraries which are not libparrot and which do not support
>> named, slurpy, and flattening parameters in their calling conventions.
5 characters to ignore isn't terribly painful.
>> Wasn't one goal of defining and using INTVAL and FLOATVAL and STRING within
>> the Parrot API to avoid the explosion of datatypes which C has suffered
>> because it doesn't have a type system and encourages people to agonize over
>> the position of each last byte?
Yes, but we're defining a way to interface to C functions, so we're
hampered by its pedantic nature.
Allison
More information about the parrot-dev
mailing list