[前][次][番号順一覧][スレッド一覧]

ruby-changes:72688

From: Kevin <ko1@a...>
Date: Tue, 26 Jul 2022 16:04:05 +0900 (JST)
Subject: [ruby-changes:72688] 9a8f6e392f (master): Cheaply derive code range for String#b return value

https://git.ruby-lang.org/ruby.git/commit/?id=9a8f6e392f

From 9a8f6e392fbd9c145566ae18fa2128ef96369430 Mon Sep 17 00:00:00 2001
From: Kevin Menard <kevin@n...>
Date: Mon, 25 Jul 2022 21:04:03 -0400
Subject: Cheaply derive code range for String#b return value

The result of String#b is a string with an ASCII_8BIT/BINARY encoding. That encoding is ASCII-compatible and has no byte sequences that are invalid for the encoding. If we know the receiver's code range, we can derive the resulting string's code range without needing to perform a full code range scan.
---
 string.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/string.c b/string.c
index f5e089aa21..d9b5278eb6 100644
--- a/string.c
+++ b/string.c
@@ -10779,7 +10779,23 @@ rb_str_b(VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L10779
         str2 = str_alloc_embed(rb_cString, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
     }
     str_replace_shared_without_enc(str2, str);
-    ENC_CODERANGE_CLEAR(str2);
+
+    // BINARY strings can never be broken; they're either 7-bit ASCII or VALID.
+    // If we know the receiver's code range then we know the result's code range.
+    int cr = ENC_CODERANGE(str);
+    switch (cr) {
+        case ENC_CODERANGE_7BIT:
+            ENC_CODERANGE_SET(str2, ENC_CODERANGE_7BIT);
+            break;
+        case ENC_CODERANGE_BROKEN:
+        case ENC_CODERANGE_VALID:
+            ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
+            break;
+        default:
+            ENC_CODERANGE_CLEAR(str2);
+            break;
+    }
+
     return str2;
 }
 
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]