зеркало из https://github.com/github/ruby.git
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:
Родитель
20cb8e8aea
Коммит
b004d3e830
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче