[Pdx-pm] Designing a C library specifically for HLL binding

chromatic chromatic at wgz.org
Thu Oct 30 16:06:03 PDT 2008

On Thursday 30 October 2008 15:13:08 Eric Wilhelm wrote:

> >This makes the HLL binding do a lot more work.
> That's actually part of the plan.  Given that making a perlish API for
> any non-trivial data requires some manipulation of HV's and AV's
> (aka "a lot of work"), and that I have to write everything from a blank
> slate, I was figuring on keeping the shared library rather dumb.

You're not going to avoid the HV/AV problem, unless your HLL can manipulate C 
data structures directly (Parrot can, and Perl 5 can, if you want to use tie 
magic from XS, which I don't).

> >It has to know how
> > much memory to allocate (which can vary from platform to platform),
> The goal there was "none".  The temporary structs are lexically scoped
> by the caller (this is called an "automatic variable"?) and pointers to
> them are passed into the shared functions, so nothing in the shared
> library deals with memory.

That means if the struct size ever changes (or alignment, or padding, or 
compiler, or ... okay, that's about it), the HLL bindings have to change, and 
then you have versioning questions, and that's yucky.

>   // in sharedthingy.h
>   struct pointstruct {
>     float x;
>     float y;
>     float z;
>   };
>   // in Inline::C code:
>   SV* next_polygon(SV* obj) {
>     filedatastruct* fds = (filedatastruct*) SvIV(SvRV(obj));
>     ...
>     HV * hash = newHV();
>     int i;
>     int p;
>     pointstruct * a_point;

There's a crash waiting to happen.  You've just asked C to allocate room a 
pointer on the stack.  That's fine, but it doesn't point to anything, and 
you're about to pass an unintialized pointer to code that presumably will 
dereference it and get garbage values (or, if it *writes* to struct members 
through the pointer, will overwrite other locations in memory that may 
contain other data you cared about).  Instead:

	pointstruct a_point;

>     p = get_polygon_point_count(fds);
>     for(i=0; i<p; i++) {
>       ...
>       get_polygon_point(fds, i, a_point);

... and then:

	get_polygon_point(fds, i, &a_point);

> At least, that's what I have in my head thus far.  Am I correct in my
> reading that there's nothing to malloc/free here outside of what the
> perlapi calls are doing for me?

That's right, as long as you fix the initialization code so that the C 
compiler initializes the right amount of memory (sizeof( pointstruct ) rather 
than sizeof (poinstruct *)).

Like I said though, if sizeof( pointstruct ) ever changes, you'll have to 
recompile this XS against the new headers (for Perl 5 bindings) or regenerate 
the PIR code that builds a pointstruct from the headers and a ManagedStruct 
PMC in Parrot.

If you instead wrote:

	pointstruct *p = new_pointstruct();



... and kept that API the same, and never allowed anyone to access struct 
members directly, you wouldn't have to recompile and you'd be free to 
rearrange and manipulate struct members between versions of your library all 
you want.

> > so you'll end up recompiling the HLL binding every time the shared
> > library changes.
> Assuming that I *want* some part of this to be in XS, you have to do
> that anyway, right?

Only if any of the details the XS rely on change.  If function signatures 
don't change (even if you *add* functions), then you shouldn't have to 
recompile (unless you change compilers or the compilers change their ABIs).

> This would mean that the low-level stuff in the shared library could
> stick to just dealing with the bitwise twiddly stuff, while the binding
> would mostly deal with assembling Perl data structures and error
> handling.

That's generally what you want.

> Now of course this assumes that the interpreter is implemented in C.
> What would something like this mean in parrot?

If the Parrot bindings had to handle anything other than an opaque pointer, I 
would summon an army of righteousness to march on your house (I know where 
you live) and convince you of the error of your ways -- not because Parrot 
can't do it, but because it's 2008, by gum, and I know you can 
spell "encapsulation".

-- c

More information about the Pdx-pm-list mailing list