Index: src/pmc/managedstruct.pmc =================================================================== --- src/pmc/managedstruct.pmc (revision 38350) +++ src/pmc/managedstruct.pmc (working copy) @@ -29,12 +29,12 @@ * custom_free_func is called before the normal destroy() function does any * work. */ - ATTR void *custom_free_func; + ATTR void (*custom_free_func)(PARROT_INTERP, void *, void *); ATTR void *custom_free_priv; /* if custom_clone_func is set, it will be called *instead* of the normal * clone() function logic. */ - ATTR void *custom_clone_func; + ATTR PMC * (*custom_clone_func)(PARROT_INTERP, PMC *ptr, void *priv); ATTR void *custom_clone_priv; /* @@ -86,8 +86,7 @@ VTABLE void destroy() { void *ptr = PARROT_MANAGEDSTRUCT(SELF)->ptr; if (ptr) { - custom_free_func_t free_func = - (custom_free_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_free_func; + custom_free_func_t free_func = PARROT_MANAGEDSTRUCT(SELF)->custom_free_func; if (free_func) { void *free_data = PARROT_MANAGEDSTRUCT(SELF)->custom_free_priv; free_func(interp, ptr, free_data); @@ -144,8 +143,7 @@ */ VTABLE PMC *clone() { - custom_clone_func_t clone_func = - (custom_clone_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_clone_func; + custom_clone_func_t clone_func = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_func; PMC *dest; if (clone_func) { void *clone_data = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_priv; Index: lib/Parrot/Pmc2c/Parser.pm =================================================================== --- lib/Parrot/Pmc2c/Parser.pm (revision 38350) +++ lib/Parrot/Pmc2c/Parser.pm (working copy) @@ -135,7 +135,10 @@ # name \s* - (\w+) + ( + \w+ + | \(\*\w*\)\(.*?\) + ) # modifiers \s* Index: lib/Parrot/Pmc2c/Attribute.pm =================================================================== --- lib/Parrot/Pmc2c/Attribute.pm (revision 38350) +++ lib/Parrot/Pmc2c/Attribute.pm (working copy) @@ -99,6 +99,13 @@ my $pmcname = $pmc->{name}; my $attrtype = $self->{type}; my $attrname = $self->{name}; + my $isfuncptr = 0; + my $origtype = $attrtype; + if($attrname =~ m/\(\*(\w*)\)\((.*?)\)/) { + $isfuncptr = 1; + $origtype = $attrtype . " (*)(" . $2 . ")"; + $attrname = $1; + } # Store regexes used to check some types to avoid repetitions my $isptrtostring = qr/STRING\s*\*$/; @@ -113,8 +120,15 @@ if (PObj_is_object_TEST(pmc)) { \\ EOA - if ($attrtype eq "INTVAL") { + if ($isfuncptr == 1) { $decl .= <<"EOA"; + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, \\ + "Attributes of type '$origtype' cannot be " \\ + "subclassed from a high-level PMC."); \\ +EOA + } + elsif ($attrtype eq "INTVAL") { + $decl .= <<"EOA"; PMC *attr_value = VTABLE_get_attr_str(interp, \\ pmc, Parrot_str_new_constant(interp, "$attrname")); \\ (dest) = (PMC_IS_NULL(attr_value) ? (INTVAL) 0: VTABLE_get_integer(interp, attr_value)); \\ @@ -161,8 +175,15 @@ if (PObj_is_object_TEST(pmc)) { \\ EOA - if ($attrtype eq "INTVAL") { + if ($isfuncptr == 1) { $decl .= <<"EOA"; + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, \\ + "Attributes of type '$origtype' cannot be " \\ + "subclassed from a high-level PMC."); \\ +EOA + } + elsif ($attrtype eq "INTVAL") { + $decl .= <<"EOA"; PMC *attr_value = pmc_new(interp, enum_class_Integer); \\ VTABLE_set_integer_native(interp, attr_value, value); \\ VTABLE_set_attr_str(interp, pmc, \\