-
-
Save MasterDuke17/9cdf715bc10093721345db9e1e15ecf5 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/strings/ops.c b/src/strings/ops.c | |
index 080951f7..9c2e9d08 100644 | |
--- a/src/strings/ops.c | |
+++ b/src/strings/ops.c | |
@@ -1616,6 +1616,7 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec | |
MVMuint16 sstrands, total_strands; | |
MVMint32 concats_stable = 1; | |
size_t bytes; | |
+ int all_strands_of_same_type, strand_type; | |
MVM_string_check_arg(tc, separator, "join separator"); | |
if (!IS_CONCRETE(input)) | |
@@ -1637,6 +1638,10 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec | |
}); | |
}); | |
+ all_strands_of_same_type = separator->body.storage_type == MVM_STRING_STRAND; | |
+ if (all_strands_of_same_type) | |
+ strand_type = separator->body.storage.strands->blob_string->body.storage_type; | |
+ | |
/* Take a first pass through the string, counting up length and the total | |
* number of strands we encounter as well as building a flat array of the | |
* strings (to we only have to do the indirect calls once). */ | |
@@ -1667,6 +1672,10 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec | |
piece = MVM_repr_get_str(tc, item); | |
} | |
+ if (all_strands_of_same_type) | |
+ all_strands_of_same_type = piece->body.storage_type == MVM_STRING_STRAND && | |
+ strand_type == piece->body.storage.strands->blob_string->body.storage_type; | |
+ | |
/* If it wasn't the first piece, add separator here. */ | |
if (num_pieces) { | |
total_strands += sstrands; | |
@@ -1695,11 +1704,22 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec | |
/* If we just collect all the things as strands, are we within bounds, and | |
* will be come out ahead? */ | |
- if (total_strands < MVM_STRING_MAX_STRANDS && 16 <= total_graphs / total_strands) { | |
- /* XXX TODO: Implement this, conditionalize branch thing below. */ | |
+ if (total_strands < MVM_STRING_MAX_STRANDS && all_strands_of_same_type) { | |
+ size_t offset = 0; | |
+ result->body.storage_type = MVM_STRING_STRAND; | |
+ result->body.storage.strands = allocate_strands(tc, total_strands); | |
+ result->body.num_strands = total_strands; | |
+ for (i = 0; i < num_pieces; i++) { | |
+ MVMString *piece = pieces[i]; | |
+ if (0 < i) { | |
+ copy_strands(tc, separator, 0, result, offset, separator->body.num_strands); | |
+ offset += separator->body.num_strands; | |
+ } | |
+ copy_strands(tc, piece, 0, result, offset, piece->body.num_strands); | |
+ offset += piece->body.num_strands; | |
+ } | |
} | |
- /*else {*/ | |
- if (1) { | |
+ else { | |
/* We'll produce a single, flat string. */ | |
MVMint64 position = 0; | |
MVMGraphemeIter gi; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment