unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Re: Passing C pointers through guile
       [not found] <cmu-lmtpd-29205-1215446748-1@mail-imap1.uio.no>
@ 2008-07-09 16:50 ` Kjetil S. Matheussen
  2008-07-09 18:32   ` Kjetil S. Matheussen
  2008-07-09 19:35   ` Ludovic Courtès
  0 siblings, 2 replies; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-09 16:50 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1707 bytes --]


Ludovic Court?s:
> scenes.
> 
> > I agree with Maciek that it would at least be mind-comforting to have
> > functions like scm_to_ptr/etc, although not strictly necessary,
> > since using integers works just fine.
> 
> `scm_{to,from}_uintptr ()' could be handy (patches welcome!).
> 

I gave it a try. Unfortunately, I was completely unable to create
the configure file right now, so the patch is against 1.8.5 (sorry
if this creats trouble against git repository), and
it's also untested, since I couldn't build configure. However,
the patches are trivial, so I think they work anyway. (crossing fingers)

The only thing I'm not too sure about is whether
the new SCM_I_GSC_T_UINTPTR type in configure.in will actually be
optional or not. I just copied the checking code for the optional
SCM_I_GSC_T_UINT64 type though:


"
### Optional type scm_t_uintptr
if test "$scm_stdint_has_uintptr"; then
  SCM_I_GSC_T_UINTPTR='"uintptr_t"'
  SCM_I_GSC_NEEDS_STDINT_H=1
elif test "$scm_inttypes_has_uintptr"; then
  SCM_I_GSC_T_UINTPTR='"uintptr_t"'
  SCM_I_GSC_NEEDS_INTTYPES_H=1
