summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-08-06 12:56:18 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-06 20:59:19 +0900
commitb5146e375aca25a15ec46978711cde28e5f761d6 (patch)
treebd85c41b2a077e95476ec35a93d5923706be5559 /string.c
parent43b52ac0a52807c415e9d24d25954f5055567c5e (diff)
leafify opt_plus
Inspired by 346aa557b31fe96760e505d30da26eb7a846bac9 Closes: https://github.com/ruby/ruby/pull/2321
Diffstat (limited to 'string.c')
-rw-r--r--string.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/string.c b/string.c
index 6cef5ab157..2890f46e24 100644
--- a/string.c
+++ b/string.c
@@ -1952,6 +1952,37 @@ rb_str_plus(VALUE str1, VALUE str2)
return str3;
}
+/* A variant of rb_str_plus that does not raise but return Qundef instead. */
+MJIT_FUNC_EXPORTED VALUE
+rb_str_opt_plus(VALUE str1, VALUE str2)
+{
+ assert(RBASIC_CLASS(str1) == rb_cString);
+ assert(RBASIC_CLASS(str2) == rb_cString);
+ long len1, len2;
+ MAYBE_UNUSED(char) *ptr1, *ptr2;
+ RSTRING_GETMEM(str1, ptr1, len1);
+ RSTRING_GETMEM(str2, ptr2, len2);
+ int enc1 = rb_enc_get_index(str1);
+ int enc2 = rb_enc_get_index(str2);
+
+ if (enc1 < 0) {
+ return Qundef;
+ }
+ else if (enc2 < 0) {
+ return Qundef;
+ }
+ else if (enc1 != enc2) {
+ return Qundef;
+ }
+ else if (len1 > LONG_MAX - len2) {
+ return Qundef;
+ }
+ else {
+ return rb_str_plus(str1, str2);
+ }
+
+}
+
/*
* call-seq:
* str * integer -> new_str