Hi guys!

I've been looking at chicken-bind's way of working with C-structs for a
while now, and I'm in the works of something I think will be useful. I want
to have chicken-bind generate code for struct-by-values. Thanks to all who
helped me out in this tricky process!

*Allocating memory for new structs*
Chicken-bind needs to allocate structs:
1. In its "make-<struct>" construct
2. When a function returns a struct by value
3. When a struct has a struct field (aka nested structs, effectively a
struct-by-value return type)

I have decided to use make-blob to allocate memory in all cases because
it's easy and seems to have very good performance. I haven't looked at the
code, but I believe make-blob allocates on the stack whenever it can.

I have made a new version of chicken-bind's make-<struct> which now uses
make-blob, replacing the old C_malloc. Please take a peek at
https://github.com/kristianlm/chicken-bind/commit/f7dde10bdb40aa00ae776f23570aa1001ddde26d.
I like the "set-point!" naming convention but I'm open to suggestions of
course.

*Struct-by-value return type =? locative*
You typically have code like this:
struct point {float x,y};
float distance (point *a, point *b);

To use distance, you wanna do something like:
(distance (make-point 1 2) (make-point 2 3))

This means that all struct-bindings should return types compatible with
pointers so they can be used seamlessly on the other functions. The only
way I have found to achieve this is to return locatives. It's not ideal
because you lose type information at runtime. Any ideas on how to keep this
without forcing the user to convert? Do tagged locatives exist, like tagged
pointers?

*Struct by value return types*

This is my proposal:
$ echo "struct point getPoint();" | chicken-bind  - -o -
(begin
  (begin
    (begin
      (define getPoint/overwrite!
        (foreign-lambda*
          void
          (((c-pointer (struct "point")) dest))
          "*dest=(getPoint());"))
      (define (getPoint)
        (let ((dest (location
                      (make-blob (foreign-value "sizeof(struct point)"
int)))))
          (getPoint/overwrite! dest)
          dest)))))

I wish to export the overwrite-version (and set-point! above) because I
assume it can be useful in tight loops where you only need to allocate
once. Any objections? And what might be a better name than /overwrite!?

*Compatibility*
The new patches should not change any behavior except that make-<struct>
now returns a locative instead of a c-pointer.

Looking forward to hear your thoughts and get this patch out there!
Kris
_______________________________________________
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to