Author: allison
Date: Wed Oct  3 19:09:50 2007
New Revision: 21804

Modified:
   branches/pdd15oo/include/parrot/oo.h
   branches/pdd15oo/include/parrot/oo_private.h
   branches/pdd15oo/include/parrot/pmc.h
   branches/pdd15oo/lib/Parrot/Pmc2c/PMC/Object.pm
   branches/pdd15oo/src/mmd.c
   branches/pdd15oo/src/oo.c
   branches/pdd15oo/src/pmc/class.pmc
   branches/pdd15oo/src/pmc/integer.pmc
   branches/pdd15oo/src/pmc/pmcproxy.pmc

Log:
[pdd15oo] Enable high-level classes and proxies to participate in type-level 
MMD.
- Classes and proxies report their high-level type for their vtable 'type'.
- MMD depends on the vtable MRO entry for comparing parent's types, so set it
  when the class is created and has parents added.
- Refactor vtable and method extraction out to src/oo.c.
- Refactor private class flags and add flag for anonymous classes.


Modified: branches/pdd15oo/include/parrot/oo.h
==============================================================================
--- branches/pdd15oo/include/parrot/oo.h        (original)
+++ branches/pdd15oo/include/parrot/oo.h        Wed Oct  3 19:09:50 2007
@@ -17,6 +17,9 @@
 
 /* HEADERIZER BEGIN: src/oo.c */
 
+void Parrot_oo_extract_methods_from_namespace(PARROT_INTERP, PMC *self)
+        __attribute__nonnull__(1);
+
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 PMC * Parrot_oo_find_vtable_override_for_class(PARROT_INTERP,

Modified: branches/pdd15oo/include/parrot/oo_private.h
==============================================================================
--- branches/pdd15oo/include/parrot/oo_private.h        (original)
+++ branches/pdd15oo/include/parrot/oo_private.h        Wed Oct  3 19:09:50 2007
@@ -49,11 +49,35 @@
 /* Fully qualified class name generation; defined in Class, used by Object. */
 STRING* Parrot_Class_get_fq_classname(Parrot_Interp interp, Parrot_Class 
*class_info);
 
-/* We have a flag to mark if the class inherits from anything from a different
- * class universe (for example, a PMC). */
-#define PObj_HasAlienParents_FLAG PObj_private0_FLAG
-#define PObj_HasAlienParents_TEST(o) PObj_flag_TEST(HasAlienParents, o)
-#define PObj_HasAlienParents_SET(o) PObj_flag_SET(HasAlienParents, o)
+/*
+ * Class private flags
+ */
+typedef enum {
+    CLASS_instantiated_FLAG      = PObj_private0_FLAG,
+    CLASS_is_anon_FLAG           = PObj_private1_FLAG,
+    CLASS_has_alien_parents_FLAG = PObj_private2_FLAG,
+} class_flags_enum;
+
+#define CLASS_get_FLAGS(o) (PObj_get_FLAGS(o))
+#define CLASS_flag_TEST(flag, o) (CLASS_get_FLAGS(o) & CLASS_ ## flag ## _FLAG)
+#define CLASS_flag_SET(flag, o) (CLASS_get_FLAGS(o) |= CLASS_ ## flag ## _FLAG)
+#define CLASS_flag_CLEAR(flag, o) (CLASS_get_FLAGS(o) &= ~(UINTVAL)(CLASS_ ## 
flag ## _FLAG))
+
+/* Mark if the class has been instantiated */
+#define CLASS_instantiated_TEST(o)  CLASS_flag_TEST(instantiated, o)
+#define CLASS_instantiated_SET(o)   CLASS_flag_SET(instantiated, o)
+#define CLASS_instantiated_CLEAR(o) CLASS_flag_CLEAR(instantiated, o)
+
+/* Mark if the class is anonymous */
+#define CLASS_is_anon_TEST(o)  CLASS_flag_TEST(is_anon, o)
+#define CLASS_is_anon_SET(o)   CLASS_flag_SET(is_anon, o)
+#define CLASS_is_anon_CLEAR(o) CLASS_flag_CLEAR(is_anon, o)
+
+/* Mark if the class has parents from a different object model (for
+ * example, a PMC). */
+#define CLASS_has_alien_parents_TEST(o)  CLASS_flag_TEST(has_alien_parents, o)
+#define CLASS_has_alien_parents_SET(o)   CLASS_flag_SET(has_alien_parents, o)
+#define CLASS_has_alien_parents_CLEAR(o) CLASS_flag_CLEAR(has_alien_parents, o)
 
 #endif /* PARROT_OO_PRIVATE_H_GUARD */
 

Modified: branches/pdd15oo/include/parrot/pmc.h
==============================================================================
--- branches/pdd15oo/include/parrot/pmc.h       (original)
+++ branches/pdd15oo/include/parrot/pmc.h       Wed Oct  3 19:09:50 2007
@@ -48,10 +48,6 @@
         __attribute__nonnull__(1);
 
 PARROT_API
-void Parrot_create_pmc_proxy(PARROT_INTERP, int type_num)
-        __attribute__nonnull__(1);
-
-PARROT_API
 PARROT_CANNOT_RETURN_NULL
 PARROT_MALLOC
 PMC * pmc_new(PARROT_INTERP, INTVAL base_type)

Modified: branches/pdd15oo/lib/Parrot/Pmc2c/PMC/Object.pm
==============================================================================
--- branches/pdd15oo/lib/Parrot/Pmc2c/PMC/Object.pm     (original)
+++ branches/pdd15oo/lib/Parrot/Pmc2c/PMC/Object.pm     Wed Oct  3 19:09:50 2007
@@ -58,7 +58,7 @@
             $void_return
         }
 
-        if (VTABLE_type(interp, cur_class) == enum_class_PMCProxy) {
+        if (cur_class->vtable->base_type == enum_class_PMCProxy) {
             
             /* Get the PMC instance and call the vtable method on that. */
             PMC * const del_object = VTABLE_get_attr_keyed(interp, SELF,

Modified: branches/pdd15oo/src/mmd.c
==============================================================================
--- branches/pdd15oo/src/mmd.c  (original)
+++ branches/pdd15oo/src/mmd.c  Wed Oct  3 19:09:50 2007
@@ -1404,6 +1404,8 @@
             const PMC * const cl = VTABLE_get_pmc_keyed_int(interp, mro, j);
             if (cl->vtable->base_type == type_sig)
                 break;
+            if (VTABLE_type(interp, cl) == type_sig)
+                break;
             ++dist;
         }
         /*

Modified: branches/pdd15oo/src/oo.c
==============================================================================
--- branches/pdd15oo/src/oo.c   (original)
+++ branches/pdd15oo/src/oo.c   Wed Oct  3 19:09:50 2007
@@ -19,6 +19,7 @@
 */
 
 #define PARROT_IN_OO_C
+#define PARROT_IN_OBJECTS_C /* To get the vtable.h imports we want. */
 #include "parrot/parrot.h"
 #include "parrot/oo_private.h"
 
@@ -28,6 +29,67 @@
 
 /*
 
+=item C<Parrot_oo_extract_methods_from_namespace>
+
+Extract methods an vtable overrides from the given namespace and insert them
+into the class.
+
+=cut
+
+*/
+
+void
+Parrot_oo_extract_methods_from_namespace(PARROT_INTERP, NOTNULL(PMC *self))
+{
+    Parrot_Class *_class      = PARROT_CLASS(self);
+
+    /* Pull in methods from the namespace, if any. */
+    if (!PMC_IS_NULL(_class->_namespace)) {
+        PMC *methods, *vtable_overrides;
+        PMC *ns = _class->_namespace;
+
+        /* Import any methods. */
+        Parrot_PCCINVOKE(interp, ns,
+            string_from_literal(interp, "get_associated_methods"), "->P", 
&methods);
+        if (!PMC_IS_NULL(methods)) {
+            PMC *iter = VTABLE_get_iter(interp, methods);
+            while (VTABLE_get_bool(interp, iter)) {
+                STRING *meth_name = VTABLE_shift_string(interp, iter);
+                PMC *meth_sub = VTABLE_get_pmc_keyed_str(interp, methods,
+                    meth_name);
+                VTABLE_add_method(interp, self, meth_name, meth_sub);
+            }
+        }
+
+        /* Import any vtable methods. */
+        Parrot_PCCINVOKE(interp, ns,
+            string_from_literal(interp, "get_associated_vtable_methods"), 
"->P", &vtable_overrides);
+        if (!PMC_IS_NULL(vtable_overrides)) {
+            PMC *iter = VTABLE_get_iter(interp, vtable_overrides);
+            while (VTABLE_get_bool(interp, iter)) {
+                STRING *vtable_index_str = VTABLE_shift_string(interp, iter);
+                PMC *vtable_sub = VTABLE_get_pmc_keyed_str(interp, 
vtable_overrides,
+                    vtable_index_str);
+                /* Look up the name of the vtable function from the index. */
+                INTVAL vtable_index = string_to_int(interp, vtable_index_str);
+                const char * const meth_c = 
Parrot_vtable_slot_names[vtable_index];
+                STRING *vtable_name = string_from_cstring(interp, meth_c, 0);
+
+                /* Strip leading underscores in the vtable name */
+                if (string_str_index(interp, vtable_name,
+                    string_from_literal(interp, "__"), 0) == 0) {
+                    vtable_name = string_substr(interp, vtable_name, 2,
+                        string_length(interp, vtable_name) - 2, NULL, 0);
+                }
+
+                VTABLE_add_vtable_override(interp, self, vtable_name, 
vtable_sub);
+            }
+        }
+    }
+}
+
+/*
+
 =item C<Parrot_oo_get_class>
 
 Lookup a class object from a namespace, string, or key PMC.

Modified: branches/pdd15oo/src/pmc/class.pmc
==============================================================================
--- branches/pdd15oo/src/pmc/class.pmc  (original)
+++ branches/pdd15oo/src/pmc/class.pmc  Wed Oct  3 19:09:50 2007
@@ -270,6 +270,9 @@
         _class->_namespace = new_namespace;
         _class->name       = new_name;
 
+        /* At this point we know the class isn't anonymous */
+        CLASS_is_anon_CLEAR(self);
+
         /* Register a type number for the class. */
         type_num = register_type(interp, name_arg);
 
@@ -278,6 +281,7 @@
         new_vtable->base_type     = type_num;
         new_vtable->pmc_class     = self;
         new_vtable->whoami        = VTABLE_get_string(interp, self);
+        new_vtable->mro           = _class->all_parents;
         _class->id                = type_num;
 
         /* Store the class's vtable in the global table */
@@ -359,49 +363,8 @@
         }
     }
 
