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

calc_lineno(): add assertions

This function has a lot of assumptions.  Should make them sure.
This commit is contained in:
卜部昌平 2019-07-31 23:15:56 +09:00
parent 5d33f78716
commit 19d3c80e81
2 changed files with 29 additions and 12 deletions

2
vm.c
View file

@ -1343,7 +1343,7 @@ rb_source_location(int *pline)
const rb_execution_context_t *ec = GET_EC();
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(ec, ec->cfp);
if (cfp && cfp->iseq) {
if (cfp && VM_FRAME_RUBYFRAME_P(cfp)) {
if (pline) *pline = rb_vm_get_sourceline(cfp);
return rb_iseq_path(cfp->iseq);
}

View file

@ -32,19 +32,36 @@ id2str(ID id)
inline static int
calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
{
size_t pos = (size_t)(pc - iseq->body->iseq_encoded);
if (LIKELY(pos)) {
/* use pos-1 because PC points next instruction at the beginning of instruction */
pos--;
VM_ASSERT(iseq);
VM_ASSERT(iseq->body);
VM_ASSERT(iseq->body->iseq_encoded);
VM_ASSERT(iseq->body->iseq_size);
if (! pc) {
/* This can happen during VM bootup. */
VM_ASSERT(iseq->body->type == ISEQ_TYPE_TOP);
VM_ASSERT(! iseq->body->local_table);
VM_ASSERT(! iseq->body->local_table_size);
return 0;
}
#if VMDEBUG && defined(HAVE_BUILTIN___BUILTIN_TRAP)
else {
/* SDR() is not possible; that causes infinite loop. */
rb_print_backtrace();
__builtin_trap();
}
ptrdiff_t n = pc - iseq->body->iseq_encoded;
VM_ASSERT(n <= iseq->body->iseq_size);
VM_ASSERT(n >= 0);
ASSUME(n >= 0);
size_t pos = n; /* no overflow */
if (LIKELY(pos)) {
/* use pos-1 because PC points next instruction at the beginning of instruction */
pos--;
}
#if VMDEBUG && defined(HAVE_BUILTIN___BUILTIN_TRAP)
else {
/* SDR() is not possible; that causes infinite loop. */
rb_print_backtrace();
__builtin_trap();
}
#endif
return rb_iseq_line_no(iseq, pos);
return rb_iseq_line_no(iseq, pos);
}
}
int
@ -1296,7 +1313,7 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
const rb_callable_method_entry_t *cme;
for (i=0; i<limit && cfp != end_cfp;) {
if (cfp->iseq && cfp->pc) {
if (VM_FRAME_RUBYFRAME_P(cfp)) {
if (start > 0) {
start--;
continue;