зеркало из https://github.com/github/ruby.git
Stop allocating unused backref strings at `defined?`
This commit is contained in:
Родитель
df5ae0a550
Коммит
913e01e80e
|
@ -23,5 +23,6 @@ void rb_backref_set_string(VALUE string, long pos, long len);
|
|||
void rb_match_unbusy(VALUE);
|
||||
int rb_match_count(VALUE match);
|
||||
VALUE rb_reg_new_ary(VALUE ary, int options);
|
||||
VALUE rb_reg_last_defined(VALUE match);
|
||||
|
||||
#endif /* INTERNAL_RE_H */
|
||||
|
|
28
re.c
28
re.c
|
@ -1935,21 +1935,37 @@ rb_reg_match_post(VALUE match)
|
|||
return str;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_reg_match_last(VALUE match)
|
||||
static int
|
||||
match_last_index(VALUE match)
|
||||
{
|
||||
int i;
|
||||
struct re_registers *regs;
|
||||
|
||||
if (NIL_P(match)) return Qnil;
|
||||
if (NIL_P(match)) return -1;
|
||||
match_check(match);
|
||||
regs = RMATCH_REGS(match);
|
||||
if (BEG(0) == -1) return Qnil;
|
||||
if (BEG(0) == -1) return -1;
|
||||
|
||||
for (i=regs->num_regs-1; BEG(i) == -1 && i > 0; i--)
|
||||
;
|
||||
if (i == 0) return Qnil;
|
||||
return rb_reg_nth_match(i, match);
|
||||
return i;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_reg_match_last(VALUE match)
|
||||
{
|
||||
int i = match_last_index(match);
|
||||
if (i <= 0) return Qnil;
|
||||
struct re_registers *regs = RMATCH_REGS(match);
|
||||
return rb_str_subseq(RMATCH(match)->str, BEG(i), END(i) - BEG(i));
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_reg_last_defined(VALUE match)
|
||||
{
|
||||
int i = match_last_index(match);
|
||||
if (i < 0) return Qnil;
|
||||
return RBOOL(i);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
|
@ -672,6 +672,30 @@ vm_getspecial(const rb_execution_context_t *ec, const VALUE *lep, rb_num_t key,
|
|||
return val;
|
||||
}
|
||||
|
||||
static inline VALUE
|
||||
vm_backref_defined(const rb_execution_context_t *ec, const VALUE *lep, rb_num_t type)
|
||||
{
|
||||
VALUE backref = lep_svar_get(ec, lep, VM_SVAR_BACKREF);
|
||||
int nth = 0;
|
||||
|
||||
if (type & 0x01) {
|
||||
switch (type >> 1) {
|
||||
case '&':
|
||||
case '`':
|
||||
case '\'':
|
||||
break;
|
||||
case '+':
|
||||
return rb_reg_last_defined(backref);
|
||||
default:
|
||||
rb_bug("unexpected back-ref");
|
||||
}
|
||||
}
|
||||
else {
|
||||
nth = (int)(type >> 1);
|
||||
}
|
||||
return rb_reg_nth_defined(nth, backref);
|
||||
}
|
||||
|
||||
PUREFUNC(static rb_callable_method_entry_t *check_method_entry(VALUE obj, int can_be_svar));
|
||||
static rb_callable_method_entry_t *
|
||||
check_method_entry(VALUE obj, int can_be_svar)
|
||||
|
@ -5064,10 +5088,8 @@ vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_
|
|||
}
|
||||
}
|
||||
break;
|
||||
case DEFINED_REF:{
|
||||
return vm_getspecial(ec, GET_LEP(), Qfalse, FIX2INT(obj)) != Qnil;
|
||||
break;
|
||||
}
|
||||
case DEFINED_REF:
|
||||
return RTEST(vm_backref_defined(ec, GET_LEP(), FIX2INT(obj)));
|
||||
default:
|
||||
rb_bug("unimplemented defined? type (VM)");
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче