cvsuser     04/02/25 12:49:45

  Modified:    include/parrot objects.h
               ops      object.ops
               src      objects.c
  Log:
  Zeno's object system inches ever closer
  
  Revision  Changes    Path
  1.17      +2 -1      parrot/include/parrot/objects.h
  
  Index: objects.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/objects.h,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -w -r1.16 -r1.17
  --- objects.h 25 Feb 2004 14:48:40 -0000      1.16
  +++ objects.h 25 Feb 2004 20:49:40 -0000      1.17
  @@ -1,7 +1,7 @@
   /* objects.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: objects.h,v 1.16 2004/02/25 14:48:40 dan Exp $
  + *     $Id: objects.h,v 1.17 2004/02/25 20:49:40 dan Exp $
    *  Overview:
    *     Parrot class and object header stuff
    *  Data Structure and Algorithms:
  @@ -50,6 +50,7 @@
   PMC *Parrot_get_attrib_by_num(Parrot_Interp, PMC *, INTVAL);
   void Parrot_set_attrib_by_num(Parrot_Interp, PMC *, INTVAL, PMC *);
   INTVAL Parrot_get_attrib_num(Parrot_Interp, PMC *, STRING *);
  +INTVAL Parrot_class_offset(Parrot_Interp, PMC *, STRING *);
   
   #endif
   
  
  
  
  1.28      +17 -0     parrot/ops/object.ops
  
  Index: object.ops
  ===================================================================
  RCS file: /cvs/public/parrot/ops/object.ops,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -w -r1.27 -r1.28
  --- object.ops        25 Feb 2004 14:48:47 -0000      1.27
  +++ object.ops        25 Feb 2004 20:49:43 -0000      1.28
  @@ -308,6 +308,23 @@
       goto NEXT();
   }
   
  +=item B<classoffset>(out INT, in PMC, in STR)
  +
  +Returns the offset of the first attribute for class $3 in object $2.
  +Throws an exception $3 isn't in $2's hierarchy.
  +
  +=cut
  +
  +op classoffset(out INT, in PMC, in STR) {
  +    INTVAL offset;
  +    offset = Parrot_class_offset(interpreter, $2, $3);
  +    if (offset < 0) {
  +        internal_exception(NO_CLASS, "Class not parent of object");
  +    }
  +    $1 = offset;
  +    goto NEXT();
  +}
  +
   
   =item B<adddoes>(in PMC, in STR)
   
  
  
  
  1.40      +132 -2    parrot/src/objects.c
  
  Index: objects.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/objects.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -w -r1.39 -r1.40
  --- objects.c 25 Feb 2004 20:39:11 -0000      1.39
  +++ objects.c 25 Feb 2004 20:49:45 -0000      1.40
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: objects.c,v 1.39 2004/02/25 20:39:11 scog Exp $
  +$Id: objects.c,v 1.40 2004/02/25 20:49:45 dan Exp $
   
   =head1 NAME
   
  @@ -55,6 +55,118 @@
               stash, globalname);
   }
   
  +/* Take the class and completely rebuild the atttribute stuff for
  +   it. Horribly destructive, and definitely not a good thing to do if
  +   there are instantiated objects for the class */
  +static void
  +rebuild_attrib_stuff(Parrot_Interp interpreter, PMC *class) {
  +    INTVAL cur_offset = POD_FIRST_ATTRIB;
  +    PMC *obj_array;
  +    PMC *attr_offset_hash;
  +    PMC *class_offset_hash;
  +    PMC *parent_array;
  +    PMC *a_parent_class;
  +    STRING *classname;
  +    INTVAL class_offset;
  +    INTVAL parent_class_count;
  +
  +    obj_array = PMC_data(class);
  +    attr_offset_hash = pmc_new(interpreter, enum_class_OrderedHash);
  +    class_offset_hash = pmc_new(interpreter, enum_class_OrderedHash);
  +    parent_array = VTABLE_get_pmc_keyed_int(interpreter, obj_array,
  +                                            PCD_ALL_PARENTS);
  +    parent_class_count = VTABLE_elements(interpreter, parent_array);
  +    if (parent_class_count) {
  +        for (class_offset = 0; class_offset < parent_class_count;
  +             class_offset++) {
  +            INTVAL parent_attr_count;
  +            PMC *a_parent_array;
  +            PMC *parent_attrib_array;
  +            a_parent_class = VTABLE_get_pmc_keyed_int(interpreter,
  +                                                      parent_array,
  +                                                      class_offset);
  +            a_parent_array = PMC_data(a_parent_class);
  +            parent_attrib_array = VTABLE_get_pmc_keyed_int(interpreter,
  +                                                           a_parent_array,
  +                                                           PCD_CLASS_ATTRIBUTES);
  +            parent_attr_count = VTABLE_elements(interpreter, parent_attrib_array);
  +            
  +            /* If there are any parent attributes, then go add the
  +               parent to this class' attribute info things */
  +            if (parent_attr_count) {
  +                STRING *parent_name;
  +                INTVAL parent_offset;
  +                STRING *FQ_name;
  +                STRING *partial_name;
  +                parent_name = VTABLE_get_string_keyed_int(interpreter,
  +                                                          a_parent_array,
  +                                                          PCD_CLASS_NAME);
  +                /* Note the current offset as where this class'
  +                   attributes start */
  +                VTABLE_set_integer_keyed_str(interpreter,
  +                                             attr_offset_hash,
  +                                             parent_name, cur_offset);
  +                partial_name = string_concat(interpreter, parent_name,
  +                                             string_from_cstring(interpreter, "\0", 
1),
  +                                             0);
  +                for (parent_offset = 0; parent_offset < parent_attr_count;
  +                     parent_offset++) {
  +                    STRING *attr_name;
  +                    STRING *full_name;
  +                    attr_name = VTABLE_get_string_keyed_int(interpreter, 
parent_attrib_array, parent_offset);
  +                    full_name = string_concat(interpreter, partial_name, attr_name, 
0);
  +                    VTABLE_set_integer_keyed_str(interpreter, attr_offset_hash, 
full_name, cur_offset++);
  +                }
  +            }
  +
  +        }
  +    }
  +
  +    /* Now append our own. To make things easier, we make sure we
  +       always appear in the offset list, even if we don't have any
  +       attributes. That way the append code for adding attributes to a
  +       child class works better */
  +    classname = VTABLE_get_string_keyed_int(interpreter, obj_array,
  +                                            PCD_CLASS_NAME);
  +    VTABLE_set_integer_keyed_str(interpreter, attr_offset_hash, classname,
  +                                 cur_offset);
  +    {
  +        PMC *attribs;
  +        INTVAL attr_count;
  +        
  +        attribs = VTABLE_get_pmc_keyed_int(interpreter, obj_array,
  +                                           PCD_CLASS_ATTRIBUTES);
  +        attr_count = VTABLE_elements(interpreter, attribs);
  +        if (attr_count) {
  +            STRING *partial_name;
  +            INTVAL offset;
  +            partial_name = string_concat(interpreter, classname,
  +                                         string_from_cstring(interpreter, "\0", 1),
  +                                         0);
  +
  +            for (offset = 0; offset < attr_count; offset++) {
  +                STRING *attr_name;
  +                STRING *full_name;
  +                attr_name = VTABLE_get_string_keyed_int(interpreter, attribs,
  +                                                        offset);
  +                full_name = string_concat(interpreter, partial_name, attr_name, 0);
  +                VTABLE_set_integer_keyed_str(interpreter, attr_offset_hash, 
full_name, cur_offset++);
  +            }
  +        }
  +    }
  +            
  +
  +    /* And replace what was in there with the new ones */
  +    VTABLE_set_pmc_keyed_int(interpreter, obj_array, PCD_ATTRIBUTES,
  +                             attr_offset_hash);
  +    VTABLE_set_pmc_keyed_int(interpreter, obj_array, PCD_ATTRIB_OFFS,
  +                             class_offset_hash);
  +    /* And note the totals */
  +    class->cache.int_val = cur_offset;
  +
  +    return;
  +}
  +
   /*
   
   =item C<PMC *
  @@ -439,6 +551,7 @@
               }
           }
       }
  +    rebuild_attrib_stuff(interpreter, current_class_obj);
       return NULL;
   }
   
  @@ -670,7 +783,6 @@
       full_attr_name = string_concat(interpreter, class_name, 
string_from_cstring(interpreter, "\0", 1), 0);
       full_attr_name = string_concat(interpreter, full_attr_name, attr, 0);
       
  -
       /*
        * TODO check if someone is trying to add attributes to a parent class
        * while there are already child class attrs
  @@ -718,6 +830,24 @@
       else {
           internal_exception(INTERNAL_NOT_IMPLEMENTED, "Can't set non-core object 
attribs yet");
       }
  +}
  +
  +INTVAL
  +Parrot_class_offset(Parrot_Interp interpreter, PMC *object, STRING *class) {
  +    PMC *offset_hash;
  +    PMC *internal_array;
  +    INTVAL offset;
  +    internal_array = PMC_data(object);
  +    offset_hash = VTABLE_get_pmc_keyed_int(interpreter,
  +                                           internal_array,
  +                                           PCD_ATTRIB_OFFS);
  +    if (VTABLE_exists_keyed_str(interpreter, offset_hash, class)) {
  +        offset = VTABLE_get_integer_keyed_str(interpreter, offset_hash, class);
  +    }
  +    else {
  +        offset = -1;
  +    }
  +    return offset;
   }
   
   /*
  
  
  

Reply via email to