Re: [Chicken-users] patch for chicken-bind!

2012-10-21 Thread Felix
Wow! Cool stuff - I'll look at that.

 
 It would be great if this were reviewed and made part of the official
 chicken-bind.

Sure - I'll get back to you.


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] patch for chicken-bind

2012-07-09 Thread Felix
Hello!


Bind 1.0 with support for passing structs by value is now
available. Many thanks, Kristian, for contributing this!


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] patch for chicken-bind

2012-06-26 Thread Kristian Lein-Mathisen
Hi Jim,

I really appreciate you looking over this!

However, I think that it may be more practical to return locatives because
they are interchangeable with c-pointers. This makes them easier to pass
around with other parts of the foreign-code.

If we remove (locative ...) and use scheme-pointer, nested struct getters
and struct return-types in scheme would return blobs instead of locatives.
Let's check out this (untested) example of what I think would be typical
usage:

(bind 
struct point  { float x, y; };
struct circle { struct point origin; float radius; };
float distance(struct point, struct point);)

(define c1 (make-circle (make-point 10 10) 0.5))
(define c2 (make-circle (make-point 1 1) 0.2))

;; circle-origin is a nested-struct getter.
;; if it returns blobs, we must do:
(distance (make-locative (circle-origin c1)) (make-locative (circle-origin
c2)))
;; if it returns locative:
(distance (circle-origin c1) (circle-origin c2))

I was not aware of the performance penalty introduced by (locative blob).
Would it be beneficial to return the locative of the blob as a last step,
and use scheme-pointer in the intermediate, destination-operand, step?

Thank you,
K.



On Mon, Jun 25, 2012 at 10:18 PM, Jim Ursetto zbignie...@gmail.com wrote:

 Tip: if you use scheme-pointer instead of c-pointer, you can omit the
 locative).  E.g. (make-blob size) instead of (location (make-blob size)).
  This will be faster.

 On Jun 25, 2012, at 5:27 PM, Kristian Lein-Mathisen wrote:


 Hi guys!

 It's me again, still going on about struct-by-value in 
 chicken-bindhttp://wiki.call-cc.org/eggref/4/bind.
 This time I think I may have codehttps://github.com/kristianlm/chicken-bind 
 worthy
 of entering the official repo. The patches add three new features:

