summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--doc/ref/api-compound.texi22
-rw-r--r--doc/ref/libguile-smobs.texi174
-rw-r--r--doc/ref/srfi-modules.texi4
-rw-r--r--libguile/__scm.h2
-rw-r--r--libguile/i18n.c4
-rw-r--r--libguile/throw.c2
-rw-r--r--libguile/throw.h2
-rw-r--r--module/ice-9/psyntax-pp.scm9
-rw-r--r--module/ice-9/psyntax.scm12
10 files changed, 97 insertions, 138 deletions
diff --git a/.gitignore b/.gitignore
index b136c7ae2..12cbc32f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -150,10 +150,14 @@ INSTALL
/lib/dirent.h
/lib/langinfo.h
/lib/wctype.h
+/lib/poll.h
+/lib/sys/select.h
+/lib/sys/times.h
/build-aux/ar-lib
/build-aux/test-driver
*.trs
/test-suite/standalone/test-smob-mark
/test-suite/standalone/test-scm-values
/test-suite/standalone/test-scm-to-latin1-string
+/test-suite/standalone/test-scm-c-bind-keyword-arguments
/libguile/vm-operations.h
diff --git a/doc/ref/api-compound.texi b/doc/ref/api-compound.texi
index 1990d777d..94e01450e 100644
--- a/doc/ref/api-compound.texi
+++ b/doc/ref/api-compound.texi
@@ -689,22 +689,18 @@ Vectors can literally be entered in source code, just like strings,
characters or some of the other data types. The read syntax for vectors
is as follows: A sharp sign (@code{#}), followed by an opening
parentheses, all elements of the vector in their respective read syntax,
-and finally a closing parentheses. The following are examples of the
-read syntax for vectors; where the first vector only contains numbers
-and the second three different object types: a string, a symbol and a
-number in hexadecimal notation.
+and finally a closing parentheses. Like strings, vectors do not have to
+be quoted.
+
+The following are examples of the read syntax for vectors; where the
+first vector only contains numbers and the second three different object
+types: a string, a symbol and a number in hexadecimal notation.
@lisp
#(1 2 3)
#("Hello" foo #xdeadbeef)
@end lisp
-Like lists, vectors have to be quoted:
-
-@lisp
-'#(a b c) @result{} #(a b c)
-@end lisp
-
@node Vector Creation
@subsubsection Dynamic Vector Creation and Validation
@@ -735,7 +731,7 @@ The inverse operation is @code{vector->list}:
Return a newly allocated list composed of the elements of @var{v}.
@lisp
-(vector->list '#(dah dah didah)) @result{} (dah dah didah)
+(vector->list #(dah dah didah)) @result{} (dah dah didah)
(list->vector '(dididit dah)) @result{} #(dididit dah)
@end lisp
@end deffn
@@ -796,8 +792,8 @@ Return the number of elements in @var{vec} as a @code{size_t}.
Return the contents of position @var{k} of @var{vec}.
@var{k} must be a valid index of @var{vec}.
@lisp
-(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8
-(vector-ref '#(1 1 2 3 5 8 13 21)
+(vector-ref #(1 1 2 3 5 8 13 21) 5) @result{} 8
+(vector-ref #(1 1 2 3 5 8 13 21)
(let ((i (round (* 2 (acos -1)))))
(if (inexact? i)
(inexact->exact i)
diff --git a/doc/ref/libguile-smobs.texi b/doc/ref/libguile-smobs.texi
index 6f7c0f45f..572bcf316 100644
--- a/doc/ref/libguile-smobs.texi
+++ b/doc/ref/libguile-smobs.texi
@@ -31,7 +31,6 @@ datatypes described here.)
* Creating Smob Instances::
* Type checking::
* Garbage Collecting Smobs::
-* Garbage Collecting Simple Smobs::
* Remembering During Operations::
* Double Smobs::
* The Complete Example::
@@ -40,31 +39,10 @@ datatypes described here.)
@node Describing a New Type
@subsection Describing a New Type
-To define a new type, the programmer must write four functions to
+To define a new type, the programmer must write two functions to
manage instances of the type:
@table @code
-@item mark
-Guile will apply this function to each instance of the new type it
-encounters during garbage collection. This function is responsible for
-telling the collector about any other @code{SCM} values that the object
-has stored. The default smob mark function does nothing.
-@xref{Garbage Collecting Smobs}, for more details.
-
-@item free
-Guile will apply this function to each instance of the new type that is
-to be deallocated. The function should release all resources held by
-the object. This is analogous 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} is non-zero)
-using @code{scm_gc_free}. @xref{Garbage Collecting Smobs}, for more
-details.
-
-This function operates while the heap is in an inconsistent state and
-must therefore be careful. @xref{Smobs}, for details about what this
-function is allowed to do.
-
@item 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 default print
@@ -81,6 +59,32 @@ never @code{equal?} unless they are @code{eq?}.
@end table
+When the only resource associated with a smob is memory managed by the
+garbage collector---i.e., memory allocated with the @code{scm_gc_malloc}
+functions---this is sufficient. However, when a smob is associated with
+other kinds of resources, it may be necessary to define one of the
+following functions, or both:
+
+@table @code
+@item mark
+Guile will apply this function to each instance of the new type it
+encounters during garbage collection. This function is responsible for
+telling the collector about any other @code{SCM} values that the object
+has stored, and that are in memory regions not already scanned by the
+garbage collector. @xref{Garbage Collecting Smobs}, for more details.
+
+@item free
+Guile will apply this function to each instance of the new type that is
+to be deallocated. The function should release all resources held by
+the object. This is analogous to the Java finalization method---it is
+invoked at an unspecified time (when garbage collection occurs) after
+the object is dead. @xref{Garbage Collecting Smobs}, for more details.
+
+This function operates while the heap is in an inconsistent state and
+must therefore be careful. @xref{Smobs}, for details about what this
+function is allowed to do.
+@end table
+
To actually register the new smob type, call @code{scm_make_smob_type}.
It returns a value of type @code{scm_t_bits} which identifies the new
smob type.
@@ -164,35 +168,11 @@ word of a smob, you should use the macros @code{SCM_SMOB_OBJECT} and
@code{SCM_SET_SMOB_OBJECT} to access it.
Creating a smob instance can be tricky when it consists of multiple
-steps that allocate resources and might fail. It is recommended that
-you go about creating a smob in the following way:
-
-@itemize
-@item
-Allocate the memory block for holding the data with
-@code{scm_gc_malloc}.
-@item
-Initialize it to a valid state without calling any functions that might
-cause a non-local exits. For example, initialize pointers to NULL.
-Also, do not store @code{SCM} values in it that must be protected.
-Initialize these fields with @code{SCM_BOOL_F}.
-
-A valid state is one that can be safely acted upon by the @emph{mark}
-and @emph{free} functions of your smob type.
-@item
-Create the smob using @code{scm_new_smob}, passing it the initialized
-memory block. (This step will always succeed.)
-@item
-Complete the initialization of the memory block by, for example,
-allocating additional resources and making it point to them.
-@end itemize
-
-This procedure ensures that the smob is in a valid state as soon as it
-exists, that all resources that are allocated for the smob are
-properly associated with it so that they can be properly freed, and
-that no @code{SCM} values that need to be protected are stored in it
-while the smob does not yet completely exist and thus can not protect
-them.
+steps that allocate resources. Most of the time, this is mainly about
+allocating memory to hold associated data structures. Using memory
+managed by the garbage collector simplifies things: the garbage
+collector will automatically scan those data structures for pointers,
+and reclaim them when they are no longer referenced.
Continuing the example from above, if the global variable
@code{image_tag} contains a tag returned by @code{scm_make_smob_type},
@@ -229,44 +209,19 @@ make_image (SCM name, SCM s_width, SCM s_height)
*/
image->name = name;
image->pixels =
- scm_gc_malloc (width * height, "image pixels");
+ scm_gc_malloc_pointerless (width * height, "image pixels");
return smob;
@}
@end example
-Let us look at what might happen when @code{make_image} is called.
-
-The conversions of @var{s_width} and @var{s_height} to @code{int}s might
-fail and signal an error, thus causing a non-local exit. This is not a
-problem since no resources have been allocated yet that would have to be
-freed.
-
-The allocation of @var{image} in step 1 might fail, but this is likewise
-no problem.
-
-Step 2 can not exit non-locally. At the end of it, the @var{image}
-struct is in a valid state for the @code{mark_image} and
-@code{free_image} functions (see below).
-
-Step 3 can not exit non-locally either. This is guaranteed by Guile.
-After it, @var{smob} contains a valid smob that is properly initialized
-and protected, and in turn can properly protect the Scheme values in its
-@var{image} struct.
+We use @code{scm_gc_malloc_pointerless} for the pixel buffer to tell the
+garbage collector not to scan it for pointers. Calls to
+@code{scm_gc_malloc}, @code{scm_new_smob}, and
+@code{scm_gc_malloc_pointerless} raise an exception in out-of-memory
+conditions; the garbage collector is able to reclaim previously
+allocated memory if that happens.
-But before the smob is completely created, @code{scm_new_smob} might
-cause the garbage collector to run. During this garbage collection, the
-@code{SCM} values in the @var{image} struct would be invisible to Guile.
-It only gets to know about them via the @code{mark_image} function, but
-that function can not yet do its job since the smob has not been created
-yet. Thus, it is important to not store @code{SCM} values in the
-@var{image} struct until after the smob has been created.
-
-Step 4, finally, might fail and cause a non-local exit. In that case,
-the complete creation of the smob has not been successful, but it does
-nevertheless exist in a valid state. It will eventually be freed by
-the garbage collector, and all the resources that have been allocated
-for it will be correctly freed by @code{free_image}.
@node Type checking
@subsection Type checking
@@ -310,8 +265,17 @@ to @code{scm_remember_upto_here_1}.
@subsection Garbage Collecting Smobs
Once a smob has been released to the tender mercies of the Scheme
-system, it must be prepared to survive garbage collection. Guile calls
-the @emph{mark} and @emph{free} functions of the smob to manage this.
+system, it must be prepared to survive garbage collection. In the
+example above, all the memory associated with the smob is managed by the
+garbage collector because we used the @code{scm_gc_} allocation
+functions. Thus, no special care must be taken: the garbage collector
+automatically scans them and reclaims any unused memory.
+
+However, when data associated with a smob is managed in some other
+way---e.g., @code{malloc}'d memory or file descriptors---it is possible
+to specify a @emph{free} function to release those resources when the
+smob is reclaimed, and a @emph{mark} function to mark Scheme objects
+otherwise invisible to the garbage collector.
As described in more detail elsewhere (@pxref{Conservative GC}), every
object in the Scheme system has a @dfn{mark bit}, which the garbage
@@ -343,7 +307,9 @@ values will have become dangling references.
To mark an arbitrary Scheme object, the @emph{mark} function calls
@code{scm_gc_mark}.
-Thus, here is how we might write @code{mark_image}:
+Thus, here is how we might write @code{mark_image}---again this is not
+needed in our example since we used the @code{scm_gc_} allocation
+routines, so this is just for the sake of illustration:
@example
@group
@@ -398,7 +364,8 @@ type of the @emph{free} function should be @code{size_t}, an unsigned
integral type; the @emph{free} function should always return zero.
Here is how we might write the @code{free_image} function for the image
-smob type:
+smob type---again for the sake of illustration, since our example does
+not need it thanks to the use of the @code{scm_gc_} allocation routines:
@example
size_t
free_image (SCM image_smob)
@@ -426,37 +393,12 @@ during garbage collection; keep the @emph{mark} and @emph{free}
functions very simple. Since collections occur at unpredictable times,
it is easy for any unusual activity to interfere with normal code.
-
-@node Garbage Collecting Simple Smobs
-@subsection Garbage Collecting Simple Smobs
-
-It is often useful to define very simple smob types --- smobs which have
-no data to mark, other than the cell itself, or smobs whose immediate
-data word is simply an ordinary Scheme object, to be marked recursively.
-Guile provides some functions to handle these common cases; you can use
-this function as your smob type's @emph{mark} function, if your smob's
-structure is simple enough.
-
-If the smob refers to no other Scheme objects, then no action is
-necessary; the garbage collector has already marked the smob cell
-itself. In that case, you can use zero as your mark function.
-
-If the smob refers to exactly one other Scheme object via its first
-immediate word, you can use @code{scm_markcdr} as its mark function.
-Its definition is simply:
-
-@smallexample
-SCM
-scm_markcdr (SCM obj)
-@{
- return SCM_SMOB_OBJECT (obj);
-@}
-@end smallexample
-
@node Remembering During Operations
@subsection Remembering During Operations
@cindex remembering
+@c FIXME: Remove this section?
+
It's important that a smob is visible to the garbage collector
whenever its contents are being accessed. Otherwise it could be freed
while code is still using it.
@@ -516,6 +458,8 @@ while the collector runs.)
@node Double Smobs
@subsection Double Smobs
+@c FIXME: Remove this section?
+
Smobs are called smob because they are small: they normally have only
room for one @code{void*} or @code{SCM} value plus 16 bits. The
reason for this is that smobs are directly implemented by using the
diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
index d97f49820..32ff271b7 100644
--- a/doc/ref/srfi-modules.texi
+++ b/doc/ref/srfi-modules.texi
@@ -677,8 +677,8 @@ Maps each seed value to next seed value.
@item seed
The state value for the unfold.
-@item tail-gen
-Creates the tail of the list; defaults to @code{(lambda (x) '())}.
+@item tail
+The tail of the list; defaults to @code{'()}.
@end table
@end deffn
diff --git a/libguile/__scm.h b/libguile/__scm.h
index 0a749bec5..31e395285 100644
--- a/libguile/__scm.h
+++ b/libguile/__scm.h
@@ -77,7 +77,7 @@
* 1) int foo (char arg) SCM_NORETURN;
*/
#ifdef __GNUC__
-#define SCM_NORETURN __attribute__ ((noreturn))
+#define SCM_NORETURN __attribute__ ((__noreturn__))
#else
#define SCM_NORETURN
#endif
diff --git a/libguile/i18n.c b/libguile/i18n.c
index dc6d07d12..0f607f331 100644
--- a/libguile/i18n.c
+++ b/libguile/i18n.c
@@ -1535,7 +1535,9 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
codeset = nl_langinfo (CODESET);
}
- c_result = strdup (c_result);
+ if (c_result != NULL)
+ c_result = strdup (c_result);
+
unlock_locale_mutex ();
if (c_result == NULL)
diff --git a/libguile/throw.c b/libguile/throw.c
index 4b1885eed..244bcf153 100644
--- a/libguile/throw.c
+++ b/libguile/throw.c
@@ -442,7 +442,7 @@ scm_handle_by_throw (void *handler_data SCM_UNUSED, SCM tag, SCM args)
}
SCM
-scm_ithrow (SCM key, SCM args, int noreturn SCM_UNUSED)
+scm_ithrow (SCM key, SCM args, int no_return SCM_UNUSED)
{
return scm_throw (key, args);
}
diff --git a/libguile/throw.h b/libguile/throw.h
index 6cf6790b6..62592d22e 100644
--- a/libguile/throw.h
+++ b/libguile/throw.h
@@ -79,7 +79,7 @@ SCM_API int scm_exit_status (SCM args);
SCM_API SCM scm_catch_with_pre_unwind_handler (SCM tag, SCM thunk, SCM handler, SCM lazy_handler);
SCM_API SCM scm_catch (SCM tag, SCM thunk, SCM handler);
SCM_API SCM scm_with_throw_handler (SCM tag, SCM thunk, SCM handler);
-SCM_API SCM scm_ithrow (SCM key, SCM args, int noreturn);
+SCM_API SCM scm_ithrow (SCM key, SCM args, int no_return);
SCM_API SCM scm_throw (SCM key, SCM args);
SCM_INTERNAL void scm_init_throw (void);
diff --git a/module/ice-9/psyntax-pp.scm b/module/ice-9/psyntax-pp.scm
index 36194123d..eeffecf38 100644
--- a/module/ice-9/psyntax-pp.scm
+++ b/module/ice-9/psyntax-pp.scm
@@ -3053,7 +3053,14 @@
((read-file
(lambda (fn dir k)
(let ((p (open-input-file
- (if (absolute-file-name? fn) fn (in-vicinity dir fn)))))
+ (if (absolute-file-name? fn)
+ fn
+ (if dir
+ (in-vicinity dir fn)
+ (syntax-violation
+ 'include
+ "relative file name only allowed when the include form is in a file"
+ x))))))
(let ((enc (file-encoding p)))
(set-port-encoding! p (let ((t enc)) (if t t "UTF-8")))
(let f ((x (read p)) (result '()))
diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index 4b66b8b04..5368785c2 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -3056,9 +3056,15 @@
(define read-file
(lambda (fn dir k)
(let* ((p (open-input-file
- (if (absolute-file-name? fn)
- fn
- (in-vicinity dir fn))))
+ (cond ((absolute-file-name? fn)
+ fn)
+ (dir
+ (in-vicinity dir fn))
+ (else
+ (syntax-violation
+ 'include
+ "relative file name only allowed when the include form is in a file"
+ x)))))
(enc (file-encoding p)))
;; Choose the input encoding deterministically.