Skip to content

Commit

Permalink
get rid of Role PMC
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimmy Zhuo committed Mar 22, 2013
1 parent ec716a6 commit 1a70da8
Show file tree
Hide file tree
Showing 7 changed files with 0 additions and 1,228 deletions.
2 changes: 0 additions & 2 deletions MANIFEST
Expand Up @@ -1376,7 +1376,6 @@ src/pmc/resizablefloatarray.pmc []
src/pmc/resizableintegerarray.pmc []
src/pmc/resizablepmcarray.pmc []
src/pmc/resizablestringarray.pmc []
src/pmc/role.pmc []
src/pmc/scalar.pmc []
src/pmc/scheduler.pmc []
src/pmc/schedulermessage.pmc []
Expand Down Expand Up @@ -1895,7 +1894,6 @@ t/pmc/resizableintegerarray.t [test]
t/pmc/resizablepmcarray.t [test]
t/pmc/resizablestringarray.t [test]
t/pmc/ro.t [test]
t/pmc/role.t [test]
t/pmc/scalar.t [test]
t/pmc/schedulermessage.t [test]
t/pmc/signal.t [test]
Expand Down
23 changes: 0 additions & 23 deletions include/parrot/oo.h
Expand Up @@ -43,22 +43,6 @@ typedef enum {
/* HEADERIZER BEGIN: src/oo.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */

PARROT_EXPORT
void Parrot_ComposeRole(PARROT_INTERP,
ARGIN(PMC *role),
ARGIN(PMC *exclude),
int got_exclude,
ARGIN(PMC *alias),
int got_alias,
ARGIN(PMC *methods_hash),
ARGIN(PMC *roles_list))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
__attribute__nonnull__(5)
__attribute__nonnull__(7)
__attribute__nonnull__(8);

PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
Expand Down Expand Up @@ -178,13 +162,6 @@ INTVAL Parrot_oo_register_type(PARROT_INTERP,
__attribute__nonnull__(2)
__attribute__nonnull__(3);

#define ASSERT_ARGS_Parrot_ComposeRole __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(role) \
, PARROT_ASSERT_ARG(exclude) \
, PARROT_ASSERT_ARG(alias) \
, PARROT_ASSERT_ARG(methods_hash) \
, PARROT_ASSERT_ARG(roles_list))
#define ASSERT_ARGS_Parrot_ComputeMRO_C3 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(_class))
Expand Down
209 changes: 0 additions & 209 deletions src/oo.c
Expand Up @@ -1225,215 +1225,6 @@ Parrot_ComputeMRO_C3(PARROT_INTERP, ARGIN(PMC *_class))
return result;
}


/*
=item C<void Parrot_ComposeRole(PARROT_INTERP, PMC *role, PMC *exclude, int
got_exclude, 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
them. The C<role> parameter is the role that we are composing into the class
or role. C<methods_hash> is the hash of method names to invokable PMCs that
contains the methods the class or role has. C<roles_list> is the list of roles
the class or method does.
The C<role> parameter is only dealt with by its external interface. Whether
this routine is usable by any other object system implemented in Parrot very
much depends on how closely the role composition semantics they want are to
the default implementation.
=cut
*/

