Author: chromatic
Date: Wed May 16 19:24:08 2007
New Revision: 18577
Modified:
trunk/include/parrot/objects.h
trunk/src/objects.c
Log:
[OO] Minor coding style cleanups.
There is one API change, where a function with an always-ignored return value
is now officially void.
Modified: trunk/include/parrot/objects.h
==============================================================================
--- trunk/include/parrot/objects.h (original)
+++ trunk/include/parrot/objects.h Wed May 16 19:24:08 2007
@@ -32,7 +32,7 @@
PARROT_API void Parrot_new_class(Parrot_Interp, PMC *, PMC *);
PARROT_API PMC *Parrot_class_lookup(Parrot_Interp, STRING *);
PARROT_API PMC *Parrot_class_lookup_p(Parrot_Interp, PMC *);
-PARROT_API PMC *Parrot_add_parent(Parrot_Interp, PMC *, PMC *);
+PARROT_API void Parrot_add_parent(Parrot_Interp, PMC *, PMC *);
PARROT_API PMC *Parrot_remove_parent(Parrot_Interp, PMC *, PMC *);
PARROT_API PMC *Parrot_multi_subclass(Parrot_Interp, PMC *, STRING *);
PARROT_API void Parrot_instantiate_object(Parrot_Interp, PMC *);
Modified: trunk/src/objects.c
==============================================================================
--- trunk/src/objects.c (original)
+++ trunk/src/objects.c Wed May 16 19:24:08 2007
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2001-2003, The Perl Foundation.
+Copyright (C) 2001-2007, The Perl Foundation.
$Id$
=head1 NAME
@@ -24,12 +24,12 @@
#include "objects.str"
-static void parrot_class_register(Interp * , PMC *name,
+static void parrot_class_register(Interp *interp, PMC *name,
PMC *new_class, PMC *parent, PMC *mro);
/*
-=item C<INTVAL Parrot_get_vtable_index(Interp *, STRING *name)>
+=item C<INTVAL Parrot_get_vtable_index(Interp *interp, STRING *name)>
Return index if C<name> is a valid vtable slot name.
@@ -40,10 +40,10 @@
INTVAL
Parrot_get_vtable_index(Interp *interp, STRING *name)
{
- char *name_c = string_to_cstring(interp, name);
-
- INTVAL low = 0;
- INTVAL high = NUM_VTABLE_FUNCTIONS - 1;
+ char *name_c = string_to_cstring(interp, name);
+ INTVAL low = 0;
+ INTVAL high = NUM_VTABLE_FUNCTIONS - 1;
+ INTVAL i;
/* some of the first "slots" don't have names. skip 'em. */
while (!Parrot_vtable_slot_names[low]) {
@@ -52,11 +52,14 @@
}
while (low <= high) {
- INTVAL i = (low + high) / 2;
+ char *meth_c;
+ int cmp;
+
+ i = (low + high) / 2;
+ meth_c = Parrot_vtable_slot_names[i];
- const char *meth_c = Parrot_vtable_slot_names[i];
/* XXX slot_names still have __ in front */
- int cmp = strcmp(name_c, meth_c + 2);
+ cmp = strcmp(name_c, meth_c + 2);
if (!cmp) {
string_cstring_free(name_c);
@@ -69,14 +72,16 @@
}
string_cstring_free(name_c);
+
return -1;
}
/*
-=item C<static PMC* find_vtable_meth_ns(Interp *interp, PMC *ns, INTVAL
vtable_index)>
+=item C<static PMC* find_vtable_meth_ns(Interp *interp, PMC *ns,
+ INTVAL vtable_index)>
-Return sub PMC if a method with the vtable name exists in ns
+Return Sub PMC if a method with the vtable name exists in ns
=cut
@@ -92,11 +97,14 @@
const char *meth = Parrot_vtable_slot_names[vtable_index];
STRING *meth_str = string_from_cstring(interp, meth, strlen(meth));
- int j;
+ STRING *ns_key;
+ PMC *res;
+ int j;
for (j = 0; j < k; ++j) {
- STRING *ns_key = (STRING *)parrot_hash_get_idx(interp, (Hash
*)PMC_struct_val(ns), key);
- PMC *res = VTABLE_get_pmc_keyed_str(interp, ns, ns_key);
+ ns_key = (STRING *)parrot_hash_get_idx(interp,
+ (Hash *)PMC_struct_val(ns), key);
+ res = VTABLE_get_pmc_keyed_str(interp, ns, ns_key);
/* success if matching vtable index or double-underscored name */
if (res->vtable->base_type == enum_class_Sub &&
@@ -110,21 +118,21 @@
/*
-=item C<PMC* Parrot_find_vtable_meth(Interp* interp, PMC *pmc, STRING *meth)>
+=item C<PMC* Parrot_find_vtable_meth(Interp *interp, PMC *pmc, STRING *meth)>
-Given pmc, run through its mro looking for the meth vtable method
-Return the vtable method PMC if found
+Given pmc, run through its mro looking for the meth vtable method.
+Return the vtable method PMC if found.
=cut
*/
PMC*
-Parrot_find_vtable_meth(Interp* interp, PMC *pmc, STRING *meth)
+Parrot_find_vtable_meth(Interp *interp, PMC *pmc, STRING *meth)
{
- PMC *_class = pmc;
INTVAL i, n;
- PMC *ns, *mro, *self_class;
+ PMC *ns, *mro, *self_class, *res;
+ PMC *_class = pmc;
/* Get index in Parrot_vtable_slot_names[]. */
INTVAL vtable_index = Parrot_get_vtable_index(interp, meth);
@@ -133,9 +141,8 @@
return NULL;
/* Get class. */
- if (PObj_is_object_TEST(pmc)) {
- _class = self_class = GET_CLASS((Buffer *)PMC_data(pmc), pmc);
- }
+ if (PObj_is_object_TEST(pmc))
+ _class = self_class = GET_CLASS(PMC_data_typed(pmc, Buffer), pmc);
/* Get MRO and iterate over it to find method with a matching
vtable index or double-underscored name. */
@@ -147,7 +154,8 @@
ns = VTABLE_pmc_namespace(interp, _class);
if (!PMC_IS_NULL(ns)) {
- PMC *res = find_vtable_meth_ns(interp, ns, vtable_index);
+ res = find_vtable_meth_ns(interp, ns, vtable_index);
+
if (!PMC_IS_NULL(res))
return res;
}
@@ -171,18 +179,23 @@
STRING*
readable_name(Interp *interp, PMC *name)
{
+ STRING *join_on;
+ PMC *array;
+
if (name->vtable->base_type == enum_class_String)
return VTABLE_get_string(interp, name);
- else {
- STRING *j = CONST_STRING(interp, ";");
- PMC *ar = pmc_new(interp, enum_class_ResizableStringArray);
- assert(name->vtable->base_type == enum_class_Key);
- while (name) {
- VTABLE_push_string(interp, ar, key_string(interp, name));
- name = key_next(interp, name);
- }
- return string_join(interp, j, ar);
+
+ join_on = CONST_STRING(interp, ";");
+ array = pmc_new(interp, enum_class_ResizableStringArray);
+
+ assert(name->vtable->base_type == enum_class_Key);
+
+ while (name) {
+ VTABLE_push_string(interp, array, key_string(interp, name));
+ name = key_next(interp, name);
}
+
+ return string_join(interp, join_on, array);
}
/*
@@ -200,10 +213,10 @@
static void
fail_if_exist(Interp *interp, PMC *name)
{
- INTVAL type;
+ INTVAL type;
PMC * const classname_hash = interp->class_hash;
- PMC * type_pmc = (PMC *)VTABLE_get_pointer_keyed(interp,
+ PMC *type_pmc = (PMC *)VTABLE_get_pointer_keyed(interp,
classname_hash, name);
if (PMC_IS_NULL(type_pmc) ||
type_pmc->vtable->base_type == enum_class_NameSpace)
@@ -213,15 +226,15 @@
if (type > enum_type_undef) {
/* TODO get printable name */
- STRING *class_name = VTABLE_get_string(interp, name);
real_exception(interp, NULL, INVALID_OPERATION,
- "Class %Ss already registered!\n", class_name);
+ "Class %Ss already registered!\n",
+ VTABLE_get_string(interp, name));
}
- if (type < enum_type_undef) {
+
+ if (type < enum_type_undef)
real_exception(interp, NULL, INVALID_OPERATION,
"native type with name '%s' already exists - "
"can't register Class", data_types[type].name);
- }
}
/*
@@ -232,8 +245,8 @@
{
PMC * const new_array = pmc_new(interp,
source_array->vtable->base_type);
- const INTVAL count = VTABLE_elements(interp, source_array);
- INTVAL i;
+ const INTVAL count = VTABLE_elements(interp, source_array);
+ INTVAL i;
/*
* preserve type, we have OrderedHash and Array
@@ -241,10 +254,12 @@
* (but the keys aren't used -leo)
*/
VTABLE_set_integer_native(interp, new_array, count);
+
for (i = 0; i < count; i++) {
VTABLE_set_pmc_keyed_int(interp, new_array, i,
VTABLE_get_pmc_keyed_int(interp, source_array, i));
}
+
return new_array;
}
@@ -254,15 +269,11 @@
static void
rebuild_attrib_stuff(Interp *interp, PMC *_class)
{
- INTVAL cur_offset;
+ INTVAL attr_count, cur_offset, n_class, n_mro, offset;
+ PMC *attr_offset_hash, *mro, *attribs;
+ STRING *classname, *partial_name;
SLOTTYPE *class_slots;
- PMC *attr_offset_hash;
- PMC *mro;
- STRING *classname;
- INTVAL n_class;
- INTVAL n_mro;
- PMC *attribs;
- INTVAL attr_count;
+
#ifndef NDEBUG
PMC * const orig_class = _class;
#endif
@@ -276,41 +287,37 @@
attr_offset_hash = pmc_new(interp, enum_class_Hash);
set_attrib_num(_class, class_slots, PCD_ATTRIBUTES, attr_offset_hash);
- mro = _class->vtable->mro;
+ mro = _class->vtable->mro;
n_mro = VTABLE_elements(interp, mro);
- /*
- * walk from oldest parent downto n_class == 0 which is this class
- */
+ /* walk from oldest parent down to n_class == 0 which is this class */
cur_offset = 0;
+
for (n_class = n_mro - 1; n_class >= 0; --n_class) {
_class = VTABLE_get_pmc_keyed_int(interp, mro, n_class);
- if (!PObj_is_class_TEST(_class)) {
- /* this Class isa PMC - no attributes there
- */
+
+ /* this Class isa PMC - no attributes there */
+ if (!PObj_is_class_TEST(_class))
continue;
- }
class_slots = PMC_data_typed(_class, SLOTTYPE *);
classname = VTABLE_get_string(interp,
get_attrib_num(class_slots, PCD_CLASS_NAME));
- attribs = get_attrib_num(class_slots, PCD_CLASS_ATTRIBUTES);
+ attribs = get_attrib_num(class_slots, PCD_CLASS_ATTRIBUTES);
attr_count = VTABLE_elements(interp, attribs);
+
if (attr_count) {
- INTVAL offset;
+ STRING *attr_name, *full_name;
+
+ partial_name = string_concat(interp, classname,
+ string_from_cstring(interp, "\0", 1), 0);
- STRING * const partial_name =
- string_concat(interp, classname,
- string_from_cstring(interp, "\0", 1),
- 0);
for (offset = 0; offset < attr_count; offset++) {
- STRING * const attr_name =
- VTABLE_get_string_keyed_int(interp, attribs, offset);
- STRING * const full_name =
- string_concat(interp, partial_name, attr_name, 0);
- /*
- * store this attribute with short and full name
- */
+ attr_name = VTABLE_get_string_keyed_int(interp, attribs,
offset);
+ full_name = string_concat(interp, partial_name, attr_name, 0);
+
+ /* store this attribute with short and full name */
+
VTABLE_set_integer_keyed_str(interp, attr_offset_hash,
attr_name, cur_offset);
VTABLE_set_integer_keyed_str(interp, attr_offset_hash,
@@ -344,12 +351,13 @@
static void
create_deleg_pmc_vtable(Interp *interp, PMC *_class, PMC *class_name, int full)
{
- int i;
+ int i;
const char *meth;
- STRING meth_str;
+ STRING meth_str;
DECL_CONST_CAST;
- PMC * const vtable_pmc = get_attrib_num((SLOTTYPE*)PMC_data(_class),
PCD_OBJECT_VTABLE);
+ PMC * const vtable_pmc = get_attrib_num(PMC_data_typed(_class,
+ SLOTTYPE *), PCD_OBJECT_VTABLE);
VTABLE * const vtable = (VTABLE *)PMC_struct_val(vtable_pmc);
VTABLE * const ro_vtable = vtable->ro_variant_vtable;
VTABLE * const deleg_pmc_vtable = interp->vtables[enum_class_deleg_pmc];
@@ -358,8 +366,10 @@
VTABLE * const delegate_vtable = interp->vtables[enum_class_delegate];
memset(&meth_str, 0, sizeof (meth_str));
+
meth_str.encoding = Parrot_fixed_8_encoding_ptr;
meth_str.charset = Parrot_default_charset_ptr;
+
for (i = 0; (meth = Parrot_vtable_slot_names[i]) != NULL; ++i) {
if (!*meth)
continue;
@@ -370,14 +380,10 @@
meth_str.hashval = 0;
if (!PMC_IS_NULL(Parrot_find_vtable_meth(interp, _class, &meth_str))) {
- /* the method exists; keep the ParrotObject aka delegate vtable
slot */
+ /* the method exists; keep the ParrotObject delegate vtable slot */
((void **)vtable)[i] = ((void**)object_vtable)[i];
if (ro_vtable)
((void **)ro_vtable)[i] = ((void**)ro_object_vtable)[i];
-
-#if 0
- PIO_eprintf(interp, "deleg_pmc class '%Ss' found '%s'\n",
class_name, meth);
-#endif
}
else if (full) {
/*
@@ -421,6 +427,7 @@
if (idx >= MMD_USER_FIRST)
return NULL;
+
return Parrot_mmd_func_names[idx];
}
@@ -433,6 +440,7 @@
if (!strcmp(Parrot_mmd_func_names[i], name))
return i;
}
+
return -1;
}
@@ -453,10 +461,9 @@
PMC *
Parrot_single_subclass(Interp *interp, PMC *base_class, PMC *name)
{
- PMC *child_class;
+ PMC *child_class, *parents, *temp_pmc, *mro;
SLOTTYPE *child_class_array;
- PMC *parents, *temp_pmc, *mro;
- int parent_is_class;
+ int parent_is_class;
/* Set the classname, if we have one */
if (!PMC_IS_NULL(name)) {
@@ -465,18 +472,19 @@
else {
/* XXX not really threadsafe but good enough for now */
static int anon_count;
- STRING *child_class_name = Parrot_sprintf_c(interp, "%c%canon_%d", 0,
0, ++anon_count);
- name = pmc_new(interp, enum_class_String);
+ STRING *child_class_name;
+ child_class_name = Parrot_sprintf_c(interp, "%c%canon_%d", 0, 0,
+ ++anon_count);
+ name = pmc_new(interp, enum_class_String);
VTABLE_set_string_native(interp, name, child_class_name);
}
/* ParrotClass is the baseclass anyway, so build just a new class */
- if (base_class == interp->vtables[enum_class_ParrotClass]->pmc_class) {
+ if (base_class == interp->vtables[enum_class_ParrotClass]->pmc_class)
return pmc_new_init(interp, enum_class_ParrotClass, name);
- }
- parent_is_class = PObj_is_class_TEST(base_class);
- child_class = pmc_new(interp, enum_class_ParrotClass);
+ parent_is_class = PObj_is_class_TEST(base_class);
+ child_class = pmc_new(interp, enum_class_ParrotClass);
/* Hang an array off the data pointer */
set_attrib_array_size(child_class, PCD_MAX);
@@ -486,12 +494,15 @@
/* We will have five entries in this array */
/* We have the same number of attributes as our parent */
- CLASS_ATTRIB_COUNT(child_class) = parent_is_class ?
CLASS_ATTRIB_COUNT(base_class) : 0;
+ CLASS_ATTRIB_COUNT(child_class) = parent_is_class ?
+ CLASS_ATTRIB_COUNT(base_class) : 0;
/* Our parent class array has a single member in it */
parents = pmc_new(interp, enum_class_ResizablePMCArray);
+
VTABLE_set_integer_native(interp, parents, 1);
VTABLE_set_pmc_keyed_int(interp, parents, 0, base_class);
+
set_attrib_num(child_class, child_class_array, PCD_PARENTS, parents);
set_attrib_num(child_class, child_class_array, PCD_CLASS_NAME, name);
@@ -502,10 +513,10 @@
/* But we have no attributes of our own. Yet */
temp_pmc = pmc_new(interp, enum_class_ResizablePMCArray);
- set_attrib_num(child_class, child_class_array, PCD_CLASS_ATTRIBUTES,
temp_pmc);
+ set_attrib_num(child_class, child_class_array, PCD_CLASS_ATTRIBUTES,
+ temp_pmc);
parrot_class_register(interp, name, child_class, base_class, mro);
-
rebuild_attrib_stuff(interp, child_class);
if (!parent_is_class) {
@@ -523,10 +534,10 @@
* if any parent isa PMC, then still individual vtables might
* be overridden in this subclass
*/
- const PMC* parent;
+ const PMC *parent;
int i, n, any_pmc_parent;
- n = VTABLE_elements(interp, mro);
+ n = VTABLE_elements(interp, mro);
any_pmc_parent = 0;
/* 0 = this, 1 = parent (handled above), 2 = grandpa */
@@ -540,6 +551,7 @@
if (any_pmc_parent)
create_deleg_pmc_vtable(interp, child_class, name, 0);
}
+
return child_class;
}
@@ -558,7 +570,7 @@
Parrot_new_class(Interp *interp, PMC *_class, PMC *name)
{
SLOTTYPE *class_array;
- PMC *mro;
+ PMC *mro;
/* check against duplicate newclasses */
fail_if_exist(interp, name);
@@ -566,13 +578,14 @@
/* Hang an array off the data pointer, empty of course */
set_attrib_array_size(_class, PCD_MAX);
class_array = PMC_data_typed(_class, SLOTTYPE *);
+
/* set_attrib_flags(_class); init does it */
/* Our parent class array has nothing in it */
set_attrib_num(_class, class_array, PCD_PARENTS,
pmc_new(interp, enum_class_ResizablePMCArray));
- /* TODO create all class structures in constant PMC pool
- */
+
+ /* TODO create all class structures in constant PMC pool */
/*
* create MRO (method resolution order) array
@@ -581,8 +594,7 @@
mro = pmc_new(interp, enum_class_ResizablePMCArray);
VTABLE_push_pmc(interp, mro, _class);
- /* no attributes yet
- */
+ /* no attributes yet */
set_attrib_num(_class, class_array, PCD_CLASS_ATTRIBUTES,
pmc_new(interp, enum_class_ResizablePMCArray));
@@ -613,44 +625,50 @@
Parrot_class_lookup(Interp *interp, STRING *class_name)
{
const INTVAL type = pmc_type(interp, class_name);
- if (type > 0) {
- PMC * const pmc = interp->vtables[type]->pmc_class;
- assert(pmc);
- return pmc;
- }
- return PMCNULL;
+ PMC *pmc;
+
+ if (type <= 0)
+ return PMCNULL;
+
+ pmc = interp->vtables[type]->pmc_class;
+ assert(pmc);
+ return pmc;
}
PMC *
Parrot_class_lookup_p(Interp *interp, PMC *class_name)
{
const INTVAL type = pmc_type_p(interp, class_name);
- if (type > 0) {
- PMC * const pmc = interp->vtables[type]->pmc_class;
- assert(pmc);
- return pmc;
- }
- return PMCNULL;
+ PMC *pmc;
+
+ if (type <= 0)
+ return PMCNULL;
+
+ pmc = interp->vtables[type]->pmc_class;
+ assert(pmc);
+ return pmc;
}
static INTVAL
register_type(Interp *interp, PMC *name)
{
INTVAL type;
- PMC * classname_hash, *item;
+ PMC *classname_hash, *item;
/* so pt_shared_fixup() can safely do a type lookup */
LOCK_INTERPRETER(interp);
classname_hash = interp->class_hash;
type = interp->n_vtable_max++;
+
/* Have we overflowed the table? */
- if (type >= interp->n_vtable_alloced) {
+ if (type >= interp->n_vtable_alloced)
parrot_realloc_vtables(interp);
- }
+
/* set entry in name->type hash */
- item = pmc_new(interp, enum_class_Integer);
+ item = pmc_new(interp, enum_class_Integer);
PMC_int_val(item) = type;
+
VTABLE_set_pmc_keyed(interp, classname_hash, name, item);
UNLOCK_INTERPRETER(interp);
@@ -677,11 +695,9 @@
PMC *new_class, PMC *parent, PMC *mro)
{
VTABLE *new_vtable, *parent_vtable;
- PMC *vtable_pmc;
- PMC *ns, *top;
- INTVAL new_type;
+ PMC *vtable_pmc, *ns, *top;
+ INTVAL new_type = register_type(interp, name);
- new_type = register_type(interp, name);
/* Build a new vtable for this class
* The child class PMC gets the vtable of its parent class or
* a ParrotClass vtable
@@ -690,47 +706,53 @@
parent_vtable = parent->vtable;
else
parent_vtable = new_class->vtable;
+
new_vtable = Parrot_clone_vtable(interp, parent_vtable);
/* Set the vtable's type to the newly allocated type */
new_vtable->base_type = new_type;
+
/* And cache our class PMC in the vtable so we can find it later */
- new_vtable->pmc_class = new_class;
- new_vtable->mro = mro;
+ new_vtable->pmc_class = new_class;
+ new_vtable->mro = mro;
if (parent_vtable->ro_variant_vtable)
new_vtable->ro_variant_vtable =
Parrot_clone_vtable(interp, parent_vtable->ro_variant_vtable);
/* Reset the init method to our instantiation method */
- new_vtable->init = Parrot_instantiate_object;
- new_vtable->init_pmc = Parrot_instantiate_object_init;
- new_class->vtable = new_vtable;
+ new_vtable->init = Parrot_instantiate_object;
+ new_vtable->init_pmc = Parrot_instantiate_object_init;
+ new_class->vtable = new_vtable;
/* Put our new vtable in the global table */
interp->vtables[new_type] = new_vtable;
/* check if we already have a NameSpace */
top = CONTEXT(interp->ctx)->current_namespace;
- ns = VTABLE_get_pmc_keyed(interp, top, name);
+ ns = VTABLE_get_pmc_keyed(interp, top, name);
+
/* XXX nested, use current as base ? */
if (PMC_IS_NULL(ns)) {
/* XXX try HLL namespace too XXX */
top = Parrot_get_ctx_HLL_namespace(interp);
- ns = VTABLE_get_pmc_keyed(interp, top, name);
+ ns = VTABLE_get_pmc_keyed(interp, top, name);
}
+
if (PMC_IS_NULL(ns)) {
ns = pmc_new(interp, enum_class_NameSpace);
VTABLE_set_pmc_keyed(interp, top, name, ns);
}
+
/* attach namspace to vtable */
new_vtable->_namespace = ns;
if (new_vtable->ro_variant_vtable) {
- VTABLE * const ro_vt = new_vtable->ro_variant_vtable;
- ro_vt->base_type = new_vtable->base_type;
- ro_vt->pmc_class = new_vtable->pmc_class;
- ro_vt->mro = new_vtable->mro;
+ VTABLE *ro_vt;
+ ro_vt = new_vtable->ro_variant_vtable;
+ ro_vt->base_type = new_vtable->base_type;
+ ro_vt->pmc_class = new_vtable->pmc_class;
+ ro_vt->mro = new_vtable->mro;
ro_vt->_namespace = new_vtable->_namespace;
}
@@ -747,35 +769,38 @@
parent_vtable = interp->vtables[enum_class_ParrotObject];
new_vtable = Parrot_clone_vtable(interp, parent_vtable);
+
if (parent_vtable->ro_variant_vtable)
new_vtable->ro_variant_vtable =
Parrot_clone_vtable(interp, parent_vtable->ro_variant_vtable);
+
new_vtable->base_type = new_type;
- new_vtable->mro = mro;
+ new_vtable->mro = mro;
new_vtable->pmc_class = new_class;
set_attrib_num(new_class, (SLOTTYPE*)PMC_data(new_class),
PCD_OBJECT_VTABLE,
vtable_pmc = constant_pmc_new(interp, enum_class_VtableCache));
PMC_struct_val(vtable_pmc) = new_vtable;
+
/* attach namspace to object vtable too */
new_vtable->_namespace = ns;
if (new_vtable->ro_variant_vtable) {
- VTABLE * const ro_vt = new_vtable->ro_variant_vtable;
- ro_vt->base_type = new_vtable->base_type;
- ro_vt->pmc_class = new_vtable->pmc_class;
- ro_vt->mro = new_vtable->mro;
+ VTABLE *ro_vt;
+ ro_vt = new_vtable->ro_variant_vtable;
+ ro_vt->base_type = new_vtable->base_type;
+ ro_vt->pmc_class = new_vtable->pmc_class;
+ ro_vt->mro = new_vtable->mro;
ro_vt->_namespace = new_vtable->_namespace;
}
}
static PMC*
-get_init_meth(Interp *interp, PMC *_class,
- STRING *prop_str , STRING **meth_str)
+get_init_meth(Interp *interp, PMC *_class, STRING *prop_str, STRING **meth_str)
{
- STRING *meth;
+ STRING *meth;
HashBucket *b;
- PMC *props, *ns, *method;
+ PMC *props, *ns, *method;
*meth_str = NULL;
#if 0
@@ -794,10 +819,11 @@
return NULL;
meth = PMC_str_val((PMC*) b->value);
#endif
+
*meth_str = meth;
+ ns = VTABLE_pmc_namespace(interp, _class);
+ method = VTABLE_get_pmc_keyed_str(interp, ns, meth);
- ns = VTABLE_pmc_namespace(interp, _class);
- method = VTABLE_get_pmc_keyed_str(interp, ns, meth);
return PMC_IS_NULL(method) ? NULL : method;
}
@@ -835,6 +861,7 @@
* Note: mro contains this class as first element
*/
nparents = VTABLE_elements(interp, classsearch_array);
+
for (i = nparents - 1; i >= 0; --i) {
parent_class = VTABLE_get_pmc_keyed_int(interp,
classsearch_array, i);
@@ -852,11 +879,10 @@
assert(i >= 1);
next_parent = VTABLE_get_pmc_keyed_int(interp,
classsearch_array, i - 1);
- if (!PObj_is_class_TEST(next_parent)) {
+ if (!PObj_is_class_TEST(next_parent))
continue;
- }
- attr = pmc_new_noinit(interp,
- parent_class->vtable->base_type);
+
+ attr = pmc_new_noinit(interp, parent_class->vtable->base_type);
obj_data = PMC_data_typed(object, SLOTTYPE *);
set_attrib_num(object, obj_data, 0, attr);
VTABLE_init(interp, attr);
@@ -933,7 +959,7 @@
instantiate_object(Interp *interp, PMC *object, PMC *init)
{
SLOTTYPE *new_object_array;
- INTVAL attrib_count, i;
+ INTVAL attrib_count, i;
PMC * const _class = object->vtable->pmc_class;
/*
@@ -970,8 +996,7 @@
/*
=item C<PMC *
-Parrot_add_parent(Interp *interp, PMC *_class,
- PMC *parent)>
+Parrot_add_parent(Interp *interp, PMC *_class, PMC *parent)>
Add the parent class to the current class' parent list. This also
involved adding all the parent's parents, as well as all attributes of
@@ -985,19 +1010,21 @@
*/
-
/* create a list if non-empty lists */
static PMC*
not_empty(Interp *interp, PMC *seqs)
{
INTVAL i;
PMC * const nseqs = pmc_new(interp, enum_class_ResizablePMCArray);
+ PMC *list;
for (i = 0; i < VTABLE_elements(interp, seqs); ++i) {
- PMC * const list = VTABLE_get_pmc_keyed_int(interp, seqs, i);
+ list = VTABLE_get_pmc_keyed_int(interp, seqs, i);
+
if (VTABLE_elements(interp, list))
VTABLE_push_pmc(interp, nseqs, list);
}
+
return nseqs;
}
@@ -1005,21 +1032,26 @@
static PMC*
class_mro_merge(Interp *interp, PMC *seqs)
{
- PMC *res, *seq, *cand, *nseqs, *s;
+ PMC *seq, *nseqs, *s;
INTVAL i, j, k;
- cand = NULL; /* silence compiler uninit warning */
- res = pmc_new(interp, enum_class_ResizablePMCArray);
+ /* silence compiler uninit warning */
+ PMC *cand = NULL;
+ PMC *res = pmc_new(interp, enum_class_ResizablePMCArray);
+
while (1) {
nseqs = not_empty(interp, seqs);
if (!VTABLE_elements(interp, nseqs))
break;
+
for (i = 0; i < VTABLE_elements(interp, nseqs); ++i) {
- seq = VTABLE_get_pmc_keyed_int(interp, nseqs, i);
+ seq = VTABLE_get_pmc_keyed_int(interp, nseqs, i);
cand = VTABLE_get_pmc_keyed_int(interp, seq, 0);
+
/* check if candidate is valid */
for (j = 0; j < VTABLE_elements(interp, nseqs); ++j) {
s = VTABLE_get_pmc_keyed_int(interp, nseqs, j);
+
for (k = 1; k < VTABLE_elements(interp, s); ++k)
if (VTABLE_get_pmc_keyed_int(interp, s, k) == cand) {
cand = NULL;
@@ -1032,16 +1064,19 @@
if (!cand)
real_exception(interp, NULL, E_TypeError,
"inconsisten class hierarchy");
+
/* push candidate onto mro result */
VTABLE_push_pmc(interp, res, cand);
+
/* remove candidate from head of lists */
for (i = 0; i < VTABLE_elements(interp, nseqs); ++i) {
seq = VTABLE_get_pmc_keyed_int(interp, nseqs, i);
- if (VTABLE_get_pmc_keyed_int(interp, seq, 0) == cand) {
+
+ if (VTABLE_get_pmc_keyed_int(interp, seq, 0) == cand)
VTABLE_shift_pmc(interp, seq);
- }
}
}
+
return res;
}
@@ -1049,37 +1084,41 @@
static PMC*
create_class_mro(Interp *interp, PMC *_class)
{
- PMC *lparents, *bases;
+ PMC *lparents, *bases, *base, *lmap;
INTVAL i;
/* list of lists
* [ [class] [mro of bases] [bases] ]
*/
PMC * const lall = pmc_new(interp, enum_class_ResizablePMCArray);
- PMC * const lc = pmc_new(interp, enum_class_ResizablePMCArray);
+ PMC * const lc = pmc_new(interp, enum_class_ResizablePMCArray);
VTABLE_push_pmc(interp, lc, _class);
VTABLE_push_pmc(interp, lall, lc);
bases = get_attrib_num(PMC_data(_class), PCD_PARENTS);
+
for (i = 0; i < VTABLE_elements(interp, bases); ++i) {
- PMC * const base = VTABLE_get_pmc_keyed_int(interp, bases, i);
- PMC * const lmap = PObj_is_class_TEST(base) ?
+ base = VTABLE_get_pmc_keyed_int(interp, bases, i);
+ lmap = PObj_is_class_TEST(base) ?
create_class_mro(interp, base) : base->vtable->mro;
VTABLE_push_pmc(interp, lall, lmap);
}
+
lparents = VTABLE_clone(interp, bases);
VTABLE_push_pmc(interp, lall, lparents);
+
return class_mro_merge(interp, lall);
}
-PMC *
+void
Parrot_add_parent(Interp *interp, PMC *_class, PMC *parent)
{
PMC *current_parent_array;
if (!PObj_is_class_TEST(_class))
internal_exception(1, "Class isn't a ParrotClass");
+
if (!PObj_is_class_TEST(parent) && parent == parent->vtable->pmc_class) {
/* Permit inserting non-classes so at least thaw'ing classes
* is easy. Adding these parents after classes have been
@@ -1087,32 +1126,33 @@
*/
PMC *class_name;
- if (CLASS_ATTRIB_COUNT(_class) != 0) {
+ if (CLASS_ATTRIB_COUNT(_class) != 0)
internal_exception(1, "Subclassing built-in type too late");
- }
- Parrot_add_attribute(interp, _class,
- CONST_STRING(interp, "__value"));
+
+ Parrot_add_attribute(interp, _class, CONST_STRING(interp, "__value"));
+
class_name = pmc_new(interp, enum_class_String);
+
VTABLE_set_string_native(interp, class_name,
VTABLE_name(interp, _class));
+
create_deleg_pmc_vtable(interp, _class, class_name, 1);
} else if (!PObj_is_class_TEST(parent)) {
internal_exception(1, "Parent isn't a ParrotClass");
}
-
current_parent_array = get_attrib_num(PMC_data(_class), PCD_PARENTS);
VTABLE_push_pmc(interp, current_parent_array, parent);
- _class->vtable->mro = create_class_mro(interp, _class);
+ _class->vtable->mro = create_class_mro(interp, _class);
rebuild_attrib_stuff(interp, _class);
- return NULL;
}
/*
-=item C<PMC * Parrot_remove_parent(Interp *interp, PMC *removed_class, PMC
*existing_class)>
+=item C<PMC * Parrot_remove_parent(Interp *interp, PMC *removed_class,
+ PMC *existing_class)>
This currently does nothing but return C<NULL>.
@@ -1128,7 +1168,8 @@
/*
=item C<PMC *
-Parrot_multi_subclass(Interp *interp, PMC *base_class_array, STRING
*child_class_name)>
+Parrot_multi_subclass(Interp *interp, PMC *base_class_array,
+ STRING *child_class_name)>
This currently does nothing but return C<NULL>.
@@ -1137,37 +1178,40 @@
*/
PMC *
-Parrot_multi_subclass(Interp *interp, PMC *base_class_array, STRING
*child_class_name) {
+Parrot_multi_subclass(Interp *interp, PMC *base_class_array,
+ STRING *child_class_name) {
return NULL;
}
/*
=item C<INTVAL
-Parrot_object_isa(Interp *interp, PMC *pmc, PMC *cl)>
+Parrot_object_isa(Interp *interp, PMC *pmc, PMC *_class)>
-Return whether the object C<pmc> is an instance of class C<cl>.
+Returns whether the object C<pmc> is an instance of class C<_class>.
=cut
*/
INTVAL
-Parrot_object_isa(Interp *interp, PMC *pmc, PMC *cl)
+Parrot_object_isa(Interp *interp, PMC *pmc, PMC *_class)
{
- PMC *mro;
+ PMC *mro;
INTVAL i, classcount;
/* if this is not a class */
- if (!PObj_is_class_TEST(pmc)) {
+ if (!PObj_is_class_TEST(pmc))
pmc = VTABLE_get_class(interp, pmc);
- }
- mro = pmc->vtable->mro;
+
+ mro = pmc->vtable->mro;
classcount = VTABLE_elements(interp, mro);
+
for (i = 0; i < classcount; ++i) {
- if (VTABLE_get_pmc_keyed_int(interp, mro, i) == cl)
+ if (VTABLE_get_pmc_keyed_int(interp, mro, i) == _class)
return 1;
}
+
return 0;
}
@@ -1239,6 +1283,7 @@
if (mc->idx[i])
mem_sys_free(mc->idx[i]);
}
+
mem_sys_free(mc->idx);
mem_sys_free(mc);
}
@@ -1254,9 +1299,11 @@
if (!mc)
return;
+
/* is it a valid entry */
if (type >= mc->mc_size || !mc->idx[type])
return;
+
for (i = 0; i < TBL_SIZE; ++i) {
Meth_cache_entry *e;
for (e = mc->idx[type][i]; e;) {
@@ -1265,6 +1312,7 @@
e = next;
}
}
+
mem_sys_free(mc->idx[type]);
mc->idx[type] = NULL;
}
@@ -1286,19 +1334,25 @@
* isn't yet up */
if (!interp->class_hash)
return;
+
if (interp->resume_flag & RESUME_INITIAL)
return;
+
if (!_class) {
invalidate_all_caches(interp);
return;
}
+
type = pmc_type(interp, _class);
+
if (type < 0)
return;
+
if (type == 0) {
invalidate_all_caches(interp);
return;
}
+
invalidate_type_caches(interp, (UINTVAL)type);
}
@@ -1308,28 +1362,31 @@
* i.e. from obj.$Sreg(args)
* If this hash is implemented mark it during DOD
*/
+
PMC *
Parrot_find_method_direct(Interp *interp, PMC *_class, STRING *method_name)
{
PMC * const found = find_method_direct_1(interp, _class, method_name);
- STRING * s1, *s2;
- if (found)
+ STRING *s1, *s2;
+
+ if (!PMC_IS_NULL(found))
return found;
+
s1 = CONST_STRING(interp, "__get_string");
s2 = CONST_STRING(interp, "__get_repr");
+
if (string_equal(interp, method_name, s1) == 0)
return find_method_direct_1(interp, _class, s2);
+
return NULL;
}
PMC *
Parrot_find_method_with_cache(Interp *interp, PMC *_class, STRING *method_name)
{
+ UINTVAL type, bits, i;
- UINTVAL type;
- Caches *mc;
- int is_const;
- UINTVAL bits, i;
+ Caches *mc;
Meth_cache_entry *e, *old;
assert(method_name != 0);
@@ -1338,13 +1395,13 @@
return Parrot_find_method_direct(interp, _class, method_name);
#endif
- is_const = PObj_constant_TEST(method_name);
- if (!is_const) {
+ if (! PObj_constant_TEST(method_name))
return Parrot_find_method_direct(interp, _class, method_name);
- }
- mc = interp->caches;
+
+ mc = interp->caches;
type = _class->vtable->base_type;
bits = (((UINTVAL) method_name->strstart) >> 2) & TBL_SIZE_MASK;
+
if (type >= mc->mc_size) {
if (mc->idx) {
mc->idx = (Meth_cache_entry ***)mem_sys_realloc(mc->idx,
@@ -1354,10 +1411,13 @@
mc->idx = (Meth_cache_entry ***)mem_sys_allocate(
sizeof (Meth_cache_entry ***) * (type + 1));
}
+
for (i = mc->mc_size; i <= type; ++i)
mc->idx[i] = NULL;
+
mc->mc_size = type + 1;
}
+
if (!mc->idx[type]) {
mc->idx[type] = (Meth_cache_entry **)mem_sys_allocate(
sizeof (Meth_cache_entry *) * TBL_SIZE);
@@ -1365,22 +1425,26 @@
for (i = 0; i < TBL_SIZE; ++i)
mc->idx[type][i] = NULL;
}
- e = mc->idx[type][bits];
+
+ e = mc->idx[type][bits];
old = NULL;
+
while (e && e->strstart != method_name->strstart) {
old = e;
- e = e->next;
+ e = e->next;
}
+
if (!e) {
- PMC * const found = Parrot_find_method_direct(interp, _class,
method_name);
/* when here no or no correct entry was at [bits] */
- e = mem_allocate_typed(Meth_cache_entry);
+ e = mem_allocate_typed(Meth_cache_entry);
+
if (old)
old->next = e;
else
mc->idx[type][bits] = e;
- e->pmc = found;
- e->next = NULL;
+
+ e->pmc = Parrot_find_method_direct(interp, _class, method_name);
+ e->next = NULL;
e->strstart = method_name->strstart;
}
@@ -1481,20 +1545,24 @@
Parrot_add_attribute(Interp *interp, PMC* _class, STRING* attr)
{
STRING *full_attr_name;
- char *c_error;
+ char *c_error;
SLOTTYPE * const class_array = (SLOTTYPE *)PMC_data(_class);
- STRING * const class_name = VTABLE_get_string(interp,
+ STRING * const class_name = VTABLE_get_string(interp,
get_attrib_num(class_array, PCD_CLASS_NAME));
- PMC * const attr_array = get_attrib_num(class_array, PCD_CLASS_ATTRIBUTES);
- PMC * const attr_hash = get_attrib_num(class_array, PCD_ATTRIBUTES);
- INTVAL idx = VTABLE_elements(interp, attr_array);
+ PMC * const attr_array = get_attrib_num(class_array,
+ PCD_CLASS_ATTRIBUTES);
+ PMC * const attr_hash = get_attrib_num(class_array, PCD_ATTRIBUTES);
+ INTVAL idx = VTABLE_elements(interp, attr_array);
VTABLE_set_integer_native(interp, attr_array, idx + 1);
VTABLE_set_string_keyed_int(interp, attr_array, idx, attr);
+
full_attr_name = string_concat(interp, class_name,
string_from_cstring(interp, "\0", 1), 0);
+
full_attr_name = string_concat(interp, full_attr_name, attr, 0);
+
/* TODO escape NUL char */
if (VTABLE_exists_keyed_str(interp, attr_hash, full_attr_name))
{
@@ -1502,15 +1570,15 @@
internal_exception(1, "Attribute '%s' already exists", c_error);
string_cstring_free(c_error);
}
+
/*
* TODO check if someone is trying to add attributes to a parent class
* while there are already child class attrs
*/
idx = CLASS_ATTRIB_COUNT(_class)++;
- VTABLE_set_integer_keyed_str(interp, attr_hash,
- attr, idx);
- VTABLE_set_integer_keyed_str(interp, attr_hash,
- full_attr_name, idx);
+ VTABLE_set_integer_keyed_str(interp, attr_hash, attr, idx);
+ VTABLE_set_integer_keyed_str(interp, attr_hash, full_attr_name, idx);
+
return idx;
}
@@ -1536,69 +1604,68 @@
{
/*
* this is called from ParrotObject's vtable now, so
- * their is no need for checking object being a valid
- * object PMC
+ * there is no need for checking object being a valid object PMC
*/
SLOTTYPE * const attrib_array = PMC_data_typed(object, SLOTTYPE *);
- const INTVAL attrib_count = PMC_int_val(object);
+ const INTVAL attrib_count = PMC_int_val(object);
- if (attrib >= attrib_count || attrib < 0) {
+ if (attrib >= attrib_count || attrib < 0)
real_exception(interp, NULL, ATTRIB_NOT_FOUND,
"No such attribute #%d", (int)attrib);
- }
+
return get_attrib_num(attrib_array, attrib);
}
static INTVAL
attr_str_2_num(Interp *interp, PMC *object, STRING *attr)
{
- PMC *_class;
- PMC *attr_hash;
- SLOTTYPE *class_array;
+ PMC *_class, *attr_hash;
+ SLOTTYPE *class_array;
HashBucket *b;
- STRING *delimit;
- STRING *attr_name;
- STRING *obj_name;
- int idx, length;
+ STRING *delimit, *attr_name, *obj_name;
+ int idx, length;
if (!PObj_is_object_TEST(object))
internal_exception(INTERNAL_NOT_IMPLEMENTED,
"Can't set non-core object attribs yet");
_class = GET_CLASS((SLOTTYPE *)PMC_data(object), object);
- if (PObj_is_PMC_shared_TEST(object)) {
- /* XXX Shared objects have the 'wrong' class stored in them
- * (because of the reference to the namespace and because it
- * references PMCs that may go away),
- * since we actually want one from the current interpreter. */
+
+ /* XXX Shared objects have the 'wrong' class stored in them
+ * (because of the reference to the namespace and because it
+ * references PMCs that may go away),
+ * since we actually want one from the current interpreter. */
+ if (PObj_is_PMC_shared_TEST(object))
_class = VTABLE_get_class(interp, object);
- }
- class_array = (SLOTTYPE *)PMC_data(_class);
- attr_hash = get_attrib_num(class_array, PCD_ATTRIBUTES);
- b = parrot_hash_get_bucket(interp,
+
+ class_array = PMC_data_typed(_class, SLOTTYPE *);
+ attr_hash = get_attrib_num(class_array, PCD_ATTRIBUTES);
+ b = parrot_hash_get_bucket(interp,
(Hash*) PMC_struct_val(attr_hash), attr);
+
if (b)
- return PMC_int_val((PMC*)b->value);
+ return PMC_int_val((PMC *)b->value);
/* Create a delimiter for splitting up the Class\0attribute syntax. */
delimit = string_from_cstring(interp, "\0", 1);
/* Calculate the offset and the length of the attribute string. */
- idx = string_str_index(interp, attr, delimit, 0) + 1;
+ idx = string_str_index(interp, attr, delimit, 0) + 1;
+
if (!idx) {
real_exception(interp, NULL, ATTRIB_NOT_FOUND,
"No such attribute '%Ss'", attr);
return 0;
}
+
length = string_length(interp, attr) - idx;
/* Extract the attribute and object name. */
- attr_name = string_substr(interp, attr, idx, length, 0, 0);
- obj_name = string_substr(interp, attr, 0, idx-1, 0, 0);
+ attr_name = string_substr(interp, attr, idx, length, 0, 0);
+ obj_name = string_substr(interp, attr, 0, idx - 1, 0, 0);
real_exception(interp, NULL, ATTRIB_NOT_FOUND,
- "No such attribute '%Ss\\0%Ss'",
- obj_name, attr_name);
+ "No such attribute '%Ss\\0%Ss'", obj_name, attr_name);
return 0;
}
@@ -1620,8 +1687,7 @@
is asking for the correct attribute number.
=item C<PMC *
-Parrot_set_attrib_by_str(Interp *interp, PMC *object,
- STRING *attr, PMC *value)>
+Parrot_set_attrib_by_str(Interp *interp, PMC *object, STRING *attr, PMC
*value)>
Sets attribute with full qualified name C<attr> from C<object> to C<value>.
@@ -1632,19 +1698,19 @@
void
Parrot_set_attrib_by_num(Interp *interp, PMC *object, INTVAL attrib, PMC
*value) {
SLOTTYPE * const attrib_array = PMC_data_typed(object, SLOTTYPE *);
- const INTVAL attrib_count = PMC_int_val(object);
+ const INTVAL attrib_count = PMC_int_val(object);
- if (attrib >= attrib_count || attrib < 0) {
+ if (attrib >= attrib_count || attrib < 0)
real_exception(interp, NULL, ATTRIB_NOT_FOUND,
"No such attribute #%d", (int)attrib);
- }
+
set_attrib_num(object, attrib_array, attrib, value);
}
void
Parrot_set_attrib_by_str(Interp *interp, PMC *object, STRING *attr, PMC
*value) {
-
- Parrot_set_attrib_by_num(interp, object, attr_str_2_num(interp, object,
attr), value);
+ Parrot_set_attrib_by_num(interp, object,
+ attr_str_2_num(interp, object, attr), value);
}
INTVAL
@@ -1654,26 +1720,33 @@
if (!PObj_is_object_TEST(object))
real_exception(interp, NULL, 1, "Not an object");
- class_pmc = GET_CLASS((SLOTTYPE *)PMC_data(object), object);
+
+ class_pmc = GET_CLASS(PMC_data_typed(object, SLOTTYPE *), object);
+
/* unroll common case - object is this class */
- attribs = get_attrib_num(PMC_data(class_pmc), PCD_CLASS_ATTRIBUTES);
+ attribs = get_attrib_num(PMC_data(class_pmc), PCD_CLASS_ATTRIBUTES);
attr_count = VTABLE_elements(interp, attribs);
- offset = PMC_int_val(object) - attr_count;
+ offset = PMC_int_val(object) - attr_count;
+
if (!string_equal(interp, VTABLE_name(interp, class_pmc), _class))
return offset;
+
/* now check mro */
mro = class_pmc->vtable->mro;
- n = VTABLE_elements(interp, mro);
+ n = VTABLE_elements(interp, mro);
+
for (i = 1; i < n; ++i) {
- class_pmc = VTABLE_get_pmc_keyed_int(interp, mro, i);
- attribs = get_attrib_num(PMC_data(class_pmc), PCD_CLASS_ATTRIBUTES);
+ class_pmc = VTABLE_get_pmc_keyed_int(interp, mro, i);
+ attribs = get_attrib_num(PMC_data(class_pmc), PCD_CLASS_ATTRIBUTES);
attr_count = VTABLE_elements(interp, attribs);
- offset -= attr_count;
- if (!string_equal(interp,
- VTABLE_name(interp, class_pmc), _class))
+ offset -= attr_count;
+
+ if (!string_equal(interp, VTABLE_name(interp, class_pmc), _class))
return offset;
}
- return -1; /* error is catched in opcode */
+
+ /* error caught in opcode */
+ return -1;
}
/*
@@ -1683,22 +1756,25 @@
Find and return the constructor method PMC for the named sub. The
classtoken is an identifier for the class used for fast lookup, or 0
-if you don't have an identifier token. Which, as they're currently
-undefined, is pretty likely
+if you don't have an identifier token (which, as they're currently
+undefined, is pretty likely).
=cut
*/
-PMC *Parrot_find_class_constructor(Interp *interp, STRING *_class, INTVAL
classtoken) {
+PMC *Parrot_find_class_constructor(Interp *interp, STRING *_class,
+ INTVAL classtoken) {
return NULL;
}
-PMC *Parrot_find_class_destructor(Interp *interp, STRING *_class, INTVAL
classtoken) {
+PMC *Parrot_find_class_destructor(Interp *interp, STRING *_class,
+ INTVAL classtoken) {
return NULL;
}
-PMC *Parrot_find_class_fallback(Interp *interp, STRING *_class, INTVAL
classtoken) {
+PMC *Parrot_find_class_fallback(Interp *interp, STRING *_class,
+ INTVAL classtoken) {
return NULL;
}
@@ -1731,33 +1807,40 @@
static PMC* C3_merge(Interp *interp, PMC *merge_list)
{
- PMC *result = pmc_new(interp, enum_class_ResizablePMCArray);
+ PMC *result = pmc_new(interp, enum_class_ResizablePMCArray);
int list_count = VTABLE_elements(interp, merge_list);
int cand_count = 0;
- int i;
- PMC *accepted = PMCNULL;
+ int i, reject;
+ PMC *accepted = PMCNULL;
/* Try and find something appropriate to add to the MRO - basically, the
* first list head that is not in the tail of all the other lists. */
for (i = 0; i < list_count; i++) {
- PMC *cand_list = VTABLE_get_pmc_keyed_int(interp, merge_list, i);
- PMC *cand_class;
- int reject = 0;
- int j;
+ PMC *cand_list, *cand_class;
+ int reject, j;
+
+ reject = 0;
+ cand_list = VTABLE_get_pmc_keyed_int(interp, merge_list, i);
+
if (VTABLE_elements(interp, cand_list) == 0)
continue;
+
cand_class = VTABLE_get_pmc_keyed_int(interp, cand_list, 0);
cand_count++;
+
for (j = 0; j < list_count; j++) {
/* Skip the current list. */
if (j != i) {
/* Is it in the tail? If so, reject. */
- PMC *check_list = VTABLE_get_pmc_keyed_int(interp, merge_list,
j);
- int check_length = VTABLE_elements(interp, check_list);
- int k;
+ PMC *check_list;
+ int check_length, k;
+
+ check_list = VTABLE_get_pmc_keyed_int(interp, merge_list, j);
+ check_length = VTABLE_elements(interp, check_list);
for (k = 1; k < check_length; k++) {
- if (VTABLE_get_pmc_keyed_int(interp, check_list, k) ==
cand_class) {
+ if (VTABLE_get_pmc_keyed_int(interp, check_list, k) ==
+ cand_class) {
reject = 1;
break;
}
@@ -1785,9 +1868,12 @@
/* Otherwise, remove what was accepted from the merge lists. */
for (i = 0; i < list_count; i++) {
- PMC *list = VTABLE_get_pmc_keyed_int(interp, merge_list, i);
- int list_count = VTABLE_elements(interp, list);
- int j;
+ PMC *list;
+ int list_count, j;
+
+ list = VTABLE_get_pmc_keyed_int(interp, merge_list, i);
+ list_count = VTABLE_elements(interp, list);
+
for (j = 0; j < list_count; j++) {
if (VTABLE_get_pmc_keyed_int(interp, list, j) == accepted) {
VTABLE_delete_keyed_int(interp, list, j);
@@ -1800,6 +1886,7 @@
* the start of the list, and we're done. */
result = C3_merge(interp, merge_list);
VTABLE_unshift_pmc(interp, result, accepted);
+
return result;
}
@@ -1811,14 +1898,18 @@
int i, parent_count;
/* Now get immediate parents list. */
- Parrot_PCCINVOKE(interp, _class, string_from_const_cstring(interp,
"parents", 0),
+ Parrot_PCCINVOKE(interp, _class,
+ string_from_const_cstring(interp, "parents", 0),
"->P", &immediate_parents);
+
if (immediate_parents == NULL) {
real_exception(interp, NULL, METH_NOT_FOUND,
"Failed to get parents list from class!");
return PMCNULL;
}
+
parent_count = VTABLE_elements(interp, immediate_parents);
+
if (parent_count == 0)
{
/* No parents - MRO just contains this class. */
@@ -1830,10 +1921,13 @@
/* Otherwise, need to do merge. For that, need linearizations of all of
* our parents added to the merge list. */
for (i = 0; i < parent_count; i++) {
- PMC *lin = Parrot_ComputeMRO_C3(interp,
+ PMC *lin;
+ lin = Parrot_ComputeMRO_C3(interp,
VTABLE_get_pmc_keyed_int(interp, immediate_parents, i));
+
if (PMC_IS_NULL(lin))
return PMCNULL;
+
VTABLE_push_pmc(interp, merge_list, lin);
}
@@ -1841,20 +1935,21 @@
* we can merge. */
VTABLE_push_pmc(interp, merge_list, immediate_parents);
result = C3_merge(interp, merge_list);
+
if (PMC_IS_NULL(result))
return PMCNULL;
/* Merged result needs this class on the start, and then we're done. */
VTABLE_unshift_pmc(interp, result, _class);
+
return result;
}
-
/*
=item C<void Parrot_ComposeRole(Interp *interp, PMC *role,
PMC *exclude, int got_exclude,
- PMC *alias, int got_alias,
+ PMC *alias, int got_alias,
PMC *methods_hash, PMC *roles_list)>
Used by the Class and Object PMCs internally to compose a role into either of
@@ -1874,25 +1969,28 @@
void Parrot_ComposeRole(Interp *interp, PMC *role,
PMC *exclude, int got_exclude,
- PMC *alias, int got_alias,
+ PMC *alias, int got_alias,
PMC *methods_hash, PMC *roles_list)
{
PMC *methods;
PMC *methods_iter;
PMC *roles_of_role;
PMC *proposed_add_methods;
+
int i, j, roles_count, roles_of_role_count;
/* Check we have not already composed the role; if so, just ignore it. */
roles_count = VTABLE_elements(interp, roles_list);
+
for (i = 0; i < roles_count; i++) {
if (VTABLE_get_pmc_keyed_int(interp, roles_list, i) == role)
return;
}
/* Get the methods from the role. */
- Parrot_PCCINVOKE(interp, role, string_from_const_cstring(interp,
"methods", 0),
- "->P", &methods);
+ Parrot_PCCINVOKE(interp, role,
+ string_from_const_cstring(interp, "methods", 0), "->P", &methods);
+
if (PMC_IS_NULL(methods))
return;
@@ -1900,20 +1998,31 @@
* put each method that would be OK to add into a proposal list, and
* bail out right away if we find a problem. */
proposed_add_methods = pmc_new(interp, enum_class_Hash);
- methods_iter = VTABLE_get_iter(interp, methods);
+ methods_iter = VTABLE_get_iter(interp, methods);
+
while (VTABLE_get_bool(interp, methods_iter)) {
/* Get current method and its name. */
- STRING *method_name = VTABLE_shift_string(interp, methods_iter);
- PMC *cur_method = VTABLE_get_pmc_keyed_str(interp, methods,
method_name);
+ STRING *method_name;
+ PMC *cur_method;
+ int excluded;
+
+ method_name = VTABLE_shift_string(interp, methods_iter);
+ cur_method = VTABLE_get_pmc_keyed_str(interp, methods, method_name);
/* Need to find the name we'll check for a conflict on. */
- int excluded = 0;
+ excluded = 0;
/* Check if it's in the exclude list. */
if (got_exclude) {
- int exclude_count = VTABLE_elements(interp, exclude);
+ int exclude_count;
+
+ exclude_count = VTABLE_elements(interp, exclude);
+
for (i = 0; i < exclude_count; i++) {
- STRING *check = VTABLE_get_string_keyed_int(interp, exclude,
i);
+ STRING *check;
+
+ check = VTABLE_get_string_keyed_int(interp, exclude, i);
+
if (string_equal(interp, check, method_name) == 0) {
excluded = 1;
break;
@@ -1928,29 +2037,35 @@
if (VTABLE_exists_keyed_str(interp, methods_hash, method_name)) {
/* Conflicts with something already in the class. */
real_exception(interp, NULL, ROLE_COMPOSITION_METH_CONFLICT,
- "A conflict occurred during role composition due to method
'%S'.",
- method_name);
+ "A conflict occurred during role composition "
+ "due to method '%S'.", method_name);
return;
}
/* What about a conflict with ourslef? */
- if (VTABLE_exists_keyed_str(interp, proposed_add_methods,
method_name)) {
+ if (VTABLE_exists_keyed_str(interp, proposed_add_methods,
+ method_name)) {
/* Something very weird is going on. */
real_exception(interp, NULL, ROLE_COMPOSITION_METH_CONFLICT,
"A conflict occurred during role composition;"
- " the method '%S' from the role managed to conflict with
itself somehow.",
- method_name);
+ " the method '%S' from the role managed to conflict "
+ "with itself somehow.", method_name);
return;
}
- /* If we got here, no conflicts! Add method to the "to compose"
list. */
- VTABLE_set_pmc_keyed_str(interp, proposed_add_methods,
method_name, cur_method);
+ /* If we got here, no conflicts! Add method to the "to compose"
+ * list. */
+ VTABLE_set_pmc_keyed_str(interp, proposed_add_methods,
+ method_name, cur_method);
}
/* Now see if we've got an alias. */
if (got_alias && VTABLE_exists_keyed_str(interp, alias, method_name)) {
/* Got one. Get name to alias it to. */
- STRING *alias_name = VTABLE_get_string_keyed_str(interp, alias,
method_name);
+ STRING *alias_name;
+
+ alias_name = VTABLE_get_string_keyed_str(interp,
+ alias, method_name);
/* Is there a method with this name already in the class?
* XXX TODO: multi-method handling. */
@@ -1964,7 +2079,8 @@
}
/* What about a conflict with ourslef? */
- if (VTABLE_exists_keyed_str(interp, proposed_add_methods,
alias_name)) {
+ if (VTABLE_exists_keyed_str(interp, proposed_add_methods,
+ alias_name)) {
real_exception(interp, NULL, ROLE_COMPOSITION_METH_CONFLICT,
"A conflict occurred during role composition"
" due to the aliasing of '%S' to '%S' (role already has"
@@ -1975,21 +2091,26 @@
/* If we got here, no conflicts! Add method to the "to compose"
* list with its alias. */
- VTABLE_set_pmc_keyed_str(interp, proposed_add_methods, alias_name,
cur_method);
+ VTABLE_set_pmc_keyed_str(interp, proposed_add_methods,
+ alias_name, cur_method);
}
}
- /* If we get here, we detected no conflicts. Go ahead and compose the
methods. */
+ /* If we get here, we detected no conflicts. Go ahead and compose the
+ * methods. */
methods_iter = VTABLE_get_iter(interp, proposed_add_methods);
+
while (VTABLE_get_bool(interp, methods_iter)) {
/* Get current method and its name. */
- STRING *method_name = VTABLE_shift_string(interp, methods_iter);
- PMC *cur_method = VTABLE_get_pmc_keyed_str(interp,
proposed_add_methods,
+ STRING *method_name;
+ PMC *cur_method;
+
+ method_name = VTABLE_shift_string(interp, methods_iter);
+ cur_method = VTABLE_get_pmc_keyed_str(interp, proposed_add_methods,
method_name);
/* Add it to the methods of the class. */
- VTABLE_set_pmc_keyed_str(interp, methods_hash, method_name,
- cur_method);
+ VTABLE_set_pmc_keyed_str(interp, methods_hash, method_name,
cur_method);
}
/* Add this role to the roles list. */
@@ -2000,12 +2121,15 @@
* that it did itself. Note that we already have the correct methods
* as roles "flatten" the methods they get from other roles into their
* own method list. */
- Parrot_PCCINVOKE(interp, role, string_from_const_cstring(interp, "roles",
0),
- "->P", &roles_of_role);
+ Parrot_PCCINVOKE(interp, role,
+ string_from_const_cstring(interp, "roles", 0), "->P", &roles_of_role);
roles_of_role_count = VTABLE_elements(interp, roles_of_role);
+
for (i = 0; i < roles_of_role_count; i++) {
/* Only add if we don't already have it in the list. */
- PMC *cur_role = VTABLE_get_pmc_keyed_int(interp, roles_of_role, i);
+ PMC *cur_role;
+ cur_role = VTABLE_get_pmc_keyed_int(interp, roles_of_role, i);
+
for (j = 0; j < roles_count; j++) {
if (VTABLE_get_pmc_keyed_int(interp, roles_list, j) == cur_role) {
/* We ain't be havin' it. */
@@ -2015,7 +2139,6 @@
}
}
-
/*
=back
@@ -2028,7 +2151,6 @@
*/
-
/*
* Local variables:
* c-file-style: "parrot"