Author: jonathan
Date: Thu Mar  8 17:45:08 2007
New Revision: 17397

Modified:
   trunk/src/pmc/metaclass.pmc
   trunk/src/pmc/object.pmc

Log:
More work towards implementing the new objects PDD; mainly implements the bulk 
of generating the attributes table, though it doesn't quite work yet.

Modified: trunk/src/pmc/metaclass.pmc
==============================================================================
--- trunk/src/pmc/metaclass.pmc (original)
+++ trunk/src/pmc/metaclass.pmc Thu Mar  8 17:45:08 2007
@@ -27,27 +27,76 @@
     PMC *namespace;       /* The namespace it's linked to, if any. */
     int instantiated;     /* Any instantiations since last modification? */

     PMC *parents;         /* Immediate parent classes. */
-    PMC *all_parents;     /* Cached list of all parents, in MRO order. */

+    PMC *all_parents;     /* Cached list of ourself and all parents, in MRO 
order. */

     PMC *roles;           /* An array of roles. */
     PMC *methods;         /* Hash of method names to methods in this class. */

     PMC *vtable_methods;  /* Hash of Parrot v-table methods we override. */

     PMC *attrib_metadata; /* Hash of attributes in this class to metadata. */

-    PMC *attrib_index;   /* Lookup table for attributes in this and parents. */

+    PMC *attrib_index;    /* Lookup table for attributes in this and parents. 
*/

     PMC *attrib_cache;    /* Cache of visible attrib names to indexes. */
 } Parrot_MetaClass;
+