PARROT_EXPORT
void
Parrot_ComposeRole(PARROT_INTERP, ARGIN(PMC *role),
ARGIN(PMC *exclude), int got_exclude,
ARGIN(PMC *alias), int got_alias,
ARGIN(PMC *methods_hash), ARGIN(PMC *roles_list))
{
ASSERT_ARGS(Parrot_ComposeRole)
PMC *methods;
PMC *methods_iter;
PMC *roles_of_role;
PMC *proposed_add_methods;

INTVAL roles_of_role_count;
INTVAL i;

/* Check we have not already composed the role; if so, just ignore it. */
INTVAL 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_pcc_invoke_method_from_c_args(interp, role, CONST_STRING(interp, "methods"), "->P", &methods);

if (PMC_IS_NULL(methods))
return;

/* We need to check for conflicts before we do the composition. We
* 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 = Parrot_pmc_new(interp, enum_class_Hash);
methods_iter = VTABLE_get_iter(interp, methods);

while (VTABLE_get_bool(interp, methods_iter)) {
STRING * const method_name = VTABLE_shift_string(interp, methods_iter);
PMC * const 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;

/* Check if it's in the exclude list. */
if (got_exclude) {
const int exclude_count = VTABLE_elements(interp, exclude);

for (i = 0; i < exclude_count; ++i) {
const STRING * const check =
VTABLE_get_string_keyed_int(interp, exclude, i);

if (STRING_equal(interp, check, method_name)) {
excluded = 1;
break;
}
}
}

/* If we weren't excluded... */
if (!excluded) {
/* Is there a method with this name already in the class? */

if (VTABLE_exists_keyed_str(interp, methods_hash, method_name)) {
/* Conflicts with something already in the class, unless it's a
* multi-method. */
PMC * const cur_entry = VTABLE_get_pmc_keyed_str(interp, methods_hash, method_name);
if (PMC_IS_NULL(cur_entry) || !VTABLE_isa(interp, cur_entry, CONST_STRING(interp, "MultiSub")))
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT,
"A conflict occurred during role composition "
"due to method '%S'.", method_name);
}

/* What about a conflict with ourslef? */
if (VTABLE_exists_keyed_str(interp, proposed_add_methods,
method_name))
/* Something very weird is going on. */
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT,
"A conflict occurred during role composition;"
" the method '%S' from the role managed to conflict "
"with itself somehow.", method_name);

/* 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 * const alias_name = VTABLE_get_string_keyed_str(interp,
alias, method_name);

/* Is there a method with this name already in the class? If it's
* not a multi-method, error. */
if (VTABLE_exists_keyed_str(interp, methods_hash, alias_name)) {
PMC * const cur_entry = VTABLE_get_pmc_keyed_str(interp, methods_hash, alias_name);
if (PMC_IS_NULL(cur_entry) || !VTABLE_isa(interp, cur_entry, CONST_STRING(interp, "MultiSub")))
/* Conflicts with something already in the class. */
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT,
"A conflict occurred during role composition"
" due to the aliasing of '%S' to '%S'.",
method_name, alias_name);
}

/* What about a conflict with ourslef? */
if (VTABLE_exists_keyed_str(interp, proposed_add_methods,
alias_name))
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT,
"A conflict occurred during role composition"
" due to the aliasing of '%S' to '%S' (role already has"
" a method '%S').", method_name, alias_name, alias_name);

/* If we get 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);
}
}

/* 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 * const method_name = VTABLE_shift_string(interp, methods_iter);
PMC * const cur_method = VTABLE_get_pmc_keyed_str(interp,
proposed_add_methods, method_name);

/* Add it to the methods of the class. */
PMC * const cur_entry = VTABLE_get_pmc_keyed_str(interp, methods_hash, method_name);
if (VTABLE_isa(interp, cur_method, CONST_STRING(interp, "MultiSub"))) {
/* The thing we're adding is a multi-sub, but is the thing in the
* class already a multi-sub? */
if (!PMC_IS_NULL(cur_entry) && VTABLE_isa(interp, cur_entry, CONST_STRING(interp, "MultiSub"))) {
/* Class already has a multi-sub; need to merge our methods into it. */
const INTVAL num_subs = VTABLE_elements(interp, cur_method);
INTVAL j;
for (j = 0; j < num_subs; ++j)
VTABLE_push_pmc(interp, cur_entry, VTABLE_get_pmc_keyed_int(interp,
cur_method, j));
}
else {
/* It's not, and we didn't conflict so must be no entry. Just stick it in. */
VTABLE_set_pmc_keyed_str(interp, methods_hash, method_name, cur_method);
}
}
else {
/* Are we adding into a multi-sub? */
if (!PMC_IS_NULL(cur_entry) && VTABLE_isa(interp, cur_entry, CONST_STRING(interp, "MultiSub")))
VTABLE_push_pmc(interp, cur_entry, cur_method);
else
VTABLE_set_pmc_keyed_str(interp, methods_hash, method_name, cur_method);
}
}

