[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: RFC: Foreign objects facility
Re: RFC: Foreign objects facility
Tue, 29 Apr 2014 08:56:39 -0700
On Sun, Apr 27, 2014 at 6:17 AM, Andy Wingo <address@hidden> wrote:
> SMOBs have a few problems.
> 1) They are limited in number to 255.
> 2) It's difficult to refer to a SMOB type from Scheme. You can use
> class-of once you have an object, but the class-of isn't exactly
> the same as the SMOB tc16, and getting the type beforehand is
> gnarly. (See http://article.gmane.org/gmane.comp.gdb.patches/96857
> for an example).
> 3) You can't create SMOB types from Scheme. This goes against our
> general trend of making Scheme more powerful.
> 4) You can't create SMOB objects from Scheme.
> 5) Similarly, you can't access SMOB fields from Scheme.
> 6) You can't subclass SMOB types. (Some people would like this
> 7) There is legacy code out there that uses e.g. SCM_SETCDR to set
> smob fields. (This is terrible, but it exists:
> for an example.)
> 8) The single/double SMOB thing is outdated and bogus. Objects should
> be able to have any number of fields.
> 9) We document mark functions in the manual, even recommending them,
> but they are really difficult to get right (see
> and almost always a bad design -- the BDW GC can do a better job
> without them.
> And yet, if we consider the generic problem of wrapping C objects in
> Scheme objects, it's clear that we have more solutions now than we used
> to -- raw #<pointer> values, define-wrapped-pointer-type, etc. But
> there's nothing that's accessible to C like SMOBs are, so people that
> use the libguile interface to wrap C types and values are out of luck.
> I propose to provide a new interface that will eventually make SMOBs
> obsolete. This new interface is based on structs with raw fields -- the
> 'u' fields. (See
> for description of 'u' fields. Note that the documentation is wrong --
> these fields are indeed traced by the GC.)
> Here is the proposed C API:
> SCM scm_make_foreign_object_type (SCM name, SCM slot_names,
> scm_t_struct_finalize finalizer);
> void scm_assert_foreign_object_type (SCM type, SCM val);
> SCM scm_make_foreign_object_1 (SCM type, scm_t_bits val0);
> SCM scm_make_foreign_object_2 (SCM type, scm_t_bits val0,
> scm_t_bits val1);
> SCM scm_make_foreign_object_3 (SCM type, scm_t_bits val0,
> scm_t_bits val1, scm_t_bits val2);
> SCM scm_make_foreign_object_n (SCM type, size_t n, scm_t_bits vals);
> scm_t_bits scm_foreign_object_ref (SCM obj, size_t n);
> void scm_foreign_object_set_x (SCM obj, size_t n, scm_t_bits val);
> The finalizer may be NULL. The scm_make_foreign_object* functions are
> just scm_make_struct without the no_tail arguments, and interpreting the
> values as raw untagged values, not unpacked SCM values. Same thing with
The struct interface, contrary to what the documentation says, takes a
stdarg list beginning with the number of fields (and not terminated
with SCM_UNDEFINED), instead of _1, _2, _3. fwiw, I would use that
over the _n version. I'd probably even use it instead of _1,_2,_3,
but I know some people like the comfortableness of having the compiler
verify the number of args is correct. I'm not sure if gcc could be
extended to handle verifying stdarg functions where one parameter
specifies the number of stdarg parms (assuming it doesn't support that
fwiw, structs already provide most of what is needed.
I have a few gdb objects using them, and it doesn't seem too bad.
I think you should fix/extend the struct interface instead of
inventing something new: given that structs already have
"uninterpreted" it is most of the way there already. It's already
intended to solve the problem you're trying to solve.
Its API just needs a way to set/ref "uninterpreted" values directly.
Plus making foreign objects completely usable from Scheme kinda
removes any usefulness of having "foreign" in the name.
With a bit of tweaking of the struct interface you're done.
So why invent something new?