+pmclass MetaClass need_ext {

+    /* This functions builds the attribute index (table to map class name and

+     * attribute name to an index) for the current class. Note: we have to

+     * make this a method so we can use PMINVOKE for now. XXX Fix that. */

+    METHOD void build_attrib_index() {

+        Parrot_MetaClass *class = PARROT_METACLASS(SELF);

+        int num_classes = VTABLE_elements(interp, class->all_parents);

+        int i;

+        int cur_index = 0;

+        PMC *table = pmc_new(interp, enum_class_Hash);

+

+        /* We will go over the list of all parents to construct the table. */

+        for (i = 0; i < num_classes; i++) {

+           /* Get the class and its attribute metadata hash. */

+            PMC *cur_class = VTABLE_get_pmc_keyed_int(interp, 
class->all_parents, i);

+            Parrot_MetaClass *class_info = PARROT_METACLASS(cur_class);

+            PMC *attribs = class_info->attrib_metadata;

+            PMC *iter = VTABLE_get_iter(interp, attribs);

+

+            /* Iterate over the attributes. */

+            while (VTABLE_get_bool(interp, iter)) {

+                /* Get attribute. */

+                PMC *cur_attrib = VTABLE_get_pmc_keyed(interp, attribs,

+                    VTABLE_shift_pmc(interp, iter));

+                STRING *attrib_name;

+

+                /* Get fully qualified class name. */

+                /* XXX BAD AND WRONG! Need to call method properly! */

+                PMC *fq_name;

+                if (!PMC_IS_NULL(class_info->namespace))

+                    fq_name = Parrot_NameSpace_get_name(interp, 
class_info->namespace);

+                else

+                    fq_name = pmc_new(interp, enum_class_ResizableStringArray);

+

+                /* Get attribute name and append it. */

+                (STRING *attrib_name) = PMINVOKE(interp, cur_attrib, "name");

+                printf("arg %s\n", string_to_cstring(interp, attrib_name));

+                VTABLE_push_string(interp, fq_name, attrib_name);

+

+                /* Insert into hash, along with index. */

+                VTABLE_set_integer_keyed(interp, table, fq_name, cur_index);

+                cur_index++;

+            }

+        }

+

+        /* Store built table and invalidate cache. */

+        class->attrib_index = table;

+        class->attrib_cache = pmc_new(interp, enum_class_Hash);

+    }
 
-
-pmclass MetaClass need_ext {
 /*
 
 =item C<void init()>
 
-Initializes the class flags.
+Initializes the class.
 
-=item C<void init_pmc(PMC *init)>
+=item C<void init_pmc(PMC *name)>
 
 The actual class creation code, called from C<newclass> opcode. The C<init>
-argument is not a PMC* but the C<classname> STRING.
+argument should stringify to the C<classname>. The class will be attatched to
+the current namespace.
 
 =cut
 
@@ -55,14 +104,14 @@
 
     void init() {
         Parrot_MetaClass *class = NULL;

-

-        /* But we are a class, really */

-        PObj_is_class_SET(SELF);

         

         /* Custom DOD mark and destory. */

         PObj_custom_mark_SET(SELF);

         PObj_active_destroy_SET(SELF);

 

+        /* We are a class. */

+        PObj_is_class_SET(SELF);

+

         /* Init the class object. */

         class = mem_sys_allocate_zeroed(sizeof(Parrot_MetaClass));

         class->namespace = PMCNULL;

@@ -72,14 +121,25 @@
         class->methods = pmc_new(interp, enum_class_Hash);

         class->vtable_methods = pmc_new(interp, enum_class_Hash);

         class->attrib_metadata = pmc_new(interp, enum_class_Hash);

-        class->attrib_index = pmc_new(interp, enum_class_Hash);

-        class->attrib_cache = pmc_new(interp, enum_class_Hash);

+        class->attrib_index = PMCNULL;

+        class->attrib_cache = PMCNULL;

+

+        /* We put ourself on the all parents list. */

+        VTABLE_push_pmc(interp, class->all_parents, SELF);

 

         PMC_data(SELF) = class;
     }
 
-    void init_pmc(PMC* args) {
+    void init_pmc(PMC* name) {
+        Parrot_MetaClass *class = NULL;
+
+        /* Set up the object. */
         SELF.init();
+
+        /* Set name and namespace. */
+        class = PARROT_METACLASS(SELF);
+        class->name = VTABLE_get_string(interp, name);
+        class->namespace = CONTEXT(interp->ctx)->current_namespace;
     }
 
 /*
@@ -97,7 +157,7 @@
 

 /*

 

-=item C<void destroy()>

+=item C<void mark()>

 

 Mark any referenced strings and PMCs.

 

@@ -134,15 +194,15 @@
 

 =cut

 

-*/    

+*/

     PMETHOD void add_attribute(STRING *attribute_name, STRING* attribute_type 
:optional, int got_type :opt_flag) {

         Parrot_MetaClass *class = PARROT_METACLASS(SELF);

         PMC *new_attribute = pmc_new(interp, enum_class_MetaAttribute);

 

         /* Set name and type. */

-        PMINVOKE(interp, pmc, "name", STRING* attribute_name);

+        PMINVOKE(interp, new_attribute, "name", STRING* attribute_name);

         if (got_type) {

-            PMINVOKE(interp, SELF, "type", STRING* attribute_type);

+            PMINVOKE(interp, new_attribute, "type", STRING* attribute_type);

         }

 

         /* If we've been instantiated already, need a new class. */

@@ -224,18 +284,25 @@
 

 =cut

 

-*/ /*
+*/
     PMETHOD void new(PMC *args :slurpy :named) {
         Parrot_MetaClass *class = PARROT_METACLASS(SELF);

-        PMC *obj;
-        STRING *name;
-        INTVAL type_id;
-
-        type_id = pmc_type(interp, class->name);
-        obj = pmc_new_init(interp, type_id, args);
-        preturn(PMC *obj)
-    }
-*/
+        PMC *obj;

+

+        /* Ensure we've built attributes list. */

+        if (PMC_IS_NULL(class->attrib_index))

+            Parrot_MetaClass_build_attrib_index(interp, SELF);

+

+        /* Set instantiated flag. */

+        class->instantiated = 1;

+

+        /* Create object. */

+        obj = pmc_new_init(interp, enum_class_Object, SELF);

+

+        /* XXX Call constructor with the supplied arguments? */

+ 

+         preturn(PMC *obj)

+     }
 }
 
 /*

Modified: trunk/src/pmc/object.pmc
==============================================================================
--- trunk/src/pmc/object.pmc    (original)
+++ trunk/src/pmc/object.pmc    Thu Mar  8 17:45:08 2007
@@ -22,8 +22,8 @@
 #define PARROT_OBJECT(o) ((Parrot_Object *) PMC_data(o))
 
 typedef struct Parrot_Object {
-    PMC *class;
-    PMC *attrib_store;
+    PMC *class;          /* The class this is an instance of. */
+    PMC *attrib_store;   /* The attributes store - a resizable PMC array. */
 } Parrot_Object;
 
 
@@ -61,7 +61,7 @@
 
 /*
 
-=item C<void destroy()>
+=item C<void mark()>
 
 Free the object's underlying struct.
 

Reply via email to