# New Ticket Created by Matt Fowles # Please include the string: [perl #30294] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=30294 >
All~ This patch implements the better allocation scheme of doubling array capacity, for the Resizable*Array pmcs. Also, includes a slight change to tests that will test a wider range of behavior. Matt
Index: classes/resizablebooleanarray.pmc =================================================================== RCS file: /cvs/public/parrot/classes/resizablebooleanarray.pmc,v retrieving revision 1.1 diff -u -r1.1 resizablebooleanarray.pmc --- classes/resizablebooleanarray.pmc 14 Jun 2004 14:03:03 -0000 1.1 +++ classes/resizablebooleanarray.pmc 15 Jun 2004 22:05:29 -0000 @@ -21,6 +21,12 @@ #include "parrot/parrot.h" +typedef struct _SizeBooleanData { + INTVAL size; + INTVAL data[1]; +} SizeBooleanData; +#define NEEDED_SIZE(n) ((n-1)*sizeof(INTVAL) + sizeof(SizeBooleanData)) + pmclass ResizableBooleanArray extends FixedBooleanArray need_ext does array { /* @@ -34,17 +40,38 @@ */ INTVAL get_integer_keyed_int (INTVAL key) { - INTVAL *data; + SizeBooleanData *sd; if (key < 0) internal_exception(OUT_OF_BOUNDS, "ResizableBooleanArray: index out of bounds!\n"); if(key >= PMC_int_val(SELF)) DYNSELF.set_integer_native(key+1); - data = (INTVAL *)PMC_data(SELF); - return data[key]; + sd = (SizeBooleanData *)PMC_data(SELF); + return sd->data[key]; } +/* + +=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)> + +Sets the integer value of the element at index C<key> to C<value>. + +=cut + +*/ + + void set_integer_keyed_int (INTVAL key, INTVAL value) { + SizeBooleanData *sd; + if (key < 0) + internal_exception(OUT_OF_BOUNDS, + "ResizableBooleanArray: index out of bounds!\n"); + if(key >= PMC_int_val(SELF)) + DYNSELF.set_integer_native(key+1); + + sd = (SizeBooleanData *)PMC_data(SELF); + sd->data[key] = (value != 0); + } /* @@ -57,36 +84,50 @@ */ void set_integer_native (INTVAL size) { - + SizeBooleanData *sd; if (size < 0) internal_exception(OUT_OF_BOUNDS, "ResizableBooleanArray: Can't resize!\n"); + sd = PMC_data(SELF); PMC_int_val(SELF) = size; - PMC_data(SELF) = mem_sys_realloc(PMC_data(SELF), size*sizeof(INTVAL)); + if(sd == NULL) { + sd = mem_sys_allocate(NEEDED_SIZE(size)); + sd->size = size; + } else if(size >= sd->size) { + sd->size = size < 2*sd->size ? sd->size*2 : size; + sd = mem_sys_realloc(sd, NEEDED_SIZE(sd->size)); + } else { + return; + } + + PMC_data(SELF) = sd; PObj_active_destroy_SET(SELF); } /* -=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)> +=item C<PMC *clone()> -Sets the integer value of the element at index C<key> to C<value>. +Creates and returns a copy of the array. =cut */ - void set_integer_keyed_int (INTVAL key, INTVAL value) { - INTVAL *data; - if (key < 0) - internal_exception(OUT_OF_BOUNDS, - "ResizableBooleanArray: index out of bounds!\n"); - if(key >= PMC_int_val(SELF)) - DYNSELF.set_integer_native(key+1); - - data = (INTVAL*)PMC_data(SELF); - data[key] = (value != 0); + PMC* clone () { + SizeBooleanData *sd; + PMC * dest = pmc_new(INTERP, SELF->vtable->base_type); + + if (!PMC_data(SELF)) + return dest; + PMC_int_val(dest) = PMC_int_val(SELF); + sd = PMC_data(SELF); + + PMC_data(dest) = mem_sys_allocate(NEEDED_SIZE(sd->size)); + mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), NEEDED_SIZE(sd->size)); + PObj_active_destroy_SET(dest); + return dest; } } @@ -102,6 +143,7 @@ =head1 HISTORY Initial version 2004.06.11 by Matt Fowles +Changed allocator to double size - MF 2004.06.15 =cut Index: classes/resizablefloatarray.pmc =================================================================== RCS file: /cvs/public/parrot/classes/resizablefloatarray.pmc,v retrieving revision 1.1 diff -u -r1.1 resizablefloatarray.pmc --- classes/resizablefloatarray.pmc 14 Jun 2004 14:03:03 -0000 1.1 +++ classes/resizablefloatarray.pmc 15 Jun 2004 22:05:29 -0000 @@ -21,6 +21,12 @@ #include "parrot/parrot.h" +typedef struct _SizeFloatData { + INTVAL size; + FLOATVAL data[1]; +} SizeFloatData; +#define NEEDED_SIZE(n) ((n-1)*sizeof(FLOATVAL) + sizeof(SizeFloatData)) + pmclass ResizableFloatArray extends FixedFloatArray need_ext does array { @@ -35,17 +41,39 @@ */ FLOATVAL get_number_keyed_int (INTVAL key) { - FLOATVAL *data; + SizeFloatData *sd; if (key < 0) internal_exception(OUT_OF_BOUNDS, "ResizableFloatArray: index out of bounds!\n"); if (key >= PMC_int_val(SELF)) DYNSELF.set_integer_native(key+1); - data = (FLOATVAL *)PMC_data(SELF); - return data[key]; + sd = (SizeFloatData *)PMC_data(SELF); + return sd->data[key]; } +/* + +=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)> + +Sets the floating-point value of the element at index C<key> to +C<value>. + +=cut + +*/ + + void set_number_keyed_int (INTVAL key, FLOATVAL value) { + SizeFloatData *sd; + if (key < 0) + internal_exception(OUT_OF_BOUNDS, + "ResizableFloatArray: index out of bounds!\n"); + if(key >= PMC_int_val(SELF)) + DYNSELF.set_integer_native(key+1); + + sd = (SizeFloatData *)PMC_data(SELF); + sd->data[key] = value; + } /* @@ -58,34 +86,50 @@ */ void set_integer_native (INTVAL size) { + SizeFloatData *sd; if (size < 0) - internal_exception(OUT_OF_BOUNDS, "ResizableFloatArray: Can't resize!\n"); + internal_exception(OUT_OF_BOUNDS, + "ResizableFloatArray: Can't resize!\n"); + + sd = PMC_data(SELF); PMC_int_val(SELF) = size; - PMC_data(SELF) = mem_sys_realloc(PMC_data(SELF), size*sizeof(FLOATVAL)); + if(sd == NULL) { + sd = mem_sys_allocate(NEEDED_SIZE(size)); + sd->size = size; + } else if(size >= sd->size) { + sd->size = size < 2*sd->size ? sd->size*2 : size; + sd = mem_sys_realloc(sd, NEEDED_SIZE(sd->size)); + } else { + return; + } + + PMC_data(SELF) = sd; PObj_active_destroy_SET(SELF); } /* -=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)> +=item C<PMC *clone()> -Sets the floating-point value of the element at index C<key> to -C<value>. +Creates and returns a copy of the array. =cut */ - void set_number_keyed_int (INTVAL key, FLOATVAL value) { - FLOATVAL *data; - if (key < 0) - internal_exception(OUT_OF_BOUNDS, - "ResizableFloatArray: index out of bounds!\n"); - if(key >= PMC_int_val(SELF)) - DYNSELF.set_integer_native(key+1); - - data = (FLOATVAL*)PMC_data(SELF); - data[key] = value; + PMC* clone () { + SizeFloatData *sd; + PMC * dest = pmc_new(INTERP, SELF->vtable->base_type); + + if (!PMC_data(SELF)) + return dest; + PMC_int_val(dest) = PMC_int_val(SELF); + sd = PMC_data(SELF); + + PMC_data(dest) = mem_sys_allocate(NEEDED_SIZE(sd->size)); + mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), NEEDED_SIZE(sd->size)); + PObj_active_destroy_SET(dest); + return dest; } } @@ -101,6 +145,7 @@ =head1 HISTORY Initial version 2004.06.11 by Matt Fowles +Changed allocator to double size - MF 2004.06.15 =cut Index: classes/resizableintegerarray.pmc =================================================================== RCS file: /cvs/public/parrot/classes/resizableintegerarray.pmc,v retrieving revision 1.1 diff -u -r1.1 resizableintegerarray.pmc --- classes/resizableintegerarray.pmc 14 Jun 2004 14:03:03 -0000 1.1 +++ classes/resizableintegerarray.pmc 15 Jun 2004 22:05:29 -0000 @@ -21,6 +21,12 @@ #include "parrot/parrot.h" +typedef struct _SizeIntData { + INTVAL size; + INTVAL data[1]; +} SizeIntData; +#define NEEDED_SIZE(n) ((n-1)*sizeof(INTVAL) + sizeof(SizeIntData)) + pmclass ResizableIntegerArray extends FixedIntegerArray need_ext does array { /* @@ -34,15 +40,37 @@ */ INTVAL get_integer_keyed_int (INTVAL key) { - INTVAL *data; + SizeIntData *sd; if (key < 0) internal_exception(OUT_OF_BOUNDS, "ResizableIntegerArray: index out of bounds!\n"); if(key >= PMC_int_val(SELF)) DYNSELF.set_integer_native(key+1); - data = (INTVAL *)PMC_data(SELF); - return data[key]; + sd = (SizeIntData *)PMC_data(SELF); + return sd->data[key]; + } + +/* + +=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)> + +Sets the integer value of the element at index C<key> to C<value>. + +=cut + +*/ + + void set_integer_keyed_int (INTVAL key, INTVAL value) { + SizeIntData *sd; + if (key < 0) + internal_exception(OUT_OF_BOUNDS, + "ResizableIntegerArray: index out of bounds!\n"); + if(key >= PMC_int_val(SELF)) + DYNSELF.set_integer_native(key+1); + + sd = (SizeIntData *)PMC_data(SELF); + sd->data[key] = value; } /* @@ -56,33 +84,50 @@ */ void set_integer_native (INTVAL size) { + SizeIntData *sd; if (size < 0) - internal_exception(OUT_OF_BOUNDS, "ResizableIntegerArray: Can't resize!\n"); + internal_exception(OUT_OF_BOUNDS, + "ResizableIntegerArray: Can't resize!\n"); + + sd = PMC_data(SELF); PMC_int_val(SELF) = size; - PMC_data(SELF) = mem_sys_realloc(PMC_data(SELF), size*sizeof(INTVAL)); + if(sd == NULL) { + sd = mem_sys_allocate(NEEDED_SIZE(size)); + sd->size = size; + } else if(size >= sd->size) { + sd->size = size < 2*sd->size ? sd->size*2 : size; + sd = mem_sys_realloc(sd, NEEDED_SIZE(sd->size)); + } else { + return; + } + + PMC_data(SELF) = sd; PObj_active_destroy_SET(SELF); } /* -=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)> +=item C<PMC *clone()> -Sets the integer value of the element at index C<key> to C<value>. +Creates and returns a copy of the array. =cut */ - void set_integer_keyed_int (INTVAL key, INTVAL value) { - INTVAL *data; - if (key < 0) - internal_exception(OUT_OF_BOUNDS, - "ResizableIntegerArray: index out of bounds!\n"); - if(key >= PMC_int_val(SELF)) - DYNSELF.set_integer_native(key+1); - - data = (INTVAL*)PMC_data(SELF); - data[key] = value; + PMC* clone () { + SizeIntData *sd; + PMC * dest = pmc_new(INTERP, SELF->vtable->base_type); + + if (!PMC_data(SELF)) + return dest; + PMC_int_val(dest) = PMC_int_val(SELF); + sd = PMC_data(SELF); + + PMC_data(dest) = mem_sys_allocate(NEEDED_SIZE(sd->size)); + mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), NEEDED_SIZE(sd->size)); + PObj_active_destroy_SET(dest); + return dest; } } @@ -98,6 +143,7 @@ =head1 HISTORY Initial version 2004.06.11 by Matt Fowles +Changed allocator to double size - MF 2004.06.15 =cut Index: classes/resizablepmcarray.pmc =================================================================== RCS file: /cvs/public/parrot/classes/resizablepmcarray.pmc,v retrieving revision 1.1 diff -u -r1.1 resizablepmcarray.pmc --- classes/resizablepmcarray.pmc 14 Jun 2004 14:03:03 -0000 1.1 +++ classes/resizablepmcarray.pmc 15 Jun 2004 22:05:29 -0000 @@ -22,8 +22,13 @@ #include "parrot/parrot.h" +typedef struct _SizePMCData { + INTVAL size; + PMC* data[1]; +} SizePMCData; +#define NEEDED_SIZE(n) ((n-1)*sizeof(PMC*) + sizeof(SizePMCData)) + pmclass ResizablePMCArray extends FixedPMCArray need_ext does array { - /* @@ -36,18 +41,39 @@ */ PMC* get_pmc_keyed_int (INTVAL key) { - PMC **data; - PMC *res; + SizePMCData *sd; if (key < 0) internal_exception(OUT_OF_BOUNDS, "ResizablePMCArray: index out of bounds!\n"); if(key >= PMC_int_val(SELF)) DYNSELF.set_integer_native(key+1); - data = (PMC **)PMC_data(SELF); - if(data[key] == PMCNULL) - data[key] = pmc_new(INTERP, enum_class_Undef); - return data[key]; + sd = (SizePMCData *)PMC_data(SELF); + if(sd->data[key] == PMCNULL) + sd->data[key] = pmc_new(INTERP, enum_class_Undef); + return sd->data[key]; + } + +/* + +=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)> + +Sets the PMC value of the element at index C<key> to C<*src>. + +=cut + +*/ + + void set_pmc_keyed_int (INTVAL key, PMC* src) { + SizePMCData *sd; + if (key < 0) + internal_exception(OUT_OF_BOUNDS, + "ResizablePMCArray: index out of bounds!\n"); + if(key >= PMC_int_val(SELF)) + DYNSELF.set_integer_native(key+1); + + sd = (SizePMCData *)PMC_data(SELF); + sd->data[key] = src; } @@ -63,41 +89,55 @@ void set_integer_native (INTVAL size) { int i; - PMC **data; + SizePMCData *sd; if (size < 0) - internal_exception(OUT_OF_BOUNDS, "ResizablePMCArray: Can't resize!\n"); + internal_exception(OUT_OF_BOUNDS, + "ResizablePMCArray: Can't resize!\n"); - data = (PMC**)mem_sys_realloc(PMC_data(SELF), size*sizeof(PMC*)); - for(i = PMC_int_val(SELF); i < size; i++) - data[i] = PMCNULL; - + sd = (SizePMCData *)PMC_data(SELF); PMC_int_val(SELF) = size; - PMC_data(SELF) = data; + if(sd == NULL) { + i = 0; + sd = mem_sys_allocate(NEEDED_SIZE(size)); + sd->size = size; + } else if(size >= sd->size) { + i = sd->size; + sd->size = size < 2*sd->size ? sd->size*2 : size; + sd = mem_sys_realloc(sd, NEEDED_SIZE(sd->size)); + } else { + return; + } + for(; i < sd->size; i++) + sd->data[i] = PMCNULL; + + PMC_data(SELF) = sd; PObj_custom_mark_destroy_SETALL(SELF); } - /* -=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)> +=item C<PMC *clone()> -Sets the PMC value of the element at index C<key> to C<*src>. +Creates and returns a copy of the array. =cut */ - void set_pmc_keyed_int (INTVAL key, PMC* src) { - PMC **data; - if (key < 0) - internal_exception(OUT_OF_BOUNDS, - "ResizablePMCArray: index out of bounds!\n"); - if(key >= PMC_int_val(SELF)) - DYNSELF.set_integer_native(key+1); - - data = (PMC**)PMC_data(SELF); - data[key] = src; + PMC* clone () { + SizePMCData *sd; + PMC * dest = pmc_new(INTERP, SELF->vtable->base_type); + + if (!PMC_data(SELF)) + return dest; + PMC_int_val(dest) = PMC_int_val(SELF); + sd = (SizePMCData *)PMC_data(SELF); + + PMC_data(dest) = mem_sys_allocate(NEEDED_SIZE(sd->size)); + mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), NEEDED_SIZE(sd->size)); + PObj_custom_mark_destroy_SETALL(SELF); + return dest; } } @@ -113,6 +153,7 @@ =head1 HISTORY Initial version 2004.06.11 by Matt Fowles +Changed allocator to double size - MF 2004.06.15 =cut Index: classes/resizablestringarray.pmc =================================================================== RCS file: /cvs/public/parrot/classes/resizablestringarray.pmc,v retrieving revision 1.1 diff -u -r1.1 resizablestringarray.pmc --- classes/resizablestringarray.pmc 14 Jun 2004 14:03:03 -0000 1.1 +++ classes/resizablestringarray.pmc 15 Jun 2004 22:05:29 -0000 @@ -21,6 +21,12 @@ #include "parrot/parrot.h" +typedef struct _SizeStringData { + INTVAL size; + STRING* data[1]; +} SizeStringData; +#define NEEDED_SIZE(n) ((n-1)*sizeof(STRING*) + sizeof(SizeStringData)) + pmclass ResizableStringArray extends FixedStringArray need_ext does array { /* @@ -34,15 +40,37 @@ */ STRING* get_string_keyed_int (INTVAL key) { - STRING **data; + SizeStringData *sd; if (key < 0) internal_exception(OUT_OF_BOUNDS, "ResizableStringArray: index out of bounds!\n"); if(key >= PMC_int_val(SELF)) DYNSELF.set_integer_native(key+1); - data = (STRING **)PMC_data(SELF); - return data[key]; + sd = (SizeStringData *)PMC_data(SELF); + return sd->data[key]; + } + +/* + +=item C<void set_string_keyed_int(INTVAL key, STRING *value)> + +Sets the Parrot string value of the element at index C<key> to C<value>. + +=cut + +*/ + + void set_string_keyed_int (INTVAL key, STRING* value) { + SizeStringData *sd; + if (key < 0) + internal_exception(OUT_OF_BOUNDS, + "ResizableStringArray: index out of bounds!\n"); + if(key >= PMC_int_val(SELF)) + DYNSELF.set_integer_native(key+1); + + sd = (SizeStringData *)PMC_data(SELF); + sd->data[key] = value; } /* @@ -57,41 +85,55 @@ void set_integer_native (INTVAL size) { int i; - STRING **data; + SizeStringData *sd; + if (size < 0) internal_exception(OUT_OF_BOUNDS, "ResizableStringArray: Can't resize!\n"); - data = mem_sys_realloc(PMC_data(SELF), size*sizeof(STRING*)); - for(i = PMC_int_val(SELF); i < size; i++) - data[i] = NULL; - + sd = (SizeStringData *)PMC_data(SELF); PMC_int_val(SELF) = size; - PMC_data(SELF) = data; + if(sd == NULL) { + i = 0; + sd = mem_sys_allocate(NEEDED_SIZE(size)); + sd->size = size; + } else if(size >= sd->size) { + i = sd->size; + sd->size = size < 2*sd->size ? sd->size*2 : size; + sd = mem_sys_realloc(sd, NEEDED_SIZE(sd->size)); + } else { + return; + } + for(; i < sd->size; i++) + sd->data[i] = NULL; + + PMC_data(SELF) = sd; PObj_custom_mark_destroy_SETALL(SELF); } - /* -=item C<void set_string_keyed_int(INTVAL key, STRING *value)> +=item C<PMC *clone()> -Sets the Parrot string value of the element at index C<key> to C<value>. +Creates and returns a copy of the array. =cut */ - void set_string_keyed_int (INTVAL key, STRING* value) { - STRING **data; - if (key < 0) - internal_exception(OUT_OF_BOUNDS, - "ResizableStringArray: index out of bounds!\n"); - if(key >= PMC_int_val(SELF)) - DYNSELF.set_integer_native(key+1); - - data = (STRING**)PMC_data(SELF); - data[key] = value; + PMC* clone () { + SizeStringData *sd; + PMC * dest = pmc_new(INTERP, SELF->vtable->base_type); + + if (!PMC_data(SELF)) + return dest; + PMC_int_val(dest) = PMC_int_val(SELF); + sd = (SizeStringData *)PMC_data(SELF); + + PMC_data(dest) = mem_sys_allocate(NEEDED_SIZE(sd->size)); + mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), NEEDED_SIZE(sd->size)); + PObj_custom_mark_destroy_SETALL(SELF); + return dest; } } @@ -107,6 +149,7 @@ =head1 HISTORY Initial version 2004.06.11 by Matt Fowles +Changed allocator to double size - MF 2004.06.15 =cut Index: t/pmc/resizablebooleanarray.t =================================================================== RCS file: /cvs/public/parrot/t/pmc/resizablebooleanarray.t,v retrieving revision 1.1 diff -u -r1.1 resizablebooleanarray.t --- t/pmc/resizablebooleanarray.t 14 Jun 2004 14:03:06 -0000 1.1 +++ t/pmc/resizablebooleanarray.t 15 Jun 2004 22:05:33 -0000 @@ -242,6 +242,7 @@ output_is(<<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys"); @{[ $fp_equality_macro ]} new P0, .ResizableBooleanArray + set P0, 1 set P0[25], 125 set P0[128], 10.2 Index: t/pmc/resizablefloatarray.t =================================================================== RCS file: /cvs/public/parrot/t/pmc/resizablefloatarray.t,v retrieving revision 1.1 diff -u -r1.1 resizablefloatarray.t --- t/pmc/resizablefloatarray.t 14 Jun 2004 14:03:06 -0000 1.1 +++ t/pmc/resizablefloatarray.t 15 Jun 2004 22:05:33 -0000 @@ -226,6 +226,7 @@ output_is(<<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys"); @{[ $fp_equality_macro ]} new P0, .ResizableFloatArray + set P0, 1 set P0[25], 125 set P0[128], 10.2 Index: t/pmc/resizableintegerarray.t =================================================================== RCS file: /cvs/public/parrot/t/pmc/resizableintegerarray.t,v retrieving revision 1.1 diff -u -r1.1 resizableintegerarray.t --- t/pmc/resizableintegerarray.t 14 Jun 2004 14:03:06 -0000 1.1 +++ t/pmc/resizableintegerarray.t 15 Jun 2004 22:05:33 -0000 @@ -226,6 +226,7 @@ output_is(<<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys"); @{[ $fp_equality_macro ]} new P0, .ResizableIntegerArray + set P0, 1 set P0[25], 125 set P0[128], 10.2 Index: t/pmc/resizablepmcarray.t =================================================================== RCS file: /cvs/public/parrot/t/pmc/resizablepmcarray.t,v retrieving revision 1.1 diff -u -r1.1 resizablepmcarray.t --- t/pmc/resizablepmcarray.t 14 Jun 2004 14:03:06 -0000 1.1 +++ t/pmc/resizablepmcarray.t 15 Jun 2004 22:05:33 -0000 @@ -225,6 +225,7 @@ output_is(<<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys"); @{[ $fp_equality_macro ]} new P0, .ResizablePMCArray + set P0, 1 set P0[25], 125 set P0[128], 10.2 Index: t/pmc/resizablestringarray.t =================================================================== RCS file: /cvs/public/parrot/t/pmc/resizablestringarray.t,v retrieving revision 1.1 diff -u -r1.1 resizablestringarray.t --- t/pmc/resizablestringarray.t 14 Jun 2004 14:03:06 -0000 1.1 +++ t/pmc/resizablestringarray.t 15 Jun 2004 22:05:33 -0000 @@ -227,6 +227,7 @@ output_is(<<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys"); @{[ $fp_equality_macro ]} new P0, .ResizableStringArray + set P0, 1 set P0[25], 125 set P0[128], 10.2