mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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]
This commit is contained in:
		
							parent
							
								
									20cb8e8aea
								
							
						
					
					
						commit
						b004d3e830
					
				
					 4 changed files with 24 additions and 36 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										43
									
								
								load.c
									
										
									
									
									
								
							
							
						
						
									
										43
									
								
								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;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue