# New Ticket Created by  Patrick R. Michaud 
# Please include the string:  [perl #54522]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=54522 >


The 'lower' method for String objects causes a segfault
in subclasses of String.  Test case:

$ cat y.pir
.sub main :main
    ##  check that 'lower' method works for String
    $P0 = new 'String'
    $P0 = 'String AbCdE.'
    say $P0
    $P1 = $P0.'lower'()
    say $P1

    ##  check that 'lower' method works for subclass of String
    $P99 = subclass 'String', 'MyString'
    $P0 = new 'MyString'
    $P0 = 'MyString AbCdE.'
    say $P0
    $P1 = $P0.'lower'()
    say $P1
.end
$ ./parrot y.pir
String AbCdE.
string abcde.
MyString AbCdE.
Segmentation fault
$

Here's the lower method itself:

    METHOD lower() {
        STRING * const s   = string_downcase(INTERP,
            VTABLE_get_string(INTERP, SELF));
        PMC * const    ret = pmc_new_noinit(INTERP, SELF->vtable->base_type);
        PMC_str_val(ret)   = s;

        PObj_custom_mark_SET(ret);

        RETURN(PMC *ret);
    }

I'm guessing the problem is the C< PMC_str_val(ret) > assignment,
where C<ret> is being generated with the same type as the invocant.
If the invocant is a String, great, but if it's a subclass of String
then we have a problem.

However, since our calling conventions now handle autoboxing, 
perhaps an even better solution would be to skip creating a
return value PMC at all, but let the autoboxer handle it:

    METHOD lower() {
        STRING * const s   = string_downcase(INTERP,
            VTABLE_get_string(INTERP, SELF));
        RETURN(STRING *s);
    }

If we decide that C<lower> needs to return an object with the
same type as the invocant, then we should probably convert
PMC_str_val() above to be a VTABLE call or set_string_native
or something like that.


And perhaps an even better solution to this would be to not
provide a 'lower' method in the String class at all.  It's not
immediately obvious to me why 'lower' exists but not 'upper',
or that 'lower' is the appropriate name.  (Perhaps 'tolower'
or 'lc' are better names?)

Pm

Reply via email to