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:
parent
43b52ac0a5
commit
b5146e375a
4 changed files with 34 additions and 4 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
31
string.c
31
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue