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

ruby-changes:56837

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Tue, 6 Aug 2019 20:59:47 +0900 (JST)
Subject: [ruby-changes:56837] 卜部昌平: b5146e375a (master): leafify opt_plus

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

From b5146e375aca25a15ec46978711cde28e5f761d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Tue, 6 Aug 2019 12:56:18 +0900
Subject: leafify opt_plus

Inspired by 346aa557b31fe96760e505d30da26eb7a846bac9

Closes: https://github.com/ruby/ruby/pull/2321

diff --git a/insns.def b/insns.def
index 40855d6..6cfb3b1 100644
--- a/insns.def
+++ b/insns.def
@@ -1080,9 +1080,6 @@ opt_plus https://github.com/ruby/ruby/blob/trunk/insns.def#L1080
 (CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
-/* Array + anything can be handled inside of opt_plus, and that
- * anything is converted into array using #to_ary. */
-// attr bool leaf = false; /* has rb_to_array_type() */
 {
     val = vm_opt_plus(recv, obj);
 
diff --git a/internal.h b/internal.h
index d391597..bd7162e 100644
--- a/internal.h
+++ b/internal.h
@@ -2124,6 +2124,7 @@ char *rb_str_to_cstr(VALUE str); https://github.com/ruby/ruby/blob/trunk/internal.h#L2124
 VALUE rb_str_eql(VALUE str1, VALUE str2);
 VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
 const char *ruby_escaped_char(int c);
+VALUE rb_str_opt_plus(VALUE, VALUE);
 
 /* expect tail call optimization */
 static inline VALUE
diff --git a/string.c b/string.c
index 6cef5ab..2890f46 100644
--- a/string.c
+++ b/string.c
@@ -1952,6 +1952,37 @@ rb_str_plus(VALUE str1, VALUE str2) https://github.com/ruby/ruby/blob/trunk/string.c#L1952
     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
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index e68ded7..d7aa5ce 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3848,9 +3848,10 @@ vm_opt_plus(VALUE recv, VALUE obj) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3848
     else if (RBASIC_CLASS(recv) == rb_cString &&
 	     RBASIC_CLASS(obj) == rb_cString &&
 	     BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
-	return rb_str_plus(recv, obj);
+	return rb_str_opt_plus(recv, obj);
     }
     else if (RBASIC_CLASS(recv) == rb_cArray &&
+             RBASIC_CLASS(obj) == rb_cArray &&
 	     BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
 	return rb_ary_plus(recv, obj);
     }
-- 
cgit v0.10.2


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

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