diff options
author | Andy Wingo <wingo@pobox.com> | 2010-08-29 11:37:29 -0700 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2010-08-29 11:41:42 -0700 |
commit | a2220d7ea406eed83b5225cc7babbe9a4949643b (patch) | |
tree | f18f67c63924440b17470423fca1b193e7071e5e /libguile | |
parent | c89920a71ff1d2201c5af8780feaa936faf2c7a3 (diff) | |
download | guile-a2220d7ea406eed83b5225cc7babbe9a4949643b.tar.gz |
add flag to vtables to indicate that their layout is valid
* libguile/struct.h (SCM_VTABLE_FLAG_VALIDATED): New flag, indicates
that the layout of a vtable has been validated. The other flags have
been renumbered.
* libguile/struct.c (scm_i_struct_inherit_vtable_magic): Set the
VALIDATED flag if everything goes through.
(scm_struct_vtable_p): If the struct should be a vtable but isn't
validated, throw an error.
(scm_make_vtable_vtable): Validate the incoming user_fields layout
bit. Set the VALIDATED flag.
(scm_c_make_structv): Add a comment about the case in which we delay
scm_i_struct_inherit_vtable_magic.
Diffstat (limited to 'libguile')
-rw-r--r-- | libguile/struct.c | 30 | ||||
-rw-r--r-- | libguile/struct.h | 32 |
2 files changed, 37 insertions, 25 deletions
diff --git a/libguile/struct.c b/libguile/struct.c index e00b526e2..c784f59bb 100644 --- a/libguile/struct.c +++ b/libguile/struct.c @@ -260,7 +260,7 @@ scm_i_struct_inherit_vtable_magic (SCM vtable, SCM obj) /* Verify that OBJ is a valid vtable. */ if (! scm_is_valid_vtable_layout (SCM_VTABLE_LAYOUT (obj))) - scm_misc_error (FUNC_NAME, "invalid layout for new vtable: ~a", + SCM_MISC_ERROR ("invalid layout for new vtable: ~a", scm_list_1 (SCM_VTABLE_LAYOUT (obj))); set_vtable_layout_flags (obj); @@ -286,7 +286,7 @@ scm_i_struct_inherit_vtable_magic (SCM vtable, SCM obj) scm_from_size_t (4), scm_from_size_t (0), scm_from_size_t (4)))) - scm_misc_error (FUNC_NAME, "invalid applicable-with-setter struct layout", + SCM_MISC_ERROR ("invalid applicable-with-setter struct layout", scm_list_1 (olayout)); SCM_SET_VTABLE_FLAGS (obj, SCM_VTABLE_FLAG_APPLICABLE | SCM_VTABLE_FLAG_SETTER); } @@ -297,10 +297,12 @@ scm_i_struct_inherit_vtable_magic (SCM vtable, SCM obj) scm_from_size_t (2), scm_from_size_t (0), scm_from_size_t (2)))) - scm_misc_error (FUNC_NAME, "invalid applicable struct layout", + SCM_MISC_ERROR ("invalid applicable struct layout", scm_list_1 (olayout)); SCM_SET_VTABLE_FLAGS (obj, SCM_VTABLE_FLAG_APPLICABLE); } + + SCM_SET_VTABLE_FLAGS (obj, SCM_VTABLE_FLAG_VALIDATED); } #undef FUNC_NAME @@ -396,9 +398,13 @@ SCM_DEFINE (scm_struct_vtable_p, "struct-vtable?", 1, 0, 0, "Return @code{#t} iff @var{x} is a vtable structure.") #define FUNC_NAME s_scm_struct_vtable_p { - return scm_from_bool - (SCM_STRUCTP (x) - && SCM_STRUCT_VTABLE_FLAG_IS_SET (x, SCM_VTABLE_FLAG_VTABLE)); + if (!SCM_STRUCTP (x) + || !SCM_STRUCT_VTABLE_FLAG_IS_SET (x, SCM_VTABLE_FLAG_VTABLE)) + return SCM_BOOL_F; + if (!SCM_VTABLE_FLAG_IS_SET (x, SCM_VTABLE_FLAG_VALIDATED)) + SCM_MISC_ERROR ("vtable has invalid layout: ~A", + scm_list_1 (SCM_VTABLE_LAYOUT (x))); + return SCM_BOOL_T; } #undef FUNC_NAME @@ -487,8 +493,10 @@ scm_c_make_structv (SCM vtable, size_t n_tail, size_t n_init, scm_t_bits *init) scm_struct_init (obj, layout, n_tail, n_init, init); - /* only check things and inherit magic if the layout was passed as an initarg. - something of a hack, but it's for back-compatibility. */ + /* If we're making a vtable, validate its layout and inherit + flags. However we allow for separation of allocation and + initialization, to humor GOOPS, so only validate if the layout was + passed as an initarg. */ if (SCM_VTABLE_FLAG_IS_SET (vtable, SCM_VTABLE_FLAG_VTABLE) && scm_is_true (SCM_VTABLE_LAYOUT (obj))) scm_i_struct_inherit_vtable_magic (vtable, obj); @@ -633,6 +641,9 @@ SCM_DEFINE (scm_make_vtable_vtable, "make-vtable-vtable", 2, 0, 1, fields = scm_string_append (scm_list_2 (required_vtable_fields, user_fields)); layout = scm_make_struct_layout (fields); + if (!scm_is_valid_vtable_layout (layout)) + SCM_MISC_ERROR ("invalid user fields", scm_list_1 (user_fields)); + basic_size = scm_i_symbol_length (layout) / 2; n_tail = scm_to_size_t (tail_array_size); @@ -648,7 +659,8 @@ SCM_DEFINE (scm_make_vtable_vtable, "make-vtable-vtable", 2, 0, 1, SCM_CRITICAL_SECTION_END; scm_struct_init (obj, layout, n_tail, n_init, v); - SCM_SET_VTABLE_FLAGS (obj, SCM_VTABLE_FLAG_VTABLE); + SCM_SET_VTABLE_FLAGS (obj, + SCM_VTABLE_FLAG_VTABLE | SCM_VTABLE_FLAG_VALIDATED); return obj; } diff --git a/libguile/struct.h b/libguile/struct.h index d2a05af2a..7a4d63521 100644 --- a/libguile/struct.h +++ b/libguile/struct.h @@ -102,22 +102,22 @@ struct's vtable has the setter flag set. */ -#define SCM_VTABLE_FLAG_VTABLE (1L << 0) /* instances of this vtable are themselves vtables? */ -#define SCM_VTABLE_FLAG_APPLICABLE_VTABLE (1L << 1) /* instances of this vtable are applicable vtables? */ -#define SCM_VTABLE_FLAG_APPLICABLE (1L << 2) /* instances of this vtable are applicable? */ -#define SCM_VTABLE_FLAG_SETTER_VTABLE (1L << 3) /* instances of this vtable are applicable-with-setter vtables? */ -#define SCM_VTABLE_FLAG_SETTER (1L << 4) /* instances of this vtable are applicable-with-setters? */ -#define SCM_VTABLE_FLAG_SIMPLE (1L << 5) /* instances of this vtable have only "p" fields */ -#define SCM_VTABLE_FLAG_SIMPLE_RW (1L << 6) /* instances of this vtable have only "pw" fields */ -#define SCM_VTABLE_FLAG_SMOB_0 (1L << 7) -#define SCM_VTABLE_FLAG_GOOPS_0 (1L << 8) -#define SCM_VTABLE_FLAG_GOOPS_1 (1L << 9) -#define SCM_VTABLE_FLAG_GOOPS_2 (1L << 10) -#define SCM_VTABLE_FLAG_GOOPS_3 (1L << 11) -#define SCM_VTABLE_FLAG_GOOPS_4 (1L << 12) -#define SCM_VTABLE_FLAG_GOOPS_5 (1L << 13) -#define SCM_VTABLE_FLAG_GOOPS_6 (1L << 14) -#define SCM_VTABLE_FLAG_GOOPS_7 (1L << 15) +#define SCM_VTABLE_FLAG_VALIDATED (1L << 0) /* the layout of this vtable been validated? */ +#define SCM_VTABLE_FLAG_VTABLE (1L << 1) /* instances of this vtable are themselves vtables? */ +#define SCM_VTABLE_FLAG_APPLICABLE_VTABLE (1L << 2) /* instances of this vtable are applicable vtables? */ +#define SCM_VTABLE_FLAG_APPLICABLE (1L << 3) /* instances of this vtable are applicable? */ +#define SCM_VTABLE_FLAG_SETTER_VTABLE (1L << 4) /* instances of this vtable are applicable-with-setter vtables? */ +#define SCM_VTABLE_FLAG_SETTER (1L << 5) /* instances of this vtable are applicable-with-setters? */ +#define SCM_VTABLE_FLAG_SIMPLE (1L << 6) /* instances of this vtable have only "p" fields */ +#define SCM_VTABLE_FLAG_SIMPLE_RW (1L << 7) /* instances of this vtable have only "pw" fields */ +#define SCM_VTABLE_FLAG_RESERVED_0 (1L << 8) +#define SCM_VTABLE_FLAG_RESERVED_1 (1L << 9) +#define SCM_VTABLE_FLAG_RESERVED_2 (1L << 10) +#define SCM_VTABLE_FLAG_SMOB_0 (1L << 11) +#define SCM_VTABLE_FLAG_GOOPS_0 (1L << 12) +#define SCM_VTABLE_FLAG_GOOPS_1 (1L << 13) +#define SCM_VTABLE_FLAG_GOOPS_2 (1L << 14) +#define SCM_VTABLE_FLAG_GOOPS_3 (1L << 15) #define SCM_VTABLE_USER_FLAG_SHIFT 16 typedef void (*scm_t_struct_finalize) (SCM obj); |