summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2019-08-08 17:53:36 +0900
committerKoichi Sasada <ko1@atdot.net>2019-08-08 17:56:04 +0900
commitb004d3e8300ba803d4a499148fa4fc6a690149e6 (patch)
treef382c3c32ba64c95b53aaf45b7c2f296ae3d6a06
parent20cb8e8aeab916d659c0359a35687bb8df1f31a6 (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.h2
-rw-r--r--load.c43
-rw-r--r--test/ruby/test_settracefunc.rb13
-rw-r--r--vm.c2
4 files changed, 24 insertions, 36 deletions
diff --git a/eval_intern.h b/eval_intern.h
index db28aa1..7c90972 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);
diff --git a/load.c b/load.c
index 56dab41..8f40430 100644
--- a/load.c
+++ b/load.c
@@ -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 1f99d3e..7d7b672 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
diff --git a/vm.c b/vm.c
index 8d5d856..3fa0b16 100644
--- a/vm.c
+++ b/vm.c
@@ -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)