1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00
Conflicts:
	.gitignore
	libguile/deprecated.c
This commit is contained in:
Andy Wingo 2013-11-28 14:53:03 +01:00
commit 6dd9810902
10 changed files with 97 additions and 138 deletions

4
.gitignore vendored
View file

@ -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

View file

@ -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)

View file

@ -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.
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.
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.
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

View file

@ -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

View file

@ -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

View file

@ -1535,7 +1535,9 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
codeset = nl_langinfo (CODESET);
}
if (c_result != NULL)
c_result = strdup (c_result);
unlock_locale_mutex ();
if (c_result == NULL)

View file

@ -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);
}

View file

@ -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);

View file

@ -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 '()))

View file

@ -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.