From 53d4df80c91d0c744e86df421572f60bb9a80261 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Wed, 20 Sep 2017 22:19:49 +0200 Subject: Remove references to tail arrays in the documentation * doc/ref/api-data.texi (Vtables, Structure Basics): Update to remove references to tail arrays, in preparation for deprecation. --- doc/ref/api-data.texi | 87 +++++++++++---------------------------------------- 1 file changed, 18 insertions(+), 69 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 7b10d34f4..7e36f7446 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000-2004, 2006-2016 +@c Copyright (C) 1996, 1997, 2000-2004, 2006-2017 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -8757,7 +8757,6 @@ records in Guile are implemented with structures. * Vtable Contents:: * Meta-Vtables:: * Vtable Example:: -* Tail Arrays:: @end menu @node Vtables @@ -8808,8 +8807,7 @@ Scheme level. This can be used for fields which should only be used from C code. @end itemize -Here are some examples. @xref{Tail Arrays}, for information on the -legacy tail array facility. +Here are some examples. @example (make-vtable "pw") ;; one writable field @@ -8840,12 +8838,11 @@ structure. @node Structure Basics @subsubsection Structure Basics -This section describes the basic procedures for working with -structures. @code{make-struct} creates a structure, and -@code{struct-ref} and @code{struct-set!} access its fields. +This section describes the basic procedures for working with structures. +@code{make-struct/no-tail} creates a structure, and @code{struct-ref} +and @code{struct-set!} access its fields. -@deffn {Scheme Procedure} make-struct vtable tail-size init @dots{} -@deffnx {Scheme Procedure} make-struct/no-tail vtable init @dots{} +@deffn {Scheme Procedure} make-struct/no-tail vtable init @dots{} Create a new structure, with layout per the given @var{vtable} (@pxref{Vtables}). @@ -8855,25 +8852,22 @@ put values in read-only fields. If there are fewer @var{init} arguments than fields then the defaults are @code{#f} for a Scheme field (type @code{p}) or 0 for an uninterpreted field (type @code{u}). -Structures also have the ability to allocate a variable number of -additional cells at the end, at their tails. However, this legacy -@dfn{tail array} facilty is confusing and inefficient, and so we do not -recommend it. @xref{Tail Arrays}, for more on the legacy tail array -interface. +The name is a bit strange, we admit. The reason for it is that Guile +used to have a @code{make-struct} that took an additional argument; +while we deprecate that old interface, @code{make-struct/no-tail} is the +new name for this functionality. -Type @code{s} self-reference fields, permission @code{o} opaque -fields, and the count field of a tail array are all ignored for the -@var{init} arguments, ie.@: an argument is not consumed by such a -field. An @code{s} is always set to the structure itself, an @code{o} -is always set to @code{#f} or 0 (with the intention that C code will -do something to it later), and the tail count is always the given -@var{tail-size}. +Type @code{s} self-reference fields and permission @code{o} opaque +fields are ignored for the @var{init} arguments, ie.@: an argument is +not consumed by such a field. An @code{s} is always set to the +structure itself and an @code{o} is always set to @code{#f} or 0 (with +the intention that C code will do something to it later). For example, @example (define v (make-vtable "prpwpw")) -(define s (make-struct v 0 123 "abc" 456)) +(define s (make-struct/no-tail v 123 "abc" 456)) (struct-ref s 0) @result{} 123 (struct-ref s 1) @result{} "abc" @end example @@ -8886,6 +8880,8 @@ There are a few ways to make structures from C. @code{scm_make_struct} takes a list, @code{scm_c_make_struct} takes variable arguments terminated with SCM_UNDEFINED, and @code{scm_c_make_structv} takes a packed array. + +For all of these, @var{tail_size} should be zero (as a SCM value). @end deftypefn @deffn {Scheme Procedure} struct? obj @@ -9197,53 +9193,6 @@ cases, the records facility is usually sufficient. But sometimes you need to make new kinds of data abstractions, and for that purpose, structs are here. -@node Tail Arrays -@subsubsection Tail Arrays - -Guile's structures have a facility whereby each instance of a vtable can -contain a variable-length tail array of values. The length of the tail -array is stored in the structure. This facility was originally intended -to allow C code to expose raw C structures with word-sized tail arrays -to Scheme. - -However, the tail array facility is confusing and doesn't work very -well. It is very rarely used, but it insinuates itself into all -invocations of @code{make-struct}. For this reason the clumsily-named -@code{make-struct/no-tail} procedure can actually be more elegant in -actual use, because it doesn't have a random @code{0} argument stuck in -the middle. - -Tail arrays also inhibit optimization by allowing instances to affect -their shapes. In the absence of tail arrays, all instances of a given -vtable have the same number and kinds of fields. This uniformity can be -exploited by the runtime and the optimizer. The presence of tail arrays -make some of these optimizations more difficult. - -Finally, the tail array facility is ad-hoc and does not compose with the -rest of Guile. If a Guile user wants an array with user-specified -length, it's best to use a vector. It is more clear in the code, and -the standard optimization techniques will do a good job with it. - -That said, we should mention some details about the interface. A vtable -that has tail array has upper-case permission descriptors: @code{W}, -@code{R} or @code{O}, correspoding to tail arrays of writable, -read-only, or opaque elements. A tail array permission descriptor may -only appear in the last element of a vtable layout. - -For exampple, @samp{pW} indicates a tail of writable Scheme-valued -fields. The @samp{pW} field itself holds the tail size, and the tail -fields come after it. - -@example -(define v (make-vtable "prpW")) ;; one fixed then a tail array -(define s (make-struct v 6 "fixed field" 'x 'y)) -(struct-ref s 0) @result{} "fixed field" -(struct-ref s 1) @result{} 2 ;; tail size -(struct-ref s 2) @result{} x ;; tail array ... -(struct-ref s 3) @result{} y -(struct-ref s 4) @result{} #f -@end example - @node Dictionary Types @subsection Dictionary Types -- cgit v1.2.3 From 04f48e94b573eaede0751110c583293cc34cd8f9 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 22 Sep 2017 11:23:00 +0200 Subject: Deprecate struct "self" slots * libguile/print.h (SCM_PRINT_STATE_LAYOUT): Use a normal slot instead of a self slot. * libguile/print.c (make_print_state): Initialize "handle" slot manually. * libguile/struct.c (issue_deprecation_warning_for_self_slots): New helper, called when making vtables to issue deprecation warnings for "self" slots. Avoids warning for the "self" slot that's part of the fixed vtable slots. (scm_i_struct_inherit_vtable_magic): Call issue_deprecation_warning_for_self_slots. * doc/ref/api-data.texi (Vtables, Structure Basics): Remove references to self slots. * NEWS: Add entry. --- NEWS | 12 +++++++++++- doc/ref/api-data.texi | 16 ++++------------ libguile/print.c | 1 + libguile/print.h | 4 ++-- libguile/struct.c | 20 ++++++++++++++++++++ 5 files changed, 38 insertions(+), 15 deletions(-) (limited to 'doc/ref/api-data.texi') diff --git a/NEWS b/NEWS index f13f40a86..78e3b30c3 100644 --- a/NEWS +++ b/NEWS @@ -26,7 +26,7 @@ If you don't care whether the URI is a relative-ref or not, use In the future `uri?' will return a true value only for URIs that specify a scheme. -** Tail arrays deprecated +** Struct tail arrays deprecated Guile's structures used to have a facility whereby each instance of a vtable can contain a variable-length tail array of values. The length @@ -57,6 +57,16 @@ will be removed from Guile 3.0. Likewise, `make-struct' / `scm_make_struct_no_tail'. Perhaps one day we will be able to reclaim the `make-struct' name! +** Struct "self" slots deprecated + +It used to be that you could make a structure vtable that had "self" +slots. Instances of that vtable would have those slots initialized to +the instance itself. This can be useful in C code where you might have +a pointer to the data array, and want to get the `SCM' handle for the +structure. However this was a little used complication without any use +in Scheme code. To replace it, just use "p" slots and initialize the +slot values manually on initialization. + * Bug fixes ** Enable GNU Readline 7.0's support for "bracketed paste". diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 7e36f7446..faddc3f65 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -8785,13 +8785,6 @@ Scheme level it's read and written as an unsigned integer. ``u'' stands for ``uninterpreted'' (it's not treated as a Scheme value), or ``unprotected'' (it's not marked during GC), or ``unsigned long'' (its size), or all of these things. - -@item -@code{s} -- a self-reference. Such a field holds the @code{SCM} value -of the structure itself (a circular reference). This can be useful in -C code where you might have a pointer to the data array, and want to -get the Scheme @code{SCM} handle for the structure. In Scheme code it -has no use. @end itemize The second letter for each field is a permission code, @@ -8857,11 +8850,10 @@ used to have a @code{make-struct} that took an additional argument; while we deprecate that old interface, @code{make-struct/no-tail} is the new name for this functionality. -Type @code{s} self-reference fields and permission @code{o} opaque -fields are ignored for the @var{init} arguments, ie.@: an argument is -not consumed by such a field. An @code{s} is always set to the -structure itself and an @code{o} is always set to @code{#f} or 0 (with -the intention that C code will do something to it later). +Fields with permission @code{o} opaque fields are ignored for the +@var{init} arguments, ie.@: an argument is not consumed by such a field. +An @code{o} slot is always set to @code{#f} or 0 (with the intention +that C code will do something to it later). For example, diff --git a/libguile/print.c b/libguile/print.c index 4d57a877d..24c532f29 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -196,6 +196,7 @@ make_print_state (void) { SCM print_state = scm_make_struct_no_tail (scm_print_state_vtable, SCM_EOL); scm_print_state *pstate = SCM_PRINT_STATE (print_state); + pstate->handle = print_state; pstate->ref_vect = scm_c_make_vector (PSTATE_SIZE, SCM_UNDEFINED); pstate->ceiling = SCM_SIMPLE_VECTOR_LENGTH (pstate->ref_vect); pstate->highlight_objects = SCM_EOL; diff --git a/libguile/print.h b/libguile/print.h index 14318c031..11f533c79 100644 --- a/libguile/print.h +++ b/libguile/print.h @@ -4,7 +4,7 @@ #define SCM_PRINT_H /* Copyright (C) 1995, 1996, 1998, 2000, 2001, 2003, 2004, 2006, 2008, - * 2010, 2012 Free Software Foundation, Inc. + * 2010, 2012, 2017 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -53,7 +53,7 @@ do { \ #define SCM_COERCE_OUTPORT(p) \ (SCM_PORT_WITH_PS_P (p) ? SCM_PORT_WITH_PS_PORT (p) : p) -#define SCM_PRINT_STATE_LAYOUT "sruwuwuwuwuwpwuwuwurprpw" +#define SCM_PRINT_STATE_LAYOUT "pruwuwuwuwuwpwuwuwurprpw" typedef struct scm_print_state { SCM handle; /* Struct handle */ int revealed; /* Has the state escaped to Scheme? */ diff --git a/libguile/struct.c b/libguile/struct.c index 08451e741..3ebe89064 100644 --- a/libguile/struct.c +++ b/libguile/struct.c @@ -30,6 +30,7 @@ #include "libguile/_scm.h" #include "libguile/async.h" #include "libguile/chars.h" +#include "libguile/deprecation.h" #include "libguile/eval.h" #include "libguile/alist.h" #include "libguile/hashtab.h" @@ -229,6 +230,23 @@ scm_is_valid_vtable_layout (SCM layout) return 1; } +static void +issue_deprecation_warning_for_self_slots (SCM vtable) +{ + SCM olayout; + size_t idx, first_user_slot = 0; + + olayout = scm_symbol_to_string (SCM_VTABLE_LAYOUT (vtable)); + if (SCM_VTABLE_FLAG_IS_SET (vtable, SCM_VTABLE_FLAG_VTABLE)) + first_user_slot = scm_vtable_offset_user; + + for (idx = first_user_slot * 2; idx < scm_c_string_length (olayout); idx += 2) + if (scm_is_eq (scm_c_string_ref (olayout, idx), SCM_MAKE_CHAR ('s'))) + scm_c_issue_deprecation_warning + ("Vtables with \"self\" slots are deprecated. Initialize these " + "fields manually."); +} + /* Have OBJ, a newly created vtable, inherit flags from VTABLE. VTABLE is a vtable-vtable and OBJ is an instance of VTABLE. */ void @@ -288,6 +306,8 @@ scm_i_struct_inherit_vtable_magic (SCM vtable, SCM obj) SCM_SET_VTABLE_FLAGS (obj, SCM_VTABLE_FLAG_APPLICABLE); } + issue_deprecation_warning_for_self_slots (obj); + SCM_SET_VTABLE_FLAGS (obj, SCM_VTABLE_FLAG_VALIDATED); } #undef FUNC_NAME -- cgit v1.2.3