else
  AC_MSG_ERROR([Can't find appropriate type for scm_t_uintptr.])
fi
AC_SUBST([SCM_I_GSC_T_UINTPTR])
"



Patch for configure.in:
http://www.notam02.no/~kjetism/configure.in.diff

Patch for libguile/Makefile.in, libguile/__scm.h, 
libguile/gen-scmconfig.c, libguile/gen-scmconfig.h.in and 
libguile/numbers.c:
http://www.notam02.no/~kjetism/libguile.diff

The two patches are also attached.


> That said, using a Scheme integer to represent a pointer wouldn't be
> efficient (pointers would likely translate to bignums).
> 

I think cleaner code would usually be more important in this case,
but at least there will be a choice.

[-- Attachment #2: Type: TEXT/PLAIN, Size: 4162 bytes --]

diff -ur libguile_org/Makefile.in libguile/Makefile.in
--- libguile_org/Makefile.in	2008-05-07 20:08:34.000000000 +0200
+++ libguile/Makefile.in	2008-07-09 17:59:52.000000000 +0200
@@ -298,6 +298,7 @@
 SCM_I_GSC_T_UINT64 = @SCM_I_GSC_T_UINT64@
 SCM_I_GSC_T_UINT8 = @SCM_I_GSC_T_UINT8@
 SCM_I_GSC_T_UINTMAX = @SCM_I_GSC_T_UINTMAX@
+SCM_I_GSC_T_UINTPTR = @SCM_I_GSC_T_UINTPTR@
 SCM_I_GSC_USE_NULL_THREADS = @SCM_I_GSC_USE_NULL_THREADS@
 SCM_I_GSC_USE_PTHREAD_THREADS = @SCM_I_GSC_USE_PTHREAD_THREADS@
 SED = @SED@
diff -ur libguile_org/__scm.h libguile/__scm.h
--- libguile_org/__scm.h	2008-04-07 23:30:03.000000000 +0200
+++ libguile/__scm.h	2008-07-09 18:27:57.000000000 +0200
@@ -365,6 +365,12 @@
 #define SCM_T_INT64_MAX   SCM_I_TYPE_MAX(scm_t_int64,SCM_T_UINT64_MAX)
 #endif
 
+#if SCM_HAVE_T_UINTPTR
+#define SCM_T_UINTPTR_MAX  SCM_I_UTYPE_MAX(scm_t_uintptr)
+#define SCM_T_UINTPTR_MIN   SCM_I_TYPE_MIN(scm_t_uintptr,SCM_T_UINTPTR_MAX)
+#define SCM_T_UINTPTR_MAX   SCM_I_TYPE_MAX(scm_t_uintptr,SCM_T_UINTPTR_MAX)
+#endif
+
 #if SCM_SIZEOF_LONG_LONG
 #define SCM_I_ULLONG_MAX  SCM_I_UTYPE_MAX(unsigned long long)
 #define SCM_I_LLONG_MIN   SCM_I_TYPE_MIN(long long,SCM_I_ULLONG_MAX)
diff -ur libguile_org/gen-scmconfig.c libguile/gen-scmconfig.c
--- libguile_org/gen-scmconfig.c	2008-04-24 19:35:57.000000000 +0200
+++ libguile/gen-scmconfig.c	2008-07-09 18:24:22.000000000 +0200
@@ -339,6 +339,19 @@
     pf ("#define SCM_HAVE_T_UINT64 0 /* 0 or 1 */\n");
 
   pf ("\n");
+  pf ("/* unsigned integer large enough to hold pointer -- if available SCM_HAVE_T_UINTPTR will\n"
+      "   be 1 and scm_t_uintptr will be a suitable type, otherwise\n"
+      "   SCM_HAVE_T_UINTPTR will be 0. */\n");
+  if (SCM_I_GSC_T_UINTPTR)
+  {
+    pf ("#define SCM_HAVE_T_UINTPTR 1 /* 0 or 1 */\n");
+    pf ("typedef %s scm_t_intptr;\n", SCM_I_GSC_T_UINTPTR);
+  }
+  else
+    pf ("#define SCM_HAVE_T_UINTPTR 0 /* 0 or 1 */\n");
+
+
+  pf ("\n");
   pf ("/* scm_t_ptrdiff_t and size, always defined -- defined to long if\n"
       "   platform doesn't have ptrdiff_t. */\n");
   pf ("typedef %s scm_t_ptrdiff;\n", SCM_I_GSC_T_PTRDIFF);
@@ -353,6 +366,7 @@
   pf ("/* Size of uintptr_t or 0 if not available */\n");
   pf ("#define SCM_SIZEOF_UINTPTR_T %d\n", SIZEOF_UINTPTR_T);
 
+
   pf ("\n");
   pf ("/* same as POSIX \"struct timespec\" -- always defined */\n");
 #ifdef HAVE_STRUCT_TIMESPEC
diff -ur libguile_org/gen-scmconfig.h.in libguile/gen-scmconfig.h.in
--- libguile_org/gen-scmconfig.h.in	2008-04-07 23:30:03.000000000 +0200
+++ libguile/gen-scmconfig.h.in	2008-07-09 17:59:00.000000000 +0200
@@ -25,6 +25,7 @@
 #define SCM_I_GSC_T_UINT64 @SCM_I_GSC_T_UINT64@
 #define SCM_I_GSC_T_INTMAX @SCM_I_GSC_T_INTMAX@
 #define SCM_I_GSC_T_UINTMAX @SCM_I_GSC_T_UINTMAX@
+#define SCM_I_GSC_T_UINTPTR @SCM_I_GSC_T_UINTPTR@
 #define SCM_I_GSC_T_PTRDIFF @SCM_I_GSC_T_PTRDIFF@
 #define SCM_I_GSC_USE_PTHREAD_THREADS @SCM_I_GSC_USE_PTHREAD_THREADS@
 #define SCM_I_GSC_USE_NULL_THREADS @SCM_I_GSC_USE_NULL_THREADS@
diff -ur libguile_org/numbers.c libguile/numbers.c
--- libguile_org/numbers.c	2008-05-07 17:29:55.000000000 +0200
+++ libguile/numbers.c	2008-07-09 18:25:29.000000000 +0200
@@ -5863,6 +5863,19 @@
 
 #endif
 
+
+#if SCM_HAVE_T_UINTPTR
+
+#define TYPE                     scm_t_uintptr
+#define TYPE_MIN                 0
+#define TYPE_MAX                 SCM_T_UINTPTR_MAX
+#define SIZEOF_TYPE              8
+#define SCM_TO_TYPE_PROTO(arg)   scm_to_uintptr (arg)
+#define SCM_FROM_TYPE_PROTO(arg) scm_from_uintptr (arg)
+#include "libguile/conv-uinteger.i.c"
+
+#endif
+
 void
 scm_to_mpz (SCM val, mpz_t rop)
 {
diff -ur libguile_org/numbers.h libguile/numbers.h
--- libguile_org/numbers.h	2008-04-07 23:30:03.000000000 +0200
+++ libguile/numbers.h	2008-07-09 18:31:06.000000000 +0200
@@ -331,6 +331,13 @@
 
 #endif
 
+#if SCM_HAVE_T_UINTPTR
+
+SCM_API scm_t_uintptr scm_to_uintptr    (SCM x);
+SCM_API SCM           scm_from_uintptr  (scm_t_uintptr x);
+
+#endif
+
 SCM_API void scm_to_mpz (SCM x, mpz_t rop);
 SCM_API SCM  scm_from_mpz (mpz_t rop);
 

[-- Attachment #3: Type: TEXT/PLAIN, Size: 2069 bytes --]

--- configure.in.org	2008-07-09 18:32:53.000000000 +0200
+++ configure.in	2008-07-09 18:46:38.000000000 +0200
@@ -352,6 +352,7 @@
    AC_CHECK_TYPE([uint32_t],[scm_stdint_has_uint32=1],,[#include <stdint.h>])
    AC_CHECK_TYPE([int64_t],[scm_stdint_has_int64=1],,[#include <stdint.h>])
    AC_CHECK_TYPE([uint64_t],[scm_stdint_has_uint64=1],,[#include <stdint.h>])
+   AC_CHECK_TYPE([uintptr_t],[scm_stdint_has_uintptr=1],,[#include <stdint.h>])
    AC_CHECK_TYPE([intmax_t],[scm_stdint_has_intmax=1],,[#include <stdint.h>])
    AC_CHECK_TYPE([uintmax_t],[scm_stdint_has_uintmax=1],,[#include <stdint.h>])
 fi
@@ -367,6 +368,7 @@
 unset ac_cv_type_uint32_t
 unset ac_cv_type_int64_t
 unset ac_cv_type_uint64_t
+unset ac_cv_type_uintptr_t
 unset ac_cv_type_intmax_t
 unset ac_cv_type_uintmax_t
 
@@ -380,6 +382,7 @@
   AC_CHECK_TYPE([uint32_t],[scm_inttypes_has_uint32=1],,[#include <inttypes.h>])
   AC_CHECK_TYPE([int64_t],[scm_inttypes_has_int64=1],,[#include <inttypes.h>])
   AC_CHECK_TYPE([uint64_t],[scm_inttypes_has_uint64=1],,[#include <inttypes.h>])
+  AC_CHECK_TYPE([uintptr_t],[scm_inttypes_has_uintptr=1],,[#include <inttypes.h>])
   AC_CHECK_TYPE([intmax_t],[scm_inttypes_has_intmax=1],,[#include <inttypes.h>])
   AC_CHECK_TYPE([uintmax_t],[scm_inttypes_has_uintmax=1],,[#include <inttypes.h>])
 fi
@@ -532,6 +535,20 @@
 fi
 AC_SUBST([SCM_I_GSC_T_UINT64])
 
+
+### Optional type scm_t_uintptr
+if test "$scm_stdint_has_uintptr"; then
+  SCM_I_GSC_T_UINTPTR='"uintptr_t"'
+  SCM_I_GSC_NEEDS_STDINT_H=1
+elif test "$scm_inttypes_has_uintptr"; then
+  SCM_I_GSC_T_UINTPTR='"uintptr_t"'
+  SCM_I_GSC_NEEDS_INTTYPES_H=1
+else
+  AC_MSG_ERROR([Can't find appropriate type for scm_t_uintptr.])
+fi
+AC_SUBST([SCM_I_GSC_T_UINTPTR])
+
+
 ### Required type scm_t_intmax
 ###
 ### We try 'intmax_t', '__int64', 'long long' in this order.  When
@@ -553,6 +570,7 @@
 fi
 AC_SUBST([SCM_I_GSC_T_INTMAX])
 
+
 ### Required type scm_t_uintmax
 ###
 ### We try 'uintmax_t', 'unsigned __int64', 'unsigned long long' in

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-09 16:50 ` Kjetil S. Matheussen
@ 2008-07-09 18:32   ` Kjetil S. Matheussen
  2008-07-09 19:37     ` Ludovic Courtès
  2008-07-09 19:35   ` Ludovic Courtès
  1 sibling, 1 reply; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-09 18:32 UTC (permalink / raw)
  To: Kjetil S. Matheussen; +Cc: guile-devel

On Wed, 9 Jul 2008, Kjetil S. Matheussen wrote:

> 
> Ludovic Court?s:
> > scenes.
> > 
> > > I agree with Maciek that it would at least be mind-comforting to have
> > > functions like scm_to_ptr/etc, although not strictly necessary,
> > > since using integers works just fine.
> > 
> > `scm_{to,from}_uintptr ()' could be handy (patches welcome!).
> > 
> 
> I gave it a try. Unfortunately, I was completely unable to create
> the configure file right now, so the patch is against 1.8.5 (sorry
> if this creats trouble against git repository), and
> it's also untested, since I couldn't build configure. However,
> the patches are trivial, so I think they work anyway. (crossing fingers)
> 

Stupid me. I could of course compile 1.8.5 since I have autoconf 1.60.
And by doing that, I found three trivial typos. New version of
http://www.notam02.no/~kjetism/libguile.diff is uploaded.

However, I can't get it to work...:

"
kjetil@ttleush ~/guile-1.8.5 $ CFLAGS=-O3 ./configure --prefix=/home/kjetil/guile-1.8.5 --without-threads
...
kjetil@ttleush ~/guile-1.8.5 $ make && make install
...
kjetil@ttleush ~/guile-1.8.5 $ more test.c
#include <libguile.h>
#include <libguile/numbers.h>

int main(){
  SCM t=scm_from_uintptr((scm_t_uintptr)&main);
  scm_t_uintptr m=scm_to_uintptr(t);
  printf("main: %p, p: %x\n",&main,m);
  return 0;
}

kjetil@ttleush ~/guile-1.8.5 $ gcc -Iinclude/ -Llib lib/libguile.a test.c
/tmp/ccMcEAxd.o: In function `main':
test.c:(.text+0x1b): undefined reference to `scm_from_uintptr'
test.c:(.text+0x2c): undefined reference to `scm_to_uintptr'
collect2: ld returned 1 exit status
kjetil@ttleush ~/guile-1.8.5 $
"

Any idea why?





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-09 16:50 ` Kjetil S. Matheussen
  2008-07-09 18:32   ` Kjetil S. Matheussen
@ 2008-07-09 19:35   ` Ludovic Courtès
  1 sibling, 0 replies; 13+ messages in thread
From: Ludovic Courtès @ 2008-07-09 19:35 UTC (permalink / raw)
  To: guile-devel

Hi,

"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:

> I gave it a try. Unfortunately, I was completely unable to create
> the configure file right now, so the patch is against 1.8.5 (sorry
> if this creats trouble against git repository), and
> it's also untested, since I couldn't build configure.

You have to make sure you are on the `branch_release-1-8', and then
"autoreconf -vfi" should suffice to produce everything.  Autoconf 2.61,
Automake 1.10 and Libtool 1.5.26 is all you need.

> The only thing I'm not too sure about is whether
> the new SCM_I_GSC_T_UINTPTR type in configure.in will actually be
> optional or not. I just copied the checking code for the optional
> SCM_I_GSC_T_UINT64 type though:

I think this type shouldn't be optional, because there will always be a
pointer-sized integer type (whereas there could be platform without
64-bit integers).

>> That said, using a Scheme integer to represent a pointer wouldn't be
>> efficient (pointers would likely translate to bignums).
>
> I think cleaner code would usually be more important in this case,
> but at least there will be a choice.

I'm not sure how much cleaner this is.  Usually, you'll want disjoint
Scheme types, which means you'll end up enclosing the pointer-as-bignum
in a structure or SRFI-9 record or similar.  This leads to even more
overhead.  Conversely, using an opaque field in a Guile struct has the
same effect but with much less overhead.

Another issue is that of memory management.  When using
pointers-as-bignums, all the GC will see is a collection of bignums, not
knowing that these are actually pointers to C objects that should not be
GC'd unless the integer is no longer used---as opposed to "no longer
referenced"!  This actually makes it mandatory to enclose the integer in
a structure or similar, and then to have a guardian on that structure to
allow the C object's destructor to be called when that structure is no
longer referenced.

(Note that it could be a valid approach in some compiler environments.
It just doesn't fit well with Guile's design.)

Anyway, it can't hurt to have the choice.  :-)

Thanks,
Ludovic.

PS: You'll have to assign copyright to the FSF so that your code can be
    integrated.  We can discuss it off-line if you want.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-09 18:32   ` Kjetil S. Matheussen
@ 2008-07-09 19:37     ` Ludovic Courtès
  0 siblings, 0 replies; 13+ messages in thread
From: Ludovic Courtès @ 2008-07-09 19:37 UTC (permalink / raw)
  To: guile-devel

Hi,

"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:

> kjetil@ttleush ~/guile-1.8.5 $ gcc -Iinclude/ -Llib lib/libguile.a test.c
> /tmp/ccMcEAxd.o: In function `main':
> test.c:(.text+0x1b): undefined reference to `scm_from_uintptr'
> test.c:(.text+0x2c): undefined reference to `scm_to_uintptr'
> collect2: ld returned 1 exit status

Normally, there's no such thing as `lib/libguile.a'.  The thing is under
`libguile/.libs/libguile.{so,a}'.  Alternatively, it might be the case
that `SCM_HAVE_T_UINTPTR' is not defined.

Thanks,
Ludovic.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
@ 2008-07-09 19:58 Kjetil S. Matheussen
  0 siblings, 0 replies; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-09 19:58 UTC (permalink / raw)
  To: guile-devel


Ludovic Courtès:
>> kjetil <at> ttleush ~/guile-1.8.5 $ gcc -Iinclude/ -Llib lib/libguile.a test.c
> > /tmp/ccMcEAxd.o: In function `main':
> > test.c:(.text+0x1b): undefined reference to `scm_from_uintptr'
> > test.c:(.text+0x2c): undefined reference to `scm_to_uintptr'
> > collect2: ld returned 1 exit status
> 
> Normally, there's no such thing as `lib/libguile.a'.  The thing is under
> `libguile/.libs/libguile.{so,a}'.  Alternatively, it might be the case
> that `SCM_HAVE_T_UINTPTR' is not defined.

Normally, yes, but I installed in the same directory as the source. :-)

Anyway, I have no idea why the above didn't work, but it works now.
I haven't changed any of the files since the last time:

kjetil@ttleush ~/guile-1.8.5 $ gcc test.c -Iinclude lib/libguile.a -lgmp -lm -lltdl -lcrypt
lib/libguile.a(posix.o): In function `scm_tmpnam':
posix.c:(.text+0x14b0): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
kjetil@ttleush ~/guile-1.8.5 $ ./a.out
main: 0x804cd54, p: 804cd54
kjetil@ttleush ~/guile-1.8.5 $





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
@ 2008-07-09 20:09 Kjetil S. Matheussen
  2008-07-09 20:43 ` Ludovic Courtès
  2008-07-11 13:05 ` Greg Troxel
  0 siblings, 2 replies; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-09 20:09 UTC (permalink / raw)
  To: guile-devel


Ludovic Court?s:
>> I gave it a try. Unfortunately, I was completely unable to create
>> the configure file right now, so the patch is against 1.8.5 (sorry
>> if this creats trouble against git repository), and
>> it's also untested, since I couldn't build configure.
>
>You have to make sure you are on the `branch_release-1-8', and then
>"autoreconf -vfi" should suffice to produce everything.  Autoconf 2.61,
>Automake 1.10 and Libtool 1.5.26 is all you need.

Thanks. It would be nice if that information was in the source 
too...


> > The only thing I'm not too sure about is whether
> > the new SCM_I_GSC_T_UINTPTR type in configure.in will actually be
> > optional or not. I just copied the checking code for the optional
> > SCM_I_GSC_T_UINT64 type though:
>
> I think this type shouldn't be optional, because there will always be a
> pointer-sized integer type (whereas there could be platform without
> 64-bit integers).

But isn't the only way to make sure that an integer size
is big enough to hold a pointer, to use uintptr_t from
stdint.h ?

It does get a little bit complicated if Guile is compiled 
on a platform without stdint.h


>>> That said, using a Scheme integer to represent a pointer wouldn't be
>>> efficient (pointers would likely translate to bignums).
>>
>> I think cleaner code would usually be more important in this case,
>> but at least there will be a choice.
>
>I'm not sure how much cleaner this is.  Usually, you'll want disjoint
>Scheme types, which means you'll end up enclosing the pointer-as-bignum
>in a structure or SRFI-9 record or similar.  This leads to even more
>overhead.  Conversely, using an opaque field in a Guile struct has the
>same effect but with much less overhead.

It's cleaner because it requires a magnitude less code.

>Another issue is that of memory management.  When using
>pointers-as-bignums, all the GC will see is a collection of bignums, not
>knowing that these are actually pointers to C objects that should not be
>GC'd unless the integer is no longer used---as opposed to "no longer
>referenced"!  This actually makes it mandatory to enclose the integer in
>a structure or similar, and then to have a guardian on that structure to
>allow the C object's destructor to be called when that structure is no
>longer referenced.

That's true. But at least my experience is that using guardians
is cleaner than smurf's. For example, I think the use of guardians for 
faust objects in http://snd.cvs.sourceforge.net/snd/cvs-snd/rt-faust.scm
is very simple, it's just one line: "(add-finalizer (-> faust 
get-c-object) cleanup-faust-object)".

Also, various types of non-gc pointers are stored in integers in
all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/
and many others (xg.c, etc.). It would be horribly idiotic
to write smurf's for all of those, or at least a common smurf, when a 
single integer is enough.




>PS: You'll have to assign copyright to the FSF so that your code can be
>    integrated.  We can discuss it off-line if you want.

Okay, just tell me what to do.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-09 20:09 Kjetil S. Matheussen
@ 2008-07-09 20:43 ` Ludovic Courtès
  2008-07-11 13:05 ` Greg Troxel
  1 sibling, 0 replies; 13+ messages in thread
From: Ludovic Courtès @ 2008-07-09 20:43 UTC (permalink / raw)
  To: guile-devel

Hey,

"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:

> Ludovic Court?s:

>>You have to make sure you are on the `branch_release-1-8', and then
>>"autoreconf -vfi" should suffice to produce everything.  Autoconf 2.61,
>>Automake 1.10 and Libtool 1.5.26 is all you need.
>
> Thanks. It would be nice if that information was in the source 
> too...

Well, `configure.in' has an `AC_PREREQ' call, 1.10(.1) is the latest
Automake, and 1.5.26 is the latest Libtool of the 1.x series, it's
easy.  :-)

>> I think this type shouldn't be optional, because there will always be a
>> pointer-sized integer type (whereas there could be platform without
>> 64-bit integers).
>
> But isn't the only way to make sure that an integer size
> is big enough to hold a pointer, to use uintptr_t from
> stdint.h ?

No.  `configure' checks the size of a number of (integer) types.  The
idea here would be to have a check for `void *' (if there isn't one
already); then in `numbers.h', you'd add something along the lines of:

  #if SCM_SIZEOF_VOID_P == 4
  #define scm_to_uintptr scm_to_uint32
  [...]
  #elif SCM_SIZEOF_VOID_P == 8
  #define scm_to_uintptr scm_to_uint64
  [...]
  #else
  #error "strange `void *'"
  #endif

IOW, don't rely on <stdint.h> or <inttypes.h>.

> That's true. But at least my experience is that using guardians
> is cleaner than smurf's.

Smurf?  Smurf's what?

> For example, I think the use of guardians for 
> faust objects in http://snd.cvs.sourceforge.net/snd/cvs-snd/rt-faust.scm
> is very simple, it's just one line: "(add-finalizer (-> faust 
> get-c-object) cleanup-faust-object)".

Yes, guardians are easy to use.

> Also, various types of non-gc pointers are stored in integers in
> all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/
> and many others (xg.c, etc.). It would be horribly idiotic
> to write smurf's for all of those, or at least a common smurf, when a 
> single integer is enough.

Do you mean "SMOB" instead of "smurf"?  :-)

If so, the deallocation routine that's called from the guardian (which
is necessarily written in C) is roughly the same as the one you'd pass
to `scm_set_smob_free ()'.

Thanks,
Ludovic.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
@ 2008-07-10 12:49 Kjetil S. Matheussen
  2008-07-10 13:01 ` Ludovic Courtès
  0 siblings, 1 reply; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-10 12:49 UTC (permalink / raw)
  To: guile-devel


Ludovic Court?s:
>
> Well, `configure.in' has an `AC_PREREQ' call, 1.10(.1) is the latest
> Automake, and 1.5.26 is the latest Libtool of the 1.x series, it's
> easy.

Thanks, I didn't know that.


>No.  `configure' checks the size of a number of (integer) types.  The
>idea here would be to have a check for `void *' (if there isn't one
>already); then in `numbers.h', you'd add something along the lines of:
>
>  #if SCM_SIZEOF_VOID_P == 4
>  #define scm_to_uintptr scm_to_uint32
>  [...]
>  #elif SCM_SIZEOF_VOID_P == 8
>  #define scm_to_uintptr scm_to_uint64
>  [...]
>  #else
>  #error "strange `void *'"
>  #endif
>
> IOW, don't rely on <stdint.h> or <inttypes.h>.

Good idea. Much better. I'll do that.



>> That's true. But at least my experience is that using guardians
>> is cleaner than smurf's.
>
>Smurf?  Smurf's what?

Oops. :-)
I ment SMOB.



>If so, the deallocation routine that's called from the guardian (which
>is necessarily written in C) is roughly the same as the one you'd pass
>to `scm_set_smob_free ()'.

Point is that you very often don't need any kind of free functionality.
For example, if you create a gui widget, you probably have a callback
function which is called if the gui is closed. That callback
function can free any allocated memory. Another example from snd
is creating ladspa plugins (audio plugins in linux). Handlers
from those, plus variuos configuration stuff, is alive througout
the whole session and will be automatically freed when the program
closes.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-10 12:49 Passing C pointers through guile Kjetil S. Matheussen
@ 2008-07-10 13:01 ` Ludovic Courtès
  0 siblings, 0 replies; 13+ messages in thread
From: Ludovic Courtès @ 2008-07-10 13:01 UTC (permalink / raw)
  To: guile-devel

Hi,

"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:

> Point is that you very often don't need any kind of free functionality.
> For example, if you create a gui widget, you probably have a callback
> function which is called if the gui is closed. That callback
> function can free any allocated memory. Another example from snd
> is creating ladspa plugins (audio plugins in linux). Handlers
> from those, plus variuos configuration stuff, is alive througout
> the whole session and will be automatically freed when the program
> closes.

Sure, but the general case is that a C-implemented object must be
explicitly destroyed when it's no longer referenced by Scheme code.

Thanks,
Ludovic.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-09 20:09 Kjetil S. Matheussen
  2008-07-09 20:43 ` Ludovic Courtès
@ 2008-07-11 13:05 ` Greg Troxel
  2008-07-11 13:12   ` Kjetil S. Matheussen
  1 sibling, 1 reply; 13+ messages in thread
From: Greg Troxel @ 2008-07-11 13:05 UTC (permalink / raw)
  To: Kjetil S. Matheussen; +Cc: guile-devel

"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:

> Also, various types of non-gc pointers are stored in integers in
> all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/
> and many others (xg.c, etc.). It would be horribly idiotic
> to write smurf's for all of those, or at least a common smurf, when a 
> single integer is enough.

What fraction of these uses are actually correct?  Have people run this
code on Windows 64 (which is LLP64, but on which long is 32 bits),
sparc64, and alpha.  I'm always worried when people store pointers in
integers - it's IMHO basically a wrong thing to do.




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-11 13:05 ` Greg Troxel
@ 2008-07-11 13:12   ` Kjetil S. Matheussen
  2008-07-11 14:42     ` Ludovic Courtès
  0 siblings, 1 reply; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-11 13:12 UTC (permalink / raw)
  To: Greg Troxel; +Cc: guile-devel, Kjetil S. Matheussen



On Fri, 11 Jul 2008, Greg Troxel wrote:

> "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:
>
>> Also, various types of non-gc pointers are stored in integers in
>> all of the rt-*.scm files in http://snd.cvs.sourceforge.net/snd/cvs-snd/
>> and many others (xg.c, etc.). It would be horribly idiotic
>> to write smurf's for all of those, or at least a common smurf, when a
>> single integer is enough.
>
> What fraction of these uses are actually correct?  Have people run this
> code on Windows 64 (which is LLP64, but on which long is 32 bits),
> sparc64, and alpha.

All of them are correct. The alternative would be messier code.
The code in question doesn't run on those platforms anyway,
since there's a lot of strict linux stuff. However, I don't
the storage of pointers in unsigned longs (which is a perfectly
legal thing to do if done correctly), would pose any problem
for running it on other hardware.


>  I'm always worried when people store pointers in
> integers - it's IMHO basically a wrong thing to do.
>

In many situations, like the one above, it's a perfectly fine thing
to do, and also the only sane option. Of course, you must know what you 
are doing.




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
  2008-07-11 13:12   ` Kjetil S. Matheussen
@ 2008-07-11 14:42     ` Ludovic Courtès
  0 siblings, 0 replies; 13+ messages in thread
From: Ludovic Courtès @ 2008-07-11 14:42 UTC (permalink / raw)
  To: guile-devel

Hi,

"Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:

> The code in question doesn't run on those platforms anyway,
> since there's a lot of strict linux stuff.

You are certainly aware that GNU/Linux *is* available on sparc64, alpha,
etc.

> However, I don't the storage of pointers in unsigned longs (which is a
> perfectly legal thing to do if done correctly), would pose any problem
> for running it on other hardware.

Again, it's not "perfectly legal", no matter whether you do it
"correctly" (whatever that means) or not: the C standard makes no
provision regarding the size of `long' versus the size of pointer types.
It happens to work on the mainstream platforms you're using, but it's
definitely not portable.

And I suppose that's the reason why you want `scm_{to,from}_uintptr ()'
in the first place, otherwise you'd just live (dangerously) with
`scm_{to,from}_unsigned_long ()'.

Thanks,
Ludovic.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Passing C pointers through guile
       [not found] <cmu-lmtpd-26382-1215792388-9@mail-imap1.uio.no>
@ 2008-07-11 17:22 ` Kjetil S. Matheussen
  0 siblings, 0 replies; 13+ messages in thread
From: Kjetil S. Matheussen @ 2008-07-11 17:22 UTC (permalink / raw)
  To: guile-devel


Ludovic Court?s:
> "Kjetil S. Matheussen" <k.s.matheussen@notam02.no> writes:
>
>> The code in question doesn't run on those platforms anyway,
>> since there's a lot of strict linux stuff.
>
> You are certainly aware that GNU/Linux *is* available on sparc64, alpha,
> etc.
>

Well, yes, but he wrote windows 64, sparc64, alpha etc.



>> However, I don't the storage of pointers in unsigned longs (which is a
>> perfectly legal thing to do if done correctly), would pose any problem
>> for running it on other hardware.
>
> Again, it's not "perfectly legal", no matter whether you do it
> "correctly" (whatever that means) or not: the C standard makes no
> provision regarding the size of `long' versus the size of pointer types.
> It happens to work on the mainstream platforms you're using, but it's
> definitely not portable.
>
> And I suppose that's the reason why you want `scm_{to,from}_uintptr ()'
> in the first place, otherwise you'd just live (dangerously) with
> `scm_{to,from}_unsigned_long ()'.
>

Yes, and this is a stupid discussion. We don't really disagree about 
anything unless anyone thinks I should change all my code using
scheme numbers to hold pointers into SMOB's, which would significantly
increase the code size which further would increase the chance of bugs.
There are, as I have given examples of already, types of pointer
where SMOB's are overkill. And just for trying out smaller things,
it a lot of work to set up all that SMOB code (again!). I do a lot
of interaction between C and scheme, and avoiding SMOBs as much
as possible saves me a lot of time.





^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2008-07-11 17:22 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-10 12:49 Passing C pointers through guile Kjetil S. Matheussen
2008-07-10 13:01 ` Ludovic Courtès
     [not found] <cmu-lmtpd-26382-1215792388-9@mail-imap1.uio.no>
2008-07-11 17:22 ` Kjetil S. Matheussen
  -- strict thread matches above, loose matches on Subject: below --
2008-07-09 20:09 Kjetil S. Matheussen
2008-07-09 20:43 ` Ludovic Courtès
2008-07-11 13:05 ` Greg Troxel
2008-07-11 13:12   ` Kjetil S. Matheussen
2008-07-11 14:42     ` Ludovic Courtès
2008-07-09 19:58 Kjetil S. Matheussen
     [not found] <cmu-lmtpd-29205-1215446748-1@mail-imap1.uio.no>
2008-07-09 16:50 ` Kjetil S. Matheussen
2008-07-09 18:32   ` Kjetil S. Matheussen
2008-07-09 19:37     ` Ludovic Courtès
2008-07-09 19:35   ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).