From 635ec42c43f281bea30bb28e74da3a3dfd4dd912 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
Date: Tue, 28 May 2019 09:20:56 +0200
Subject: [PATCH] Single `:raise` tracepoint event when exception inside `load`
 happens


diff --git a/eval_intern.h b/eval_intern.h
index f4a48d8171..750d3de6a0 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -294,9 +294,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 576464fb68..3acb769f34 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 61c9dd0d7d..795c3fe509 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -1672,6 +1672,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
diff --git a/vm.c b/vm.c
index 1bc1ed757f..cae33c37d9 100644
--- a/vm.c
+++ b/vm.c
@@ -1488,7 +1488,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)
 {
@@ -1496,7 +1495,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)
-- 
2.21.0

