[gambit-list] is this a bug in ffi?

Álvaro Castro-Castilla alvaro.castro.castilla at gmail.com
Mon Feb 6 17:37:34 EST 2012


Great! It works.

I've made this little variation to allow different scheme-type and c-type
names:

(define-macro
  (import-enum-constants scheme-type c-type . names)
  (define (interval lo hi)
    (if (< lo hi) (cons lo (interval (+ lo 1) hi)) '()))
  (let ((c-type-str (symbol->string c-type))
        (nb-names (length names))
        (wrapper (gensym)))
    `(begin
       (define ,wrapper
         (c-lambda (int)
                   ,scheme-type
                   ,(string-append
                      "static " c-type-str " _tmp_[] = {\n"
                      (apply string-append
                             (map (lambda (i name)
                                    (let ((name-str (symbol->string name)))
                                      (string-append
                                        (if (> i 0) "," "")
                                        name-str)))
                                  (interval 0 nb-names)
                                  names))
                      "};\n"
                      "___ASSIGN_NEW_WITH_INIT(___result_voidstar,"
c-type-str ",_tmp_[___arg1]);\n")))
       ,@(map (lambda (i name)
                `(define ,name (,wrapper ,i)))
              (interval 0 nb-names)
              names))))




On Mon, Feb 6, 2012 at 9:30 PM, Marc Feeley <feeley at iro.umontreal.ca> wrote:

>
> On 2012-02-06, at 1:04 PM, REPLeffect wrote:
>
> > 2012/2/6 Marc Feeley <feeley at iro.umontreal.ca>:
> >>
> >> On 2012-02-06, at 9:59 AM, Álvaro Castro-Castilla wrote:
> >>
> >>> Thank you Marc. Those are all better solutions than my wrapper
> function.
> >>>
> >>> Best regards
> >>>
> >>> Álvaro
> >>
> >> Actually, using a wrapper function is a good idea to reduce code size.
>  Its intricacies can be hidden in a macro which generates the appropriate
> Scheme and C code.  I've written something like this in the past and even
> posted an example to the Gambit mailing list (unfortunately my mail
> system's search function is broken right now so I can't find the message).
> >>
> >> Marc
> >>
> >
> > Marc,
> >
> > Is this the message you're referring to?
> >
> >
> https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-November/005445.html
>
> Yes.  Using that macro as an inspiration, I wrote the following
> import-enum-constants macro which imports a number of enum constants
> without using a wrapper function:
>
> (c-declare #<<end-of-c-declare
>
> #include <stdio.h>
>
> typedef enum { A0, B0, C0, D0, E0, F0, G0, H0, I0, J0,
>               A1, B1, C1, D1, E1, F1, G1, H1, I1, J1,
>               A2, B2, C2, D2, E2, F2, G2, H2, I2, J2,
>               A3, B3, C3, D3, E3, F3, G3, H3, I3, J3,
>               A4, B4, C4, D4, E4, F4, G4, H4, I4, J4,
>               A5, B5, C5, D5, E5, F5, G5, H5, I5, J5,
>               A6, B6, C6, D6, E6, F6, G6, H6, I6, J6,
>               A7, B7, C7, D7, E7, F7, G7, H7, I7, J7,
>               A8, B8, C8, D8, E8, F8, G8, H8, I8, J8,
>               A9, B9, C9, D9, E9, F9, G9, H9, I9, J9 } foo;
>
> void f(foo x) { printf("%d\n", x); }
>
> end-of-c-declare
> )
>
>
> ;;;---------------------------------------------------------------------------
>
> (define-macro (import-enum-constants type . names)
>  (let ((type-str (symbol->string type)))
>    `(begin
>       ,@(map (lambda (name)
>                (let ((name-str (symbol->string name)))
>                  `(define ,name
>                     ((c-lambda ()
>                                ,type
>                                ,(string-append
>
>  "___ASSIGN_NEW_WITH_INIT(___result_voidstar,"
>                                  type-str
>                                  ","
>                                  name-str
>                                  ");"))))))
>              names))))
>
>
> ;;;---------------------------------------------------------------------------
>
> (c-define-type foo "foo")
>
> (import-enum-constants foo
>  A0 B0 C0 D0 E0 F0 G0 H0 I0 J0
>  A1 B1 C1 D1 E1 F1 G1 H1 I1 J1
>  A2 B2 C2 D2 E2 F2 G2 H2 I2 J2
>  A3 B3 C3 D3 E3 F3 G3 H3 I3 J3
>  A4 B4 C4 D4 E4 F4 G4 H4 I4 J4
>  A5 B5 C5 D5 E5 F5 G5 H5 I5 J5
>  A6 B6 C6 D6 E6 F6 G6 H6 I6 J6
>  A7 B7 C7 D7 E7 F7 G7 H7 I7 J7
>  A8 B8 C8 D8 E8 F8 G8 H8 I8 J8
>  A9 B9 C9 D9 E9 F9 G9 H9 I9 J9
> )
>
> (define f (c-lambda (foo) void "f"))
>
> (f A0)
> (f F6)
> (f J9)
>
>
> When a wrapper function is used, the macro can be implemented like this:
>
>
> ;;;---------------------------------------------------------------------------
>
> (define-macro (import-enum-constants type . names)
>
>  (define (interval lo hi)
>    (if (< lo hi) (cons lo (interval (+ lo 1) hi)) '()))
>
>  (let ((type-str (symbol->string type))
>        (nb-names (length names))
>        (wrapper (gensym)))
>    `(begin
>       (define ,wrapper
>         (c-lambda (int)
>                   ,type
>                   ,(string-append
>                     "static " type-str " _tmp_[] = {\n"
>                     (apply string-append
>                            (map (lambda (i name)
>                                   (let ((name-str (symbol->string name)))
>                                     (string-append
>                                      (if (> i 0) "," "")
>                                      name-str)))
>                                 (interval 0 nb-names)
>                                 names))
>                     "};\n"
>                     "___ASSIGN_NEW_WITH_INIT(___result_voidstar," type-str
> ",_tmp_[___arg1]);\n")))
>       ,@(map (lambda (i name)
>                `(define ,name (,wrapper ,i)))
>              (interval 0 nb-names)
>              names))))
>
>
> ;;;---------------------------------------------------------------------------
>
> The version with the wrapper function is much more compact.  On Mac OS X
> with LLVM gcc the first version compiles to a 80kb file (roughly 700 bytes
> of machine code per enum constant that is imported), and the version with a
> wrapper function compiles to a 20kb file (roughly a factor of 5 times more
> compact).
>
> Marc
>
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20120206/6e7077ab/attachment.htm>


More information about the Gambit-list mailing list