Skip to content

Commit

Permalink
solve "duplicate :raise event" [Bug #15877]
Browse files Browse the repository at this point in the history
Without this patch, "raise" event invoked twice when raise an
exception in "load"ed script.
This patch by  danielwaterworth (Daniel Waterworth).
[Bug #15877]
  • Loading branch information
ko1 committed Aug 8, 2019
1 parent 20cb8e8 commit b004d3e
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 36 deletions.
2 changes: 0 additions & 2 deletions eval_intern.h
Expand Up @@ -277,9 +277,7 @@ NORETURN(void rb_print_undef(VALUE, ID, rb_method_visibility_t));
NORETURN(void rb_print_undef_str(VALUE, VALUE));
NORETURN(void rb_print_inaccessible(VALUE, ID, rb_method_visibility_t));
NORETURN(void rb_vm_localjump_error(const char *,VALUE, int));
#if 0
NORETURN(void rb_vm_jump_tag_but_local_jump(int));
#endif

VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val);
rb_cref_t *rb_vm_cref(void);
Expand Down
43 changes: 11 additions & 32 deletions load.c
Expand Up @@ -568,7 +568,7 @@ rb_provide(const char *feature)

NORETURN(static void load_failed(VALUE));

static int
static inline void
rb_load_internal0(rb_execution_context_t *ec, VALUE fname, int wrap)
{
enum ruby_tag_type state;
Expand Down Expand Up @@ -621,59 +621,40 @@ rb_load_internal0(rb_execution_context_t *ec, VALUE fname, int wrap)
th->top_wrapper = wrapper;

if (state) {
/* usually state == TAG_RAISE only, except for
* rb_iseq_load_iseq case */
VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
if (NIL_P(exc)) return state;
th->ec->errinfo = exc;
return TAG_RAISE;
rb_vm_jump_tag_but_local_jump(state);
}

if (!NIL_P(th->ec->errinfo)) {
/* exception during load */
return TAG_RAISE;
rb_exc_raise(th->ec->errinfo);
}
return state;
}

static void
rb_load_internal(VALUE fname, int wrap)
{
rb_execution_context_t *ec = GET_EC();
int state = rb_load_internal0(ec, fname, wrap);
if (state) {
if (state == TAG_RAISE) rb_exc_raise(ec->errinfo);
EC_JUMP_TAG(ec, state);
}
}

static VALUE
file_to_load(VALUE fname)
{
VALUE tmp = rb_find_file(FilePathValue(fname));
if (!tmp) load_failed(fname);
return tmp;
rb_load_internal0(ec, fname, wrap);
}

void
rb_load(VALUE fname, int wrap)
{
rb_load_internal(file_to_load(fname), wrap);
VALUE tmp = rb_find_file(FilePathValue(fname));
if (!tmp) load_failed(fname);
rb_load_internal(tmp, wrap);
}

void
rb_load_protect(VALUE fname, int wrap, int *pstate)
{
enum ruby_tag_type state;
volatile VALUE path = 0;

EC_PUSH_TAG(GET_EC());
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
path = file_to_load(fname);
rb_load(fname, wrap);
}
EC_POP_TAG();

if (state == TAG_NONE) state = rb_load_internal0(GET_EC(), path, wrap);
if (state != TAG_NONE) *pstate = state;
}

Expand Down Expand Up @@ -1025,7 +1006,7 @@ rb_require_internal(VALUE fname, int safe)
else {
switch (found) {
case 'r':
state = rb_load_internal0(ec, path, 0);
rb_load_internal(path, 0);
break;

case 's':
Expand All @@ -1034,10 +1015,8 @@ rb_require_internal(VALUE fname, int safe)
rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
break;
}
if (!state) {
rb_provide_feature(path);
result = TAG_RETURN;
}
rb_provide_feature(path);
result = TAG_RETURN;
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions test/ruby/test_settracefunc.rb
Expand Up @@ -1671,6 +1671,19 @@ def tp_return_value mid
ary
end

def test_single_raise_inside_load
events = []
tmpdir = Dir.mktmpdir
path = "#{tmpdir}/hola.rb"
File.open(path, "w") { |f| f.write("raise") }
TracePoint.new(:raise){|tp| next if !target_thread?; events << [tp.event]}.enable{
load path rescue nil
}
assert_equal [[:raise]], events
ensure
FileUtils.rmtree(tmpdir)
end

def f_raise
raise
rescue
Expand Down
2 changes: 0 additions & 2 deletions vm.c
Expand Up @@ -1487,15 +1487,13 @@ rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
return make_localjump_error(mesg, val, state);
}

#if 0
void
rb_vm_jump_tag_but_local_jump(int state)
{
VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
if (!NIL_P(exc)) rb_exc_raise(exc);
EC_JUMP_TAG(GET_EC(), state);
}
#endif

static rb_control_frame_t *
next_not_local_frame(rb_control_frame_t *cfp)
Expand Down

0 comments on commit b004d3e

Please sign in to comment.