1. Struct-by-value in arguments
2. Struct-by-value return types
3. Nested structs (practically same as 2)

 Functions on the Scheme-side interface all functions using pointers or
 locatives, regardless of their original signature.

 You can have a look at my 10 commits that make up the patch on 
 githubhttps://github.com/kristianlm/chicken-bind/commits/. I
 tried to be descriptive in my commit messages. Please let me know of your
 thoughts and concerns. If nothing pops up, I'll pass it on Felix
 (chicken-bind maintainer) for review.

 *Motivation*
 While most C libraries pass structs by reference, both physics engines
 I've come across, Chipmunk and Box2D, pass small structs like 2d-vectors
 around by value everywhere. This patch made my life easier.

 *Code samples*
 Let's walk through the new foreign-lambda snippets that it generates. I
 use the point struct in my examples, pretend it's some 2d/3d vector of
 floats. First, let's look at passing a struct by reference:

 *1. Struct arguments*
 [klm@kth chicken-bind]$ echo float length(struct point*) | chicken-bind
 - -o -
 (begin
   (begin
 (define length
   (foreign-lambda float length (c-pointer (struct point))
 *
 *
 Nothing's changed there, my patch will kick in when you pass structs by
 value. The patch checks if any arguments are non-pointer struct arguments,
 and if there are any, it wraps the call in a foreign-lambda* with all
 struct-by-val arguments to c-pointer variant which are dereferenced in C:

 [klm@kth chicken-bind]$ echo float length(struct point) | chicken-bind
 - -o -
 (begin
   (begin
 (define length
   (foreign-lambda*
 float
 (((c-pointer (struct point)) a0))
 C_return(length(*a0));

 *2. Struct return-types*
 Struct return-types are a little trickier and are split into two
 functions. One will call the original function, storing the result in a
 additional destination operand. The other will allocate memory to use as
 this destination and calls the first:

 [klm@kth chicken-bind]$ echo struct point intersection(struct line*,
 struct line) | chicken-bind  - -o -
 (begin
   (begin
 (begin
   (define intersection/overwrite!
 (foreign-lambda*
   void
   (((c-pointer (struct point)) dest)
((c-pointer (struct line)) a0)
((c-pointer (struct line)) a1))
   *dest=(intersection(a0,*a1));))
   (define (intersection a0 a1)
 (let ((dest (location
   (make-blob (foreign-value sizeof(struct point)
 int)
   (intersection/overwrite! dest a0 a1)
   dest)

 As shown above, you can mix and match struct value-passing and
 pointer-passing in the arguments.

 *3. Nested structs*
 Nested structs face the same problem as struct return-types, but
 unfortunately I haven't looked into uniting the codebase. However, it
 follows the same destination-method as above:

 [klm@kth chicken-bind]$ echo struct circle { struct point origin; float
 radius ; } | chicken-bind - -o -
 (begin
   (define circle-origin
 (lambda (s)
   (let ((blob (location
 (make-blob (foreign-value sizeof(struct point)
 int
 

[Chicken-users] patch for chicken-bind

2012-06-25 Thread Kristian Lein-Mathisen
Hi guys!

It's me again, still going on about struct-by-value in
chicken-bindhttp://wiki.call-cc.org/eggref/4/bind.
This time I think I may have
codehttps://github.com/kristianlm/chicken-bind worthy
of entering the official repo. The patches add three new features:

   1. Struct-by-value in arguments
   2. Struct-by-value return types
   3. Nested structs (practically same as 2)

Functions on the Scheme-side interface all functions using pointers or
locatives, regardless of their original signature.

You can have a look at my 10 commits that make up the patch on
githubhttps://github.com/kristianlm/chicken-bind/commits/. I
tried to be descriptive in my commit messages. Please let me know of your
thoughts and concerns. If nothing pops up, I'll pass it on Felix
(chicken-bind maintainer) for review.

*Motivation*
While most C libraries pass structs by reference, both physics engines I've
come across, Chipmunk and Box2D, pass small structs like 2d-vectors around
by value everywhere. This patch made my life easier.

*Code samples*
Let's walk through the new foreign-lambda snippets that it generates. I use
the point struct in my examples, pretend it's some 2d/3d vector of
floats. First, let's look at passing a struct by reference:

*1. Struct arguments*
[klm@kth chicken-bind]$ echo float length(struct point*) | chicken-bind -
-o -
(begin
  (begin
(define length
  (foreign-lambda float length (c-pointer (struct point))
*
*
Nothing's changed there, my patch will kick in when you pass structs by
value. The patch checks if any arguments are non-pointer struct arguments,
and if there are any, it wraps the call in a foreign-lambda* with all
struct-by-val arguments to c-pointer variant which are dereferenced in C:

[klm@kth chicken-bind]$ echo float length(struct point) | chicken-bind -
-o -
(begin
  (begin
(define length
  (foreign-lambda*
float
(((c-pointer (struct point)) a0))
C_return(length(*a0));

*2. Struct return-types*
Struct return-types are a little trickier and are split into two functions.
One will call the original function, storing the result in a additional
destination operand. The other will allocate memory to use as this
destination and calls the first:

[klm@kth chicken-bind]$ echo struct point intersection(struct line*,
struct line) | chicken-bind  - -o -
(begin
  (begin
(begin
  (define intersection/overwrite!
(foreign-lambda*
  void
  (((c-pointer (struct point)) dest)
   ((c-pointer (struct line)) a0)
   ((c-pointer (struct line)) a1))
  *dest=(intersection(a0,*a1));))
  (define (intersection a0 a1)
(let ((dest (location
  (make-blob (foreign-value sizeof(struct point)
int)
  (intersection/overwrite! dest a0 a1)
  dest)

As shown above, you can mix and match struct value-passing and
pointer-passing in the arguments.

*3. Nested structs*
Nested structs face the same problem as struct return-types, but
unfortunately I haven't looked into uniting the codebase. However, it
follows the same destination-method as above:

[klm@kth chicken-bind]$ echo struct circle { struct point origin; float
radius ; } | chicken-bind - -o -
(begin
  (define circle-origin
(lambda (s)
  (let ((blob (location
(make-blob (foreign-value sizeof(struct point) int
(copy-struct!
  (foreign-lambda*
void
(((c-pointer (struct point)) _dest)
 ((c-pointer (struct circle)) s))
*_dest = s-origin;)))
(copy-struct! blob s)
blob)))
  (define circle-radius
(foreign-lambda*
  float
  (((c-pointer (struct circle)) s))
  return(s-radius);))
  (define make-circle
(foreign-lambda*
  (c-pointer (struct circle))
  (((c-pointer (struct point)) origin) (float radius))
  struct circle *tmp_ = (struct circle *)C_malloc(sizeof(struct
circle));\ntmp_-origin = *origin;\n\ntmp_-radius =
radius;\n\nC_return(tmp_);)))


*Caveats*
Struct-by-value return types and nested-struct getters return locatives.
This is nice because it will be like any other scheme-object and doesn't
need to be explicitly freed. Be careful though, locatives will be moved
around by the GC and thus pointers to it are not permanent.

A also added a small
test-suitehttps://github.com/kristianlm/chicken-bind/blob/master/tests/struct-passing-tests.scmfor
these features.

Cheers fellow Chickeners,
- Kris
___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users