diff options
author | Koichi Sasada <[email protected]> | 2019-08-08 17:53:36 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2019-08-08 17:56:04 +0900 |
commit | b004d3e8300ba803d4a499148fa4fc6a690149e6 (patch) | |
tree | f382c3c32ba64c95b53aaf45b7c2f296ae3d6a06 | |
parent | 20cb8e8aeab916d659c0359a35687bb8df1f31a6 (diff) |
solve "duplicate :raise event" [Bug #15877]
Without this patch, "raise" event invoked twice when raise an
exception in "load"ed script.
This patch by danielwaterworth (Daniel Waterworth).
[Bug #15877]
-rw-r--r-- | eval_intern.h | 2 | ||||
-rw-r--r-- | load.c | 43 | ||||
-rw-r--r-- | test/ruby/test_settracefunc.rb | 13 | ||||
-rw-r--r-- | vm.c | 2 |
4 files changed, 24 insertions, 36 deletions
diff --git a/eval_intern.h b/eval_intern.h index db28aa1598..7c90972103 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -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); @@ -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; @@ -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; } @@ -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': @@ -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; } } } diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 1f99d3ee88..7d7b672fd8 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -1671,6 +1671,19 @@ class TestSetTraceFunc < Test::Unit::TestCase 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 @@ -1487,7 +1487,6 @@ 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) { @@ -1495,7 +1494,6 @@ rb_vm_jump_tag_but_local_jump(int state) 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) |