cvsuser     04/06/23 05:41:55

  Modified:    include/parrot pobj.h
               lib/Parrot Vtable.pm
               src      objects.c
               t/pmc    objects.t
  Log:
  Pie-thon 4 - override a PMC method in subclass
  * new deleg_pmc delegates functions to it's 1st attribute
  * for class that subclass a PMC, create a special
    vtable that either dispatches as object or as a
    deleg_pmc class depending on the existance of the
    method
  
  Revision  Changes    Path
  1.44      +9 -9      parrot/include/parrot/pobj.h
  
  Index: pobj.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/pobj.h,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -w -r1.43 -r1.44
  --- pobj.h    9 May 2004 14:58:28 -0000       1.43
  +++ pobj.h    23 Jun 2004 12:41:40 -0000      1.44
  @@ -1,7 +1,7 @@
   /* pobj.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: pobj.h,v 1.43 2004/05/09 14:58:28 leo Exp $
  + *     $Id: pobj.h,v 1.44 2004/06/23 12:41:40 leo Exp $
    *  Overview:
    *     Parrot Object data members and flags enum
    *  Data Structure and Algorithms:
  
  
  
  1.40      +31 -1     parrot/lib/Parrot/Vtable.pm
  
  Index: Vtable.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/Vtable.pm,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -w -r1.39 -r1.40
  --- Vtable.pm 15 May 2004 22:12:04 -0000      1.39
  +++ Vtable.pm 23 Jun 2004 12:41:48 -0000      1.40
  @@ -1,5 +1,5 @@
   # Copyright: 2001-2004 The Perl Foundation.  All Rights Reserved.
  -# $Id: Vtable.pm,v 1.39 2004/05/15 22:12:04 dan Exp $
  +# $Id: Vtable.pm,v 1.40 2004/06/23 12:41:48 leo Exp $
   
   =head1 NAME
   
  @@ -204,6 +204,36 @@
   /* &end_gen */
   
   EOM
  +
  +    # finally the name mapping
  +    $macros .= <<"EOM";
  +/*
  + * vtable slot names
  + */
  +#ifdef PARROT_IN_OBJECTS_C
  +static const char * const Parrot_vtable_slot_names[] = {
  +    "",     /* Pointer to package this vtable belongs to */
  +    "",     /* 'type' value for MMD */
  +    "",     /* Name of class this vtable is for */
  +    "",     /* Flags. Duh */
  +    "",          /* space separated list of interfaces */
  +    "",          /* space separated list of classes */
  +    "",     /* To hang data off this vtable */
  +
  +    /* Vtable Functions */
  +EOM
  +    for my $entry (@{$vtable}) {
  +     $macros .= <<"EOM";
  +        \"__$entry->[1]\",
  +EOM
  +    }
  +    $macros .= <<"EOM";
  +    NULL
  +};
  +#endif
  +
  +EOM
  +
       $macros;
   }
   
  
  
  
  1.97      +84 -18    parrot/src/objects.c
  
  Index: objects.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/objects.c,v
  retrieving revision 1.96
  retrieving revision 1.97
  diff -u -w -r1.96 -r1.97
  --- objects.c 23 Jun 2004 08:52:15 -0000      1.96
  +++ objects.c 23 Jun 2004 12:41:51 -0000      1.97
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: objects.c,v 1.96 2004/06/23 08:52:15 leo Exp $
  +$Id: objects.c,v 1.97 2004/06/23 12:41:51 leo Exp $
   
   =head1 NAME
   
  @@ -18,6 +18,7 @@
   
   */
   
  +#define PARROT_IN_OBJECTS_C
   #include "parrot/parrot.h"
   #include <assert.h>
   
  @@ -91,7 +92,6 @@
           if (parent_attr_count) {
               STRING *parent_name;
               INTVAL parent_offset;
  -            STRING *FQ_name;
               STRING *partial_name;
   
               parent_name = VTABLE_get_string(interpreter,
  @@ -163,6 +163,64 @@
   
   /*
   
  +=item C<static void create_deleg_pmc_vtable(Interp *, PMC *class, STRING *name)>
  +
  +Create a vtable that dispatches either to the contained PMC in the first
  +attribute (deleg_pmc) or to an overridden method (delegate), depending
  +on the existance of the method for this class.
  +
  +*/
  +
  +static void
  +create_deleg_pmc_vtable(Interp *interpreter, PMC *class, STRING *class_name)
  +{
  +    PMC *vtable_pmc;
  +    VTABLE *vtable, *deleg_pmc_vtable, *delegate_vtable, *object_vtable;
  +    int i;
  +    const char *meth;
  +    STRING meth_str;
  +
  +    vtable_pmc = get_attrib_num((SLOTTYPE *)PMC_data(class), PCD_OBJECT_VTABLE);
  +    vtable = PMC_struct_val(vtable_pmc);
  +    deleg_pmc_vtable = Parrot_base_vtables[enum_class_deleg_pmc];
  +    object_vtable = Parrot_base_vtables[enum_class_ParrotObject];
  +    delegate_vtable = Parrot_base_vtables[enum_class_delegate];
  +
  +    memset(&meth_str, 0, sizeof(meth_str));
  +    meth_str.representation = enum_stringrep_one;
  +    for (i = 0; (meth = Parrot_vtable_slot_names[i]); ++i) {
  +        if (!*meth)
  +            continue;
  +        meth_str.strstart = meth;
  +        meth_str.strlen = strlen(meth);
  +        meth_str.hashval = 0;
  +        if (Parrot_find_global(interpreter, class_name, &meth_str)) {
  +            /*
  +             * if the method exists, keep the ParrotObject aka delegate vtable
  +             * slot
  +             */
  +            LVALUE_CAST(void **,vtable)[i] = ((void**)object_vtable)[i];
  +        }
  +        else {
  +            /*
  +             * if the method doesn't exist, put in the deleg_pmc vtable
  +             * but only, it ParrotObject hasn't overriden the method
  +             */
  +            if (((void **)delegate_vtable)[i] == ((void**)object_vtable)[i])
  +                LVALUE_CAST(void **,vtable)[i] = ((void**)deleg_pmc_vtable)[i];
  +            else
  +                LVALUE_CAST(void **,vtable)[i] = ((void**)object_vtable)[i];
  +        }
  +    }
  +    /*
  +     * finally if the methods are changed dynamically
  +     * this vtable must be changed too
  +     * s. src/global.c:Parrot_store_global()
  +     */
  +}
  +
  +/*
  +
   =item C<PMC *
   Parrot_single_subclass(Parrot_Interp ointerpreter, PMC *base_class,
                          STRING *child_class_name)>
  @@ -184,8 +242,6 @@
       PMC *child_class_array;
       PMC *classname_pmc;
       PMC *parents, *temp_pmc;
  -    VTABLE *new_vtable;
  -    INTVAL new_class_number;
       int parent_is_class;
   
       parent_is_class = PObj_is_class_TEST(base_class);
  @@ -229,11 +285,10 @@
       }
       else {
           /*
  -         * we have 1 parent
  +         * we have 1 parent, that get's unshifted below
            */
           temp_pmc = pmc_new(interpreter, enum_class_Array);
  -        VTABLE_set_integer_native(interpreter, temp_pmc, 1);
  -        VTABLE_set_pmc_keyed_int(interpreter, temp_pmc, 0, base_class);
  +        VTABLE_set_integer_native(interpreter, temp_pmc, 0);
       }
       VTABLE_unshift_pmc(interpreter, temp_pmc, base_class);
       set_attrib_num(child_class_array, PCD_ALL_PARENTS, temp_pmc);
  @@ -247,6 +302,16 @@
   
       rebuild_attrib_stuff(interpreter, child_class);
   
  +    if (!parent_is_class) {
  +        /* we append one attribute to hold the PMC */
  +        Parrot_add_attribute(interpreter, child_class,
  +                CONST_STRING(interpreter, "__value"));
  +        /*
  +         * then create a vtable derived from ParrotObject and
  +         * deleg_pmc - the ParrotObject vtable is already built
  +         */
  +        create_deleg_pmc_vtable(interpreter, child_class, child_class_name);
  +    }
       return child_class;
   }
   
  @@ -266,9 +331,6 @@
   {
       PMC *class_array;
       PMC *classname_pmc;
  -    INTVAL new_class_number;
  -    VTABLE *new_vtable;
  -    PMC *temp_pmc;
   
       /* Hang an array off the data pointer, empty of course */
       class_array = PMC_data(class) = new_attrib_array();
  @@ -395,16 +457,13 @@
   get_init_meth(Parrot_Interp interpreter, PMC *class,
             STRING *prop_str , STRING **meth_str)
   {
  -    PMC *prop;
  -    union {
  -        const void * __c_ptr;
  -        void * __ptr;
  -    } __ptr_u;
       STRING *meth;
       HashBucket *b;
       PMC *props;
  +
       *meth_str = NULL;
   #if 0
  +    PMC *prop;
       prop = VTABLE_getprop(interpreter, class, prop_str);
       if (!VTABLE_defined(interpreter, prop))
           return NULL;
  @@ -457,9 +516,17 @@
       for (i = nparents - 1; i >= 0; --i) {
           parent_class = VTABLE_get_pmc_keyed_int(interpreter,
                   classsearch_array, i);
  -        /* if its a PMC skip it for now */
  -        if (!PObj_is_class_TEST(parent_class))
  +        /* if its a PMC, we put one PMC of that type into
  +         * the attribute slot #0 and call init() on that PMC
  +         */
  +        if (!PObj_is_class_TEST(parent_class)) {
  +            PMC *attr = pmc_new_noinit(interpreter,
  +                    parent_class->vtable->base_type);
  +            SLOTTYPE *obj_data = PMC_data(object);
  +            set_attrib_num(obj_data, POD_FIRST_ATTRIB, attr);
  +            VTABLE_init(interpreter, attr);
               continue;
  +        }
           meth = get_init_meth(interpreter, parent_class,
                   CONST_STRING(interpreter, "BUILD"), &meth_str);
           /* no method found and no BUILD property set? */
  @@ -1074,7 +1141,6 @@
       SLOTTYPE *class_array;
       STRING *class_name;
       INTVAL idx;
  -    PMC *offs_hash;
       PMC *attr_hash = NULL;
       PMC *attr_array;
       STRING *full_attr_name;
  
  
  
  1.45      +53 -2     parrot/t/pmc/objects.t
  
  Index: objects.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/objects.t,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -w -r1.44 -r1.45
  --- objects.t 23 Jun 2004 08:52:19 -0000      1.44
  +++ objects.t 23 Jun 2004 12:41:55 -0000      1.45
  @@ -1,6 +1,6 @@
   #! perl -w
   # Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -# $Id: objects.t,v 1.44 2004/06/23 08:52:19 leo Exp $
  +# $Id: objects.t,v 1.45 2004/06/23 12:41:55 leo Exp $
   
   =head1 NAME
   
  @@ -16,7 +16,7 @@
   
   =cut
   
  -use Parrot::Test tests => 40;
  +use Parrot::Test tests => 41;
   use Test::More;
   
   output_is(<<'CODE', <<'OUTPUT', "findclass (base class)");
  @@ -1165,3 +1165,54 @@
   ok 3
   OUTPUT
   
  +output_is(<<'CODE', <<'OUTPUT', "PMC as classes - methods");
  +##PIR##
  +.sub main @MAIN
  +  .local pmc MyInt
  +  getclass $P0, "Integer"
  +  print "ok 1\n"
  +  subclass MyInt, $P0, "MyInt"
  +  print "ok 2\n"
  +  .local pmc i
  +  $I0 = find_type "MyInt"
  +  i = new $I0
  +  print "ok 3\n"
  +  i = 42     # set_integer is inherited from Integer
  +  print "ok 4\n"
  +  $I0 = i    # get_integer is overridden below
  +  print $I0
  +  print "\n"
  +  $S0 = i    # get_string is overridden below
  +  print $S0
  +  print "\n"
  +.end
  +
  +.namespace ["MyInt"]
  +.sub __get_integer method
  +   $I0 = classoffset self, "MyInt"
  +   $P0 = getattribute self, $I0
  +   $I0 = $P0
  +   .pcc_begin_return
  +   .return $I0
  +   .pcc_end_return
  +.end
  +.sub __get_string method
  +   $I0 = classoffset self, "MyInt"
  +   $P0 = getattribute self, $I0
  +   $I0 = $P0
  +   $S1 = $I0
  +   $S0 = "MyInt("
  +   $S0 .= $S1
  +   $S0 .= ")"
  +   .pcc_begin_return
  +   .return $S0
  +   .pcc_end_return
  +.end
  +CODE
  +ok 1
  +ok 2
  +ok 3
  +ok 4
  +42
  +MyInt(42)
  +OUTPUT
  
  
  

Reply via email to