/* Add this role to the roles list. */
VTABLE_push_pmc(interp, roles_list, role);
++roles_count;

/* As a result of composing this role, we will also now do the roles
* 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_pcc_invoke_method_from_c_args(interp, role, CONST_STRING(interp, "roles"), "->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 * const cur_role = VTABLE_get_pmc_keyed_int(interp,
roles_of_role, i);
INTVAL j;

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. */
VTABLE_push_pmc(interp, roles_list, cur_role);
}
}
}
}


/*
=back
Expand Down
10 changes: 0 additions & 10 deletions src/ops/object.ops
Expand Up @@ -433,16 +433,6 @@ inline op removeparent(invar PMC, invar PMC) :object_classes {
VTABLE_remove_parent(interp, $1, $2);
}

=item B<addrole>(invar PMC, invar PMC)

Compose the role $2 into $1.

=cut

inline op addrole(invar PMC, invar PMC) :object_classes {
VTABLE_add_role(interp, $1, $2);
}

=item B<addattribute>(invar PMC, in STR)

Add the attribute named $2 to the class $1.
Expand Down
63 changes: 0 additions & 63 deletions src/pmc/class.pmc
Expand Up @@ -1062,25 +1062,6 @@ if the class has been instantiated.

/*

=item C<void add_role(PMC *role)>

Adds the supplied PMC to the list of roles for the class, provided there are
no conflicts.

=cut

*/
VTABLE void add_role(PMC *role) {
const Parrot_Class_attributes * const _class = PARROT_CLASS(SELF);

/* Do the composition. */
Parrot_ComposeRole(INTERP, role,
_class->resolve_method, !PMC_IS_NULL(_class->resolve_method),
PMCNULL, 0, _class->methods, _class->roles);
}

/*

=item C<PMC *inspect_str(STRING *what)>

Provides introspection of a specific piece of information about the class. The
Expand Down Expand Up @@ -2036,50 +2017,6 @@ Returns the roles array PMC.

/*

=item C<void add_role(PMC *role, PMC *exclude :optional :named("exclude"),
PMC *alias :optional :named("alias"))>

Composes a role into a class with the given exclusions and aliases.

=cut

*/
METHOD add_role(PMC *role,
PMC *exclude_method :optional :named("exclude_method"),
int has_exclude_method :opt_flag,
PMC *alias_method :optional :named("alias_method"),
int has_alias_method :opt_flag) {

Parrot_Class_attributes * const _class = PARROT_CLASS(SELF);

/* Add everything on the resolve list to the exclude list; if we have
* no exclude list, pass along the resolve list in its place if it has
* any methods listed in it. */
if (!has_exclude_method) {
if (VTABLE_elements(INTERP, _class->resolve_method) != 0) {
exclude_method = _class->resolve_method;
has_exclude_method = 1;
}
}
else {
const int resolve_count = VTABLE_elements(INTERP, _class->resolve_method);
int i;

for (i = 0; i < resolve_count; ++i) {
STRING * const meth_name = VTABLE_get_string_keyed_int(INTERP,
_class->resolve_method, i);
VTABLE_push_string(INTERP, exclude_method, meth_name);
}
}

/* Do the composition. */
Parrot_ComposeRole(INTERP, role, exclude_method, has_exclude_method,
alias_method, has_alias_method,
_class->methods, _class->roles);
}

/*

=item C<void inspect(STRING *what :optional)>

Gets all introspection data for the class or, if the optional string
Expand Down

0 comments on commit 1a70da8

Please sign in to comment.