From aa2a428cfb3f4273f51358eb4e7fab235c7d36c2 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 26 Sep 2022 11:39:36 -0400 Subject: Refactor str_substr and str_subseq This commit extracts common code between str_substr and rb_str_subseq into a function called str_subseq. This commit also applies optimizations in commit 2e88bca to rb_str_subseq. --- string.c | 58 +++++++++++++++++++++------------------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) (limited to 'string.c') diff --git a/string.c b/string.c index 1e7b16fbba..b9c567cbe2 100644 --- a/string.c +++ b/string.c @@ -2797,26 +2797,32 @@ rb_str_sublen(VALUE str, long pos) } } -VALUE -rb_str_subseq(VALUE str, long beg, long len) +static VALUE +str_subseq(VALUE str, long beg, long len) { VALUE str2; if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) && - SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) { - long olen; - str2 = rb_str_new_shared(rb_str_new_frozen_String(str)); + SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) { + str2 = rb_str_new_shared(str); RSTRING(str2)->as.heap.ptr += beg; - olen = RSTRING(str2)->as.heap.len; - if (olen > len) RSTRING(str2)->as.heap.len = len; + if (RSTRING(str2)->as.heap.len > len) { + RSTRING(str2)->as.heap.len = len; + } } else { - str2 = rb_str_new(RSTRING_PTR(str)+beg, len); + str2 = rb_str_new(RSTRING_PTR(str) + beg, len); RB_GC_GUARD(str); } - rb_enc_cr_str_copy_for_substr(str2, str); + return str2; +} +VALUE +rb_str_subseq(VALUE str, long beg, long len) +{ + VALUE str2 = str_subseq(str, beg, len); + rb_enc_cr_str_copy_for_substr(str2, str); return str2; } @@ -2916,25 +2922,15 @@ rb_str_substr(VALUE str, long beg, long len) static VALUE str_substr(VALUE str, long beg, long len, int empty) { - VALUE str2; char *p = rb_str_subpos(str, beg, &len); if (!p) return Qnil; - if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) && - SHARABLE_SUBSTRING_P(p, len, RSTRING_END(str))) { - long ofs = p - RSTRING_PTR(str); - str2 = str_new_shared(rb_cString, str); - RSTRING(str2)->as.heap.ptr += ofs; - RSTRING(str2)->as.heap.len = len; - ENC_CODERANGE_CLEAR(str2); - } - else { - if (!len && !empty) return Qnil; - str2 = rb_str_new(p, len); - RB_GC_GUARD(str); - } - rb_enc_cr_str_copy_for_substr(str2, str); + if (!len && !empty) return Qnil; + beg = p - RSTRING_PTR(str); + + VALUE str2 = str_subseq(str, beg, len); + rb_enc_cr_str_copy_for_substr(str2, str); return str2; } @@ -6141,9 +6137,7 @@ rb_str_setbyte(VALUE str, VALUE index, VALUE value) static VALUE str_byte_substr(VALUE str, long beg, long len, int empty) { - char *p, *s = RSTRING_PTR(str); long n = RSTRING_LEN(str); - VALUE str2; if (beg > n || len < 0) return Qnil; if (beg < 0) { @@ -6155,19 +6149,9 @@ str_byte_substr(VALUE str, long beg, long len, int empty) if (len <= 0) { if (!empty) return Qnil; len = 0; - p = 0; } - else - p = s + beg; - if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) && SHARABLE_SUBSTRING_P(beg, len, n)) { - str2 = str_new_shared(rb_cString, str); - RSTRING(str2)->as.heap.ptr += beg; - RSTRING(str2)->as.heap.len = len; - } - else { - str2 = rb_str_new(p, len); - } + VALUE str2 = str_subseq(str, beg, len); str_enc_copy(str2, str); -- cgit v1.2.1