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]

Re: structs, records, SMOBs etc.


mike@olan.com (Michael N. Livshin) writes:

> Mikael Djurfeldt <mdj@nada.kth.se> writes:
> 
> > mikel@opal.co.il (Michael N. Livshin) writes:
> > 
> > >   Records.
> > >     I think, this is (potentially) the best of the three.  To make
> > >     it so, records need to be implemented in the Guile core, and
> > >     the C interface to them needs to allow user GC hooks and binary
> > >     data.  Another win of this would be a unified type-definition
> > >     mechanism for both C and Scheme levels.
> > 
> > Yes.  This is what I referred to as a "functionally similar"
> > replacement for the structs in a recent letter.
> 
> I'm going to take a stab at this today or tomorrow (borrowing the
> implementation from SCM, probably).
>
> Where this will differ from SCM's implementation is that a C programmer
> will be able to reserve an arbitrary number of words at the beginning
> of the record's data array and do what he pleases with them.  Plus
> specifying GC hooks, of course.  The `make-record-type' which is
> exported to Scheme will reserve 0 words.  Is this OK?

It's great that you want to work on this.

My opinion (i.e. not necessarily the direction we should follow) on
this issue is:

Since Guile is foremost an embedded language intended for extension of
an application, it is important to provide good support for
manipulation of application data.

Therefore I'd like if the new record type could be "mapped" over an
application struct and if it would enable Scheme level access to
binary data.

>From the C level it could look something like this:

  scm_make_record_type (char *name,
                        scm_record_field_spec_t **specs,
		        SCM (*gc_hook) (SCM obj))

  typedef struct {
    char *name;
    scm_record_field_type_t type;
    scm_record_field_access_t access;
    int len;
  } scm_record_field_spec_t;

  typedef enum {
    SCM_FT_CHAR,
    SCM_FT_SHORT,
    SCM_FT_INT,
    SCM_FT_SCM_NO_GC,
    SCM_FT_SCM_GC,
  } scm_record_field_type_t;

  typedef enum {
    SCM_FA_OPAQUE,
    SCM_FA_READONLY,
    SCM_FA_READWRITE
  } scm_record_field_access_t;

All field types which aren't opaque would be accessible from Scheme,
i.e., it is possible to call `record-accessor' for them.

The `len' field could be used to specify an OPAQUE block of binary
data to "skip", or could be used to specify an array of fields of
similar type.

Maybe it should also be possible to put a pointer to a record field
spec array inside another record field spec array to support the
situation when a struct contains another struct, or when it contains a
pointer to another struct.

If the gc_hook is NULL, a standard function will be used (which looks
after SCM_FT_SCM_GC fields).  If the user wants special treatment he
can supply his own gc routine.

The record field spec would be "compiled" by make_record_type into a
format which is maximally efficient for the garbage collector.  This
compiled spec would be stored in the "type object".

If we represent the new records the same way as the current structs,
we can store a pointer to the type object in the CAR (where the
current "vtable" is stored), and a pointer to the data structure in
the CDR.

This is just quickly written down and not a result of much thought.
What do people say about this?

/mdj