mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-22 04:30:19 +02:00
* data-rep.texi: Updated SMOB docs to talk about
scm_make_smob_type_mfpe, SCM_RETURN_NEWSMOB, SCM_NEWSMOB function and macros.
This commit is contained in:
parent
283a1a0e77
commit
5bdab01690
1 changed files with 93 additions and 41 deletions
|
@ -46,7 +46,7 @@ by the Free Software Foundation.
|
||||||
@sp 10
|
@sp 10
|
||||||
@comment The title is printed in a large font.
|
@comment The title is printed in a large font.
|
||||||
@title Data Representation in Guile
|
@title Data Representation in Guile
|
||||||
@subtitle $Id: data-rep.texi,v 1.6 1999-06-19 11:02:18 jimb Exp $
|
@subtitle $Id: data-rep.texi,v 1.7 1999-07-07 09:40:28 mdj Exp $
|
||||||
@subtitle For use with Guile @value{VERSION}
|
@subtitle For use with Guile @value{VERSION}
|
||||||
@author Jim Blandy
|
@author Jim Blandy
|
||||||
@author Free Software Foundation
|
@author Free Software Foundation
|
||||||
|
@ -1115,58 +1115,99 @@ datatypes described here.)
|
||||||
@node Describing a New Type, Creating Instances, Defining New Types (Smobs), Defining New Types (Smobs)
|
@node Describing a New Type, Creating Instances, Defining New Types (Smobs), Defining New Types (Smobs)
|
||||||
@subsection Describing a New Type
|
@subsection Describing a New Type
|
||||||
|
|
||||||
To define a new type, the programmer must fill in an @code{scm_smobfuns}
|
To define a new type, the programmer must write four functions to
|
||||||
structure with functions to manage instances of the type. Here is the
|
manage instances of the type:
|
||||||
definition of the structure:
|
|
||||||
|
|
||||||
@example
|
|
||||||
typedef struct scm_smobfuns
|
|
||||||
@{
|
|
||||||
SCM (*mark) (SCM @var{obj});
|
|
||||||
scm_sizet (*free) (SCM @var{obj});
|
|
||||||
int (*print) (SCM @var{obj},
|
|
||||||
SCM @var{port},
|
|
||||||
scm_print_state *@var{pstate});
|
|
||||||
SCM (*equalp) (SCM @var{a}, SCM @var{b});
|
|
||||||
@} scm_smobfuns;
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item mark
|
@item mark
|
||||||
Guile will apply this function to each instance of the new type it
|
Guile will apply this function to each instance of the new type it
|
||||||
encounters during garbage collection. This function is responsible for
|
encounters during garbage collection. This function is responsible for
|
||||||
telling the collector about any other non-immediate objects the object
|
telling the collector about any other non-immediate objects the object
|
||||||
refers to. @xref{Garbage Collecting Smobs}, for more details.
|
refers to. The default smob mark function is to not mark any data.
|
||||||
|
@xref{Garbage Collecting Smobs}, for more details.
|
||||||
|
|
||||||
@item free
|
@item free
|
||||||
Guile will apply this function to each instance of the new type it could
|
Guile will apply this function to each instance of the new type it could
|
||||||
not find any live pointers to. The function should release all
|
not find any live pointers to. The function should release all
|
||||||
resources held by the object and return.
|
resources held by the object and return the number of bytes released.
|
||||||
@xref{Garbage Collecting Smobs}, for more details.
|
This is analagous to the Java finalization method-- it is invoked at
|
||||||
|
an unspecified time (when garbage collection occurs) after the object
|
||||||
|
is dead.
|
||||||
|
The default free function frees the smob data (if the size of the struct
|
||||||
|
passed to @code{scm_make_smob_type} or @code{scm_make_smob_type_mfpe} is
|
||||||
|
non-zero) using @code{scm_must_free} and returns the size of that
|
||||||
|
struct. @xref{Garbage Collecting Smobs}, for more details.
|
||||||
|
|
||||||
@item print
|
@item print
|
||||||
|
@c GJB:FIXME:: @var{exp} and @var{port} need to refer to a prototype of
|
||||||
|
@c the print function.... where is that, or where should it go?
|
||||||
Guile will apply this function to each instance of the new type to print
|
Guile will apply this function to each instance of the new type to print
|
||||||
the value, as for @code{display} or @code{write}. The function should
|
the value, as for @code{display} or @code{write}. The function should
|
||||||
write a printed representation of @var{exp} on @var{port}, in accordance
|
write a printed representation of @var{exp} on @var{port}, in accordance
|
||||||
with the parameters in @var{pstate}. (For more information on print
|
with the parameters in @var{pstate}. (For more information on print
|
||||||
states, see @ref{Ports}.)
|
states, see @ref{Ports}.) The default print function prints @code{#<NAME ADDRESS>}
|
||||||
|
where @code{NAME} is the first argument passed to @code{scm_make_smob_type} or
|
||||||
|
@code{scm_make_smob_type_mfpe}.
|
||||||
|
|
||||||
@item equalp
|
@item equalp
|
||||||
If Scheme code asks the @code{equal?} function to compare two instances
|
If Scheme code asks the @code{equal?} function to compare two instances
|
||||||
of the same smob type, Guile calls this function. It should return
|
of the same smob type, Guile calls this function. It should return
|
||||||
@code{SCM_BOOL_T} if @var{a} and @var{b} should be considered
|
@code{SCM_BOOL_T} if @var{a} and @var{b} should be considered
|
||||||
@code{equal?}, or @code{SCM_BOOL_F} otherwise. If @code{equalp} is
|
@code{equal?}, or @code{SCM_BOOL_F} otherwise. If @code{equalp} is
|
||||||
zero, @code{equal?} will assume that two instances of this type are
|
@code{NULL}, @code{equal?} will assume that two instances of this type are
|
||||||
never @code{equal?} unless they are @code{eq?}.
|
never @code{equal?} unless they are @code{eq?}.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Once you have built a @code{scm_smobfuns} structure, you can call the
|
To actually register the new smob type, you must call either @code{scm_make_smob_type}
|
||||||
@code{scm_newsmob} function to add the type to the system.
|
or @code{scm_make_smob_type_mfpe}:
|
||||||
|
|
||||||
@deftypefun long scm_newsmob (scm_smobfuns *@var{funs})
|
@deftypefun long scm_make_smob_type (const char *name, scm_sizet size)
|
||||||
This function adds the type described by @var{funs} to the system. The
|
This function adds a new smob type, named @var{name}, with instance size @var{size} to the system.
|
||||||
return value is a tag, used in creating instances of the type.
|
The return value is a tag that is used in creating instances of the type. If @var{size}
|
||||||
|
is 0, then no memory will be allocated when instances of the smob are created, and
|
||||||
|
nothing will be freed by the default free function.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
Each of the below @code{scm_set_smob_XXX} functions registers a smob
|
||||||
|
special function for a given type. You can instead use
|
||||||
|
@code{scm_make_smob_type_mfpe} to register the special smob functions
|
||||||
|
when you create the smob type, if you prefer.
|
||||||
|
|
||||||
|
@deftypefun void scm_set_smob_mark (long tc, SCM (*mark) (SCM))
|
||||||
|
This function sets the smob marking procedure for the smob type specified by
|
||||||
|
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void scm_set_smob_free (long tc, scm_sizet (*free) (SCM))
|
||||||
|
This function sets the smob freeing procedure for the smob type specified by
|
||||||
|
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void scm_set_smob_print (long tc, int (*print) (SCM,SCM,scm_print_state*))
|
||||||
|
This function sets the smob printing procedure for the smob type specified by
|
||||||
|
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void scm_set_smob_equalp (long tc, SCM (*equalp) (SCM,SCM))
|
||||||
|
This function sets the smob equality-testing predicate for the smob type specified by
|
||||||
|
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
Instead of using @code{scm_make_smob_type} and calling each of the individual
|
||||||
|
@code{scm_set_smob_XXXX} functions to register each special function
|
||||||
|
independently, you can use @code{scm_make_smob_type_mfpe} to register all
|
||||||
|
of the special functions at once as you create the smob type:
|
||||||
|
|
||||||
|
@deftypefun long scm_make_smob_type_mfpe(const char *name, scm_sizet size, SCM (*mark) (SCM), scm_sizet (*free) (SCM), int (*print) (SCM, SCM, scm_print_state*), SCM (*equalp) (SCM, SCM))
|
||||||
|
This function invokes @code{scm_make_smob_type} on its first two arguments
|
||||||
|
to add a new smob type named @var{name}, with instance size @var{size} to the system.
|
||||||
|
It also registers the @var{mark}, @var{free}, @var{print}, @var{equalp} smob
|
||||||
|
special functions for that new type. Any of these parameters can be @code{NULL}
|
||||||
|
to have that special function use the default behaviour for guile.
|
||||||
|
The return value is a tag that is used in creating instances of the type. If @var{size}
|
||||||
|
is 0, then no memory will be allocated when instances of the smob are created, and
|
||||||
|
nothing will be freed by the default free function.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
For example, here is how one might declare and register a new type
|
For example, here is how one might declare and register a new type
|
||||||
|
@ -1176,14 +1217,11 @@ representing eight-bit grayscale images:
|
||||||
|
|
||||||
long image_tag;
|
long image_tag;
|
||||||
|
|
||||||
scm_smobfuns image_funs = @{
|
|
||||||
mark_image, free_image, print_image, 0
|
|
||||||
@};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_image_type ()
|
init_image_type ()
|
||||||
@{
|
@{
|
||||||
image_tag = scm_newsmob (&image_funs);
|
image_tag = scm_make_smob_type_mfpe ("image",sizeof(struct image),
|
||||||
|
mark_image, free_image, print_image, NULL);
|
||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@ -1192,10 +1230,28 @@ init_image_type ()
|
||||||
@subsection Creating Instances
|
@subsection Creating Instances
|
||||||
|
|
||||||
Like other non-immediate types, smobs start with a cell whose @sc{car}
|
Like other non-immediate types, smobs start with a cell whose @sc{car}
|
||||||
contains typing information, and whose @code{cdr} is free for any use.
|
contains typing information, and whose @code{cdr} is free for any use. For smobs,
|
||||||
To create an instance of a smob type, you must allocate a fresh cell, by
|
the @code{cdr} stores a pointer to the internal C structure holding the
|
||||||
calling @code{SCM_NEWCELL}, and store the tag returned by
|
smob-specific data.
|
||||||
@code{scm_smobfuns} in its car.
|
To create an instance of a smob type following these standards, you should
|
||||||
|
use @code{SCM_NEWSMOB}:
|
||||||
|
|
||||||
|
@deftypefn Macro void SCM_NEWSMOB(SCM value,long tag,void *data)
|
||||||
|
Make @var{value} contain a smob instance of the type with tag @var{tag}
|
||||||
|
and smob data @var{data}. @var{value} must be previously declared
|
||||||
|
as C type @code{SCM}.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
Since it is often the case (e.g., in smob constructors) that you will
|
||||||
|
create a smob instance and return it, there is also a slightly specialized
|
||||||
|
macro for this situation:
|
||||||
|
|
||||||
|
@deftypefn Macro fn_returns SCM_RETURN_NEWSMOB(long tab, void *data)
|
||||||
|
This macro expands to a block of code that creates a smob instance of
|
||||||
|
the type with tag @var{tag} and smob data @var{data}, and returns
|
||||||
|
that @code{SCM} value. It should be the last piece of code in
|
||||||
|
a block.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
Guile provides the following functions for managing memory, which are
|
Guile provides the following functions for managing memory, which are
|
||||||
often helpful when implementing smobs:
|
often helpful when implementing smobs:
|
||||||
|
@ -1261,7 +1317,6 @@ SCM
|
||||||
make_image (SCM name, SCM s_width, SCM s_height)
|
make_image (SCM name, SCM s_width, SCM s_height)
|
||||||
@{
|
@{
|
||||||
struct image *image;
|
struct image *image;
|
||||||
SCM image_smob;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
SCM_ASSERT (SCM_NIMP (name) && SCM_STRINGP (name), name,
|
SCM_ASSERT (SCM_NIMP (name) && SCM_STRINGP (name), name,
|
||||||
|
@ -1279,11 +1334,7 @@ make_image (SCM name, SCM s_width, SCM s_height)
|
||||||
image->name = name;
|
image->name = name;
|
||||||
image->update_func = SCM_BOOL_F;
|
image->update_func = SCM_BOOL_F;
|
||||||
|
|
||||||
SCM_NEWCELL (image_smob);
|
SCM_RETURN_NEWSMOB (image_tag, image);
|
||||||
SCM_SETCDR (image_smob, image);
|
|
||||||
SCM_SETCAR (image_smob, image_tag);
|
|
||||||
|
|
||||||
return image_smob;
|
|
||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@ -1340,6 +1391,7 @@ Note that checking types is a little more complicated during garbage
|
||||||
collection; see the description of @code{SCM_GCTYP16} in @ref{Garbage
|
collection; see the description of @code{SCM_GCTYP16} in @ref{Garbage
|
||||||
Collecting Smobs}.
|
Collecting Smobs}.
|
||||||
|
|
||||||
|
@c GJB:FIXME:: should talk about guile-snarf somewhere!
|
||||||
|
|
||||||
@node Garbage Collecting Smobs, A Common Mistake In Allocating Smobs, Typechecking, Defining New Types (Smobs)
|
@node Garbage Collecting Smobs, A Common Mistake In Allocating Smobs, Typechecking, Defining New Types (Smobs)
|
||||||
@subsection Garbage Collecting Smobs
|
@subsection Garbage Collecting Smobs
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue