1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

leafify opt_plus

Inspired by 346aa557b3

Closes: https://github.com/ruby/ruby/pull/2321
This commit is contained in:
卜部昌平 2019-08-06 12:56:18 +09:00 committed by Takashi Kokubun
parent 43b52ac0a5
commit b5146e375a
No known key found for this signature in database
GPG key ID: 6FFC433B12EE23DD
4 changed files with 34 additions and 4 deletions

View file

@ -1080,9 +1080,6 @@ opt_plus
(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);

View file

@ -2124,6 +2124,7 @@ char *rb_str_to_cstr(VALUE str);
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

View file

@ -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

View file

@ -3848,9 +3848,10 @@ vm_opt_plus(VALUE recv, VALUE obj)
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);
}