pika-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pika-dev] vtable bug (Re: Replacing cport [...])


From: Tom Lord
Subject: [Pika-dev] vtable bug (Re: Replacing cport [...])
Date: Wed, 17 Mar 2004 08:35:55 -0800 (PST)

    > From: Matthew Dempsky <address@hidden>

    > So basically we'll have something like:

    > struct scm_port_binary_data
    > {
    >   int fd;
    >   enum uni_encoding_scheme enc;
    > };

    > along with

    > struct scm_port_vtable
    > {
    >   sizeof (scm_port_binary_data), 0, 0, 0,
    > 
    >   SCM_VTABLE_DISCIPLINE_INITIALIZERS (scm_port_)
    > };

    > and then all the scm_port_* functions.  

Yeah, although this makes me realize that there's a little API bug.
Well, annoyance more than bug.

The vtables interface from reps has:

        {ref,set} x {slot,limb_elt,n_limb_elts}

        ;;
        ;; except that ref_n_limb_elts is spelled n_limb_elts
        ;;

It also has:

        value_vtable

All of that's fine.

Unfortunately, it also has:

        void * scm_binary_data_addr (t_scm_arena arena, t_scm_word * value);

That one is problematic.  Unless VALUE is locked, the address returned
can not be trusted.  A copying collector can move it at any time.
(This would be a good example of how even "noop" locking code can be
handy --- scm_binary_data_addr could verify that VALUE is, indeed,
locked.)

I think it would be fairly horrid, just convenience-wise, to require
locking in every case.  So, vtable objects need some additional
functions:

        scm_ref_binary_data (void * dst,
                             t_scm_arena arena,
                             t_scm_word * value,
                             size_t start,
                             size_t end);

        scm_set_binary_data (t_scm_arena arena,
                             t_scm_word * value,
                             size_t start,
                             size_t end,
                             void * src);

which copy to and from the SRC..END-1 bytes of binary data in *VALUE.

Ports code can use something like:

        struct scm_port_binary_data port_data;

        scm_ref_binary_data ((void *)&port_data,
                             arena,
                             port,
                             0,
                             sizeof (port_data));


(That _can_ be implemented generically using just object locking and
scm_binary_data_addr but I think it's better to say that those two
functions should really be exported from reps.  Full object locking is
heavier than will be needed for some GC strategies.)

The ports implementation should have convenience functions along the
line of:

        int scm_port_fd (t_scm_arena * arena, t_scm_word * value);


        enum uni_encoding_scheme
        scm_port_encoding (t_scm_arena * arena, t_scm_word * value);

although, for now, none of the other code outside of ports.c should 
have any need for scm_port_fd.   (When POSIX/vu_* bindings are added, it 
will be useful.)


    > Also, struct cport* everywhere
    > gets changed to t_scm_word *.  The functions that actually perform IO
    > now need to do error detection that the scm_word is of the correct
    > type (since it won't be type-checked at compile time anymore), but
    > they also don't need to bother with the cport_vtable indirection
    > anymore.

    > I expect cport_vtables to go away because any port structure we need
    > can probably be filled in at the VU level (file, socket, string, etc.)
    > as a virtual fd if needed.

That's right.

I can imagine, way, way down the line the possibility of Scheme ports
that have user-defined behavior and _don't_ use the VU hooks to
achieve that.  That would be done by making the four I/O functions in
cport.[ch] essentially into generics.  We'd have to decide at that
time what the abstraction is that's between Scheme ports and VU fds.

In other words, all other code currently in libscm should continue to
go through those I/O functions even though, as you say, they can for
now (and for the forseeable future) call vu_* themselves, directly.
There shouldn't be vu_ calls outside of ports.[ch] until POSIX/vu_*
bindings are added.

-t




reply via email to

[Prev in Thread] Current Thread [Next in Thread]