Index: src/pmc/object.pmc =================================================================== --- src/pmc/object.pmc (revision 36494) +++ src/pmc/object.pmc (working copy) @@ -104,6 +104,32 @@ return -1; } +/* Get the first PMCProxy parent class, + * (works for single inheritance from a PMC, other usages untested) + * or PMCNULL if nothing appropiate is found + */ +static PMC * +getPMCProxy(PARROT_INTERP, PMC *self, STRING *name) +{ + PMC *result = PMCNULL; + PMC *parents = PARROT_CLASS(PARROT_OBJECT(self)->_class)->all_parents; + INTVAL numparents = VTABLE_get_integer(interp, parents); + INTVAL i; + for (i= 0; i < numparents; ++i) { + if ((VTABLE_get_pmc_keyed_int(interp, parents, i)->vtable->base_type) + == enum_class_PMCProxy) { + STRING * const attrproxy = CONST_STRING(interp, "proxy"); + if (Parrot_str_not_equal(interp, name, attrproxy)) { + PMC *prx = VTABLE_get_attr_str(interp, self, attrproxy); + if (!(PMC_IS_NULL(prx) || prx == self)) + result = prx; + } + break; + } + } + return result; +} + pmclass Object need_ext { ATTR PMC *_class; /* The class this is an instance of. */ ATTR PMC *attrib_store; /* The attributes store - a resizable PMC array. */ @@ -221,10 +247,14 @@ /* Look up the index. */ index = get_attrib_index(interp, obj->_class, name); - /* If lookup failed, exception. */ - if (index == -1) + /* If lookup failed, use proxy PMC or exception. */ + if (index == -1) { + PMC *prx = getPMCProxy(interp, SELF, name); + if (! PMC_IS_NULL(prx)) + return VTABLE_get_attr_str(interp, prx, name); Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ATTRIB_NOT_FOUND, "No such attribute '%S'", name); + } return VTABLE_get_pmc_keyed_int(interp, obj->attrib_store, index); } @@ -281,10 +311,16 @@ index = get_attrib_index(interp, obj->_class, name); - /* If lookup failed, exception. */ - if (index == -1) + /* If lookup failed, use proxy PMC or exception. */ + if (index == -1) { + PMC *prx = getPMCProxy(interp, SELF, name); + if (! PMC_IS_NULL(prx)) { + VTABLE_set_attr_str(interp, prx, name, value); + return; + } Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ATTRIB_NOT_FOUND, "No such attribute '%S'", name); + } VTABLE_set_pmc_keyed_int(interp, obj->attrib_store, index, value); } Index: src/pmc/exceptionhandler.pmc =================================================================== --- src/pmc/exceptionhandler.pmc (revision 36494) +++ src/pmc/exceptionhandler.pmc (working copy) @@ -192,20 +192,28 @@ STRING * const sev = CONST_STRING(interp, "severity"); STRING * const ex_str = CONST_STRING(interp, "Exception"); +/* Parrot_ExceptionHandler_attributes * const core_struct = PARROT_EXCEPTIONHANDLER(SELF); +*/ INTVAL severity = VTABLE_get_integer_keyed_str(interp, exception, sev); if (exception->vtable->base_type == enum_class_Exception || VTABLE_isa(INTERP, exception, ex_str)) { - PMC * handled_types; + PMC *handled_types; + PMC *handled_types_except; + INTVAL min_severity; + INTVAL max_severity; GET_ATTR_handled_types(INTERP, SELF, handled_types); + GET_ATTR_handled_types_except(INTERP, SELF, handled_types_except); + GET_ATTR_min_severity(INTERP, SELF, min_severity); + GET_ATTR_max_severity(INTERP, SELF, max_severity); - if (severity < core_struct->min_severity) { + if (severity < min_severity) { RETURN(INTVAL 0); } - if (core_struct->max_severity > 0 - && severity > core_struct->max_severity) { + if (max_severity > 0 + && severity > max_severity) { RETURN(INTVAL 0); } if (! PMC_IS_NULL(handled_types)) { @@ -222,22 +230,22 @@ RETURN(INTVAL 0); } - if (core_struct->handled_types_except != PMCNULL) { - const INTVAL elems = VTABLE_elements(interp, core_struct->handled_types_except); + if (handled_types_except != PMCNULL) { + const INTVAL elems = VTABLE_elements(interp, handled_types_except); const INTVAL type = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "type")); INTVAL i; for (i = 0; i < elems; i++) { const INTVAL handled_type = VTABLE_get_integer_keyed_int(interp, - core_struct->handled_types_except, i); + handled_types_except, i); if (handled_type == type) RETURN(INTVAL 0); } RETURN(INTVAL 1); } - else if (core_struct->max_severity > 0 || - core_struct->min_severity > 0) { + else if (max_severity > 0 || + min_severity > 0) { RETURN(INTVAL 1); } Index: t/pmc/exceptionhandler.t =================================================================== --- t/pmc/exceptionhandler.t (revision 36494) +++ t/pmc/exceptionhandler.t (working copy) @@ -200,9 +200,11 @@ throw $P0 subclassed_failed: + .get_results($P1) .return(0) subclassed_handler: + .get_results($P1) .return(1) .end