-    /* Pull in methods from the namespace, if any. */
-    if (!PMC_IS_NULL(_class->_namespace)) {
-        PMC *methods, *vtable_overrides;
-        PMC *ns = _class->_namespace;
-
-        /* Import any methods. */
-        Parrot_PCCINVOKE(interp, ns,
-            string_from_literal(interp, "get_associated_methods"), "->P", 
&methods);
-        if (!PMC_IS_NULL(methods)) {
-            PMC *iter = VTABLE_get_iter(interp, methods);
-            while (VTABLE_get_bool(interp, iter)) {
-                STRING *meth_name = VTABLE_shift_string(interp, iter);
-                PMC *meth_sub = VTABLE_get_pmc_keyed_str(interp, methods,
-                    meth_name);
-                VTABLE_add_method(interp, self, meth_name, meth_sub);
-            }
-        }
-
-        /* Import any vtable methods. */
-        Parrot_PCCINVOKE(interp, ns,
-            string_from_literal(interp, "get_associated_vtable_methods"), 
"->P", &vtable_overrides);
-        if (!PMC_IS_NULL(vtable_overrides)) {
-            PMC *iter = VTABLE_get_iter(interp, vtable_overrides);
-            while (VTABLE_get_bool(interp, iter)) {
-                STRING *vtable_index_str = VTABLE_shift_string(interp, iter);
-                PMC *vtable_sub = VTABLE_get_pmc_keyed_str(interp, 
vtable_overrides,
-                    vtable_index_str);
-                /* Look up the name of the vtable function from the index. */
-                INTVAL vtable_index = string_to_int(interp, vtable_index_str);
-                const char * const meth_c = 
Parrot_vtable_slot_names[vtable_index];
-                STRING *vtable_name = string_from_cstring(interp, meth_c, 0);
-
-                /* Strip leading underscores in the vtable name */
-                if (string_str_index(interp, vtable_name,
-                    string_from_literal(interp, "__"), 0) == 0) {
-                    vtable_name = string_substr(interp, vtable_name, 2,
-                        string_length(interp, vtable_name) - 2, NULL, 0);
-                }
-
-                VTABLE_add_vtable_override(interp, self, vtable_name, 
vtable_sub);
-            }
-        }
-    }
+    /* Extract any methods from the namespace */
+    Parrot_oo_extract_methods_from_namespace(interp, self);
 }
 
 static PMC *
