Created
June 23, 2011 15:01
-
-
Save anonymous/1042691 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/pmc/resizablepmcarray.pmc b/src/pmc/resizablepmcarray.pmc | |
index 29c0294..ad83307 100644 | |
--- a/src/pmc/resizablepmcarray.pmc | |
+++ b/src/pmc/resizablepmcarray.pmc | |
@@ -602,59 +602,59 @@ Returns the Parrot string representation C<ResizablePMCArray>. | |
/* | |
-=item C<void splice(PMC *value, INTVAL offset, INTVAL count)> | |
+=item C<void splice(PMC *from, INTVAL offset, INTVAL count)> | |
Replaces C<count> elements starting at C<offset> with the elements in | |
-C<value>. | |
+C<from>. | |
-Note that the C<value> PMC can be of any of the various array types. | |
- | |
-Note that this implementation can be *VERY *inefficient as it manipulates | |
-everything via the VTABLE api. | |
+Note that the C<from> PMC can be of any of the various array types. | |
=cut | |
*/ | |
- VTABLE void splice(PMC *value, INTVAL offset, INTVAL count) { | |
- | |
- const INTVAL length = VTABLE_elements(INTERP, SELF); | |
- const INTVAL elems = VTABLE_elements(INTERP, value); | |
- const INTVAL shift = elems - count; | |
- INTVAL i; | |
+ VTABLE void splice(PMC *from, INTVAL offset, INTVAL count) { | |
+ const INTVAL elems0 = VTABLE_elements(INTERP, SELF); | |
+ const INTVAL elems1 = VTABLE_elements(INTERP, from); | |
+ PMC **item = 0; | |
+ INTVAL tail; | |
+ INTVAL i; | |
/* start from end? */ | |
- if (offset < 0) | |
- offset += length; | |
+ if (offset < 0) | |
+ offset += elems0; | |
if (offset < 0) | |
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS, | |
"illegal splice offset\n"); | |
- /* shrink the array */ | |
- if (shift < 0) { | |
- /* start at offset so we don't overwrite values we'll need */ | |
- for (i = offset + count; i < length; ++i) | |
- VTABLE_set_pmc_keyed_int(INTERP, SELF, i + shift, | |
- VTABLE_get_pmc_keyed_int(INTERP, SELF, i)); | |
+ /* number of elements after the splice */ | |
+ tail = elems0 - offset - count; | |
+ if (tail < 0) tail = 0; | |
- SELF.set_integer_native(length + shift); | |
+ item = PMC_array(SELF); | |
+ if (tail > 0 && count > elems1) { | |
+ /* we're shrinking the array, so first move the tail */ | |
+ mem_sys_memmove(item + offset + elems1, item + offset + count, | |
+ tail * sizeof (PMC *)); | |
} | |
- /* grow the array */ | |
- else if (shift > 0) { | |
- SELF.set_integer_native(length + shift); | |
- | |
- /* move the existing values */ | |
- /* start at length-1 so we don't overwrite values we'll need */ | |
- for (i = length - 1; i >= offset; --i) | |
- VTABLE_set_pmc_keyed_int(INTERP, SELF, i + shift, | |
- VTABLE_get_pmc_keyed_int(INTERP, SELF, i)); | |
+ | |
+ /* now resize the array */ | |
+ SELF.set_integer_native(offset + elems1 + tail); | |
+ | |
+ item = PMC_array(SELF); | |
+ if (tail > 0 && count < elems1) { | |
+ /* the array grew, so move the tail to the right */ | |
+ mem_sys_memmove(item + offset + elems1, item + offset + count, | |
+ tail * sizeof (PMC *)); | |
} | |
- /* copy the new values */ | |
- for (i = 0; i < elems; ++i) | |
- VTABLE_set_pmc_keyed_int(INTERP, SELF, i + offset, | |
- VTABLE_get_pmc_keyed_int(INTERP, value, i)); | |
+ /* now copy C<from>'s elements into SELF */ | |
+ if (elems1 > 0) { | |
+ PMC *iter = VTABLE_get_iter(INTERP, from); | |
+ for (i = 0; i < elems1; i++) | |
+ item[offset + i] = VTABLE_shift_pmc(INTERP, iter); | |
+ } | |
} | |
/* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment