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