This is the mail archive of the guile@cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

New smob interface


Before release, it is necessary to make sure that smobs and ports get
proxy classes in Goops.  To be able to create proxy classes, Goops
needs to know the name of a smob type, but the old interface for
creation of smob types didn't specify a name.

Also, the old smob interface feels unnecessarily complicated.

Therefore I've now comitted a new interface for smob type creation
which supersedes scm_newsmob.

I realize that I have too many tasks to do before release, considering
the amount of time I can spend on Guile.  This is a request for help
to complete this change.  Here's what needs to be done:

1. Someone needs to modify the section about smobs in data-rep.texi
   and modify the code in doc/example according to the description
   below.  (The description below is very rudimentary.  It should of
   course not be copied verbatim into the manual.)

2. Someone needs to replace all calls to scm_newsmob with
   scm_make_smob_type and scm_set_smob_xxx in libguile and modify the
   smob constructors to use SCM_NEWSMOB.  While doing this, one should
   of course try to use the default mark and print functions if this
   is possible without removing functionality.

   arbiters.c, async.c and regex-posix.c has already been converted.
   Look there to see what it's about.

Who can supply this?

Description of new smob interface
=================================

The philosophy has been to make it as simple as possible for the naive
user to create new smob types and objects, while still allowing the
the advanced user to have more control, and allowing for future
extensions.

This is how the naive user does it:

typedef struct my_type_t {
  int a;
  int b;
} my_type_t;

#define MY_TYPE_A(x) (((my_type_t *) SCM_SMOB_DATA (x))->a)
#define MY_TYPE_B(x) (((my_type_t *) SCM_SMOB_DATA (x))->b)

long my_type = scm_make_smob_type ("my-type", sizeof (my_type_t));

SCM
scm_make_my_type (int a, int b)
{
  SCM z = scm_make_smob (my_type);
  MY_TYPE_A (z) = a;
  MY_TYPE_B (z) = b;
  return z;
}

Just as before, the advanced user can write his own versions of the
mark, free, print, and, equalp functions:

scm_set_smob_mark (my_type, my_mark);
scm_set_smob_free (my_type, my_free);
etc.

The default is

mark: not to mark any data

free: not free anything and return 0 if size passed to
      scm_make_smob_type was 0, or

      free the smob data using scm_must_free and return the size
      otherwise.

print: print #<NAME ADDRESS> where NAME is the first arg to
       scm_make_smob_data and

       ADDRESS the address of the handle if size = 0, or

       the address of the malloced memory block otherwise.

The behaviour of scm_make_smob is to create the handle and mallocate
memory if size > 0.

IMPORTANT NOTE: If the advanced user chooses to store GC:d data in his
malloced block and writes his own mark function, it is no longer
possible to use scm_make_smob!

In this case he needs to use the following idiom:

SCM
scm_make_my_type (int a, SCM b)
{
  SCM z;
  my_type_t *m = scm_must_malloc (sizeof (my_type_t), "my-type");
  m->a = a;
  m->b = b;
  SCM_NEWSMOB (z, my_type, m);
  return m;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]