All -
    I fail to see the reason for imposing that all
variables
"know" how to perform ops upon themselves. An operation is 
separate from the data it operates on. Therefore, I propose
the following vtbl scheme, with two goals:
  1. that the minimal vtbl be just that, minimal
  2. that it be possible (convenient) to override ops as 
     needed
First, a few basic types (these are sample only, and should
be beaten on for cach-friendliness, etc. once a design is
formalized).

typedef struct _ovl {
    U32   ov_type;
    U32   ov_flags;
    void *ov_vtbl;
    void *ov_data;
    struct _ovl *ov_next;
} OVERLOAD;

typedef union {
    SCALAR_VTBL s;
    ARRAY_VTBL  a;
    HASH_VTBL   h;
} SV_VTBL;

typedef struct sv {
    void     *sv_data;
    OVERLOAD *sv_magic;
    SV_VTBL  *sv_vtbl;
    U32      sv_flags; /* and type (SV, AV, HV) */
(... GC stuff ... MT-safe stuff ...)
} SV, *PMC;

SV_VTBL, then, supports basic operations on perlish data
types (get, store, and a few housekeeping things). Since
noone (outside perl and libperl.so) should be directly
calling vtbl functions, this makes it easy to put checks in
that a variable is the appropriate type (ie, av_fetch will
die if the variable is really a scalar).

Here are what each data type should support (each get/set
may require an argument giving a bit more detail (ie, U16
vs. I64, UTF8 vs. UTF16-bigendian, etc.)):

SCALAR_VTBL:
    get_int
    get_string
    get_real
    get_ref
    num_sign /* positive or negative (or zero?)*/
    num_is_integral
    set_int
    set_string
    set_real
    set_ref
    set_multival /* == perl5ish 
                        sv_setpv(sv...);
                        sv_setiv(sv,...);
                        SvPOK_on(sv); (esp this part)
                  */
    undef
    construct
    finalize

ARRAY_VTBL:
    get_at
    set_at
    grow /* a hint on where we plan to put values, ie 
            av->sv_vtbl.a.grow(bottom_ix, top_ix) */
    size
    clear /* @av = (); */
    undef /* undef @av; */
    get_interator
    construct
    finalize

HASH_VTBL:
    fetch
    store
    get_iterator
/* not sure if these two are needed */
    get_iterator_keys
    get_iterator_values
    clear
    undef
    size
    construct
    finalize

In order to allow overriding of opcodes for, say, BigInts,
several types of OVERLOAD are defined (4 basic types (flags
in bottom byte of ov_type?) are defined, based on what
flavor of vtbl is in ov_vtbl). These are OV_GET, OV_SET,
OV_RANDOM, OV_OPS and are denoted in sv->sv_flags. The
first three correspond to the perl5 GMG, SMG, and RMG. The
last marks that the vtbl is an overload of one or more
opcodes. Every op checks to see if it is overloaded, and if
it is, calls that. Some ops don't need to (ie, vec() can
just do a set_string and add an OVERLOAD for the bitwise
ops).

If necessary, additional subclasses of OV_OPS may be
defined (ie, OV_NUMERIC, OV_STRING, OV_IO).

-- BKS

__________________________________________________
Do You Yahoo!?
Yahoo! Mail - Free email you can access from anywhere!
http://mail.yahoo.com/

Reply via email to