@@ -438,7 +401,7 @@
             all_parents, parent_index);
 
         /* PMCProxy parents store an instance to delegate to */
-        if (VTABLE_type(interp, parent) == enum_class_PMCProxy) {
+        if (parent->vtable->base_type == enum_class_PMCProxy) {
             PMC * proxy = VTABLE_instantiate(interp, parent, PMCNULL);
             VTABLE_set_attr_keyed(interp, object, parent,
                     string_from_literal(interp, "proxy"), proxy);
@@ -465,7 +428,7 @@
             all_parents, parent_index);
 
         /* PMCProxy parents store an instance to delegate to */
-        if (VTABLE_type(interp, parent) == enum_class_PMCProxy) {
+        if (parent->vtable->base_type == enum_class_PMCProxy) {
             PMC * proxy = VTABLE_instantiate(interp, parent, init);
             VTABLE_set_attr_keyed(interp, object, parent,
                     string_from_literal(interp, "proxy"), proxy);
@@ -540,6 +503,9 @@
 
         /* We are a class. */
         PObj_is_class_SET(SELF);
+
+        /* By default we're anonymous. */
+        CLASS_is_anon_SET(SELF);
     }
 
     void init_pmc(PMC *init_data) {
@@ -833,7 +799,11 @@
 
         /* Add to the lists of our immediate parents and all parents. */
         VTABLE_push_pmc(interp, _class->parents, parent);
-         _class->all_parents = Parrot_ComputeMRO_C3(interp, SELF);
+        _class->all_parents = Parrot_ComputeMRO_C3(interp, SELF);
+
+        /* Anonymous classes have no entry in the vtable array */
+        if (!CLASS_is_anon_TEST(SELF))
+            interp->vtables[VTABLE_type(interp, SELF)]->mro = 
_class->all_parents;
     }
 
 /*
@@ -1084,6 +1054,8 @@
             /* Build full parents list.
              * XXX Need pluggable MRO, for now always do C3. */
             _class->all_parents = Parrot_ComputeMRO_C3(interp, SELF);
+            if (!CLASS_is_anon_TEST(SELF))
+                interp->vtables[VTABLE_type(interp, SELF)]->mro = 
_class->all_parents;
 
             build_attrib_index(interp, SELF);
 
@@ -1099,7 +1071,7 @@
                     _class->all_parents, i);
                 if (!VTABLE_isa(interp, class_check, class_str)) {
                     /* Found one; that's enough. */
-                    PObj_HasAlienParents_SET(SELF);
+                    CLASS_has_alien_parents_SET(SELF);
                     break;
                 }
             }
@@ -1142,7 +1114,7 @@
 
         /* If we have parents that are out of this class universe, find them
          * in the MRO and create instances of them. */
-        if (PObj_HasAlienParents_TEST(SELF)) {
+        if (CLASS_has_alien_parents_TEST(SELF)) {
             mro_length = VTABLE_elements(interp, _class->all_parents);
 
             for (i = 0; i < mro_length; i++) {

Modified: branches/pdd15oo/src/pmc/integer.pmc
==============================================================================
--- branches/pdd15oo/src/pmc/integer.pmc        (original)
+++ branches/pdd15oo/src/pmc/integer.pmc        Wed Oct  3 19:09:50 2007
@@ -334,7 +334,7 @@
 
             if ((c^a) >= 0 || (c^b) >= 0) {
                 if (!dest)
-                    dest = pmc_new(INTERP, SELF->vtable->base_type);
+                    dest = pmc_new(INTERP, VTABLE_type(interp, SELF));
 
                 /* need this for e.g. Undef PMC */
                 VTABLE_set_integer_native(INTERP, dest, c);
@@ -346,9 +346,9 @@
 MMD_Complex: {
             const INTVAL a = DYNSELF.get_integer();
             if (dest)
-                VTABLE_morph(INTERP, dest, value->vtable->base_type);
+                VTABLE_morph(INTERP, dest, VTABLE_type(interp, value));
             else
-                dest = pmc_new(INTERP, value->vtable->base_type);
+                dest = pmc_new(INTERP, VTABLE_type(interp, value));
 
             VTABLE_set_number_native(INTERP, dest,
                     a + VTABLE_get_number_keyed_int(INTERP, value, 0));
@@ -362,7 +362,7 @@
         }
 MMD_DEFAULT: {
             if (!dest)
-                dest = pmc_new(INTERP, value->vtable->base_type);
+                dest = pmc_new(INTERP, VTABLE_type(interp, value));
 
             VTABLE_set_number_native(INTERP, dest,
                 DYNSELF.get_integer() + VTABLE_get_number(INTERP, value));

Modified: branches/pdd15oo/src/pmc/pmcproxy.pmc
==============================================================================
--- branches/pdd15oo/src/pmc/pmcproxy.pmc       (original)
+++ branches/pdd15oo/src/pmc/pmcproxy.pmc       Wed Oct  3 19:09:50 2007
@@ -62,6 +62,7 @@
 
 */
 
+
 pmclass PMCProxy
     need_ext {
 
@@ -135,6 +136,10 @@
         if (!PMC_IS_NULL(proxy_info->_namespace))
             Parrot_PCCINVOKE(interp, proxy_info->_namespace,
                 string_from_literal(interp, "set_class"), "P->", SELF);
+
+        /* Extract any methods from the namespace */
+        Parrot_oo_extract_methods_from_namespace(interp, SELF);
+
     }
 
 /*
@@ -262,6 +267,22 @@
 
 /*
 
+=item C<INTVAL type()>
+
+Returns the integer type of the class.
+
+=cut
+
+*/
+
+
+    INTVAL type() {
+        Parrot_Class *_class    = PARROT_CLASS(SELF);
+        return _class->id;
+    }
+
+/*
+
 =item C<PMC *inspect_str(STRING *what)>
 
 Provides introspection of a specific piece of information about the PMC. The
@@ -273,7 +294,7 @@
 
 String PMC containing the name of the PMC
 
-=item namespce
+=item namespace
 
 NameSpace PMC of the the namespace attached to the PMC
 

Reply via email to