summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-18 16:13:53 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-18 16:13:53 +0000
commitf79eaf199cc5c5ff1cc5c7774cab13af2a05a18e (patch)
tree089025c87c1ba5668700fce1429d5303e237d106
parent478cdf49d7fcca58de301637dba598d2da69ef3e (diff)
merge revision(s) 51292,51439,51440: [Backport #11404] [Backport #11481]
* load.c (rb_load_internal0): do not raise any exceptions but return the result tag state. * load.c (rb_load_protect): reduce nested EXEC_TAGs. * load.c (rb_load_internal0): extra check before returning TAG_RAISE when a non-local transfer of control happens while loading and parsing a Ruby source file. [ruby-core:70169] [Bug #11404] * load.c (rb_load_internal0): stop separating exits at loading from exits from execution. TAG_FATAL is the only case that `errinfo` is a Fixnum, and should continue to exit by JUMP_TAG but not raising as an ordinary exception. [ruby-core:70169] [Bug #11404] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@52655 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog22
-rw-r--r--load.c39
-rw-r--r--test/ruby/test_require.rb29
-rw-r--r--version.h2
4 files changed, 77 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 676453311e..fd526e6e1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Thu Nov 19 01:06:07 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * load.c (rb_load_internal0): stop separating exits at loading
+ from exits from execution. TAG_FATAL is the only case that
+ `errinfo` is a Fixnum, and should continue to exit by JUMP_TAG
+ but not raising as an ordinary exception.
+ [ruby-core:70169] [Bug #11404]
+
+Thu Nov 19 01:06:07 2015 Alex Dowad <alexinbeijing@gmail.com>
+
+ * load.c (rb_load_internal0): extra check before returning
+ TAG_RAISE when a non-local transfer of control happens while
+ loading and parsing a Ruby source file.
+ [ruby-core:70169] [Bug #11404]
+
+Thu Nov 19 01:06:07 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * load.c (rb_load_internal0): do not raise any exceptions but
+ return the result tag state.
+
+ * load.c (rb_load_protect): reduce nested EXEC_TAGs.
+
Thu Nov 19 00:41:09 2015 NARUSE, Yui <naruse@ruby-lang.org>
* enc/euc_jp.c (mbc_case_fold): check given string is valid or not,
diff --git a/load.c b/load.c
index af3548c19a..bf5d9cf648 100644
--- a/load.c
+++ b/load.c
@@ -575,13 +575,12 @@ rb_provide(const char *feature)
NORETURN(static void load_failed(VALUE));
-static inline void
+static int
rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
{
int state;
volatile VALUE wrapper = th->top_wrapper;
volatile VALUE self = th->top_self;
- volatile int loaded = FALSE;
volatile int mild_compile_error;
#if !defined __GNUC__
rb_thread_t *volatile th0 = th;
@@ -608,7 +607,6 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
th->mild_compile_error++;
node = (NODE *)rb_load_file_str(fname);
- loaded = TRUE;
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
th->mild_compile_error--;
rb_iseq_eval(iseq);
@@ -623,44 +621,57 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
th->top_self = self;
th->top_wrapper = wrapper;
- if (!loaded && !FIXNUM_P(th->errinfo)) {
- /* an error on loading don't include INT2FIX(TAG_FATAL) see r35625 */
- rb_exc_raise(th->errinfo);
- }
if (state) {
- rb_vm_jump_tag_but_local_jump(state);
+ VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
+ if (NIL_P(exc)) return state;
+ th->errinfo = exc;
+ return TAG_RAISE;
}
if (!NIL_P(th->errinfo)) {
/* exception during load */
- rb_exc_raise(th->errinfo);
+ return TAG_RAISE;
}
+ return state;
}
static void
rb_load_internal(VALUE fname, int wrap)
{
- rb_load_internal0(GET_THREAD(), fname, wrap);
+ rb_thread_t *curr_th = GET_THREAD();
+ int state = rb_load_internal0(curr_th, fname, wrap);
+ if (state) {
+ if (state == TAG_RAISE) rb_exc_raise(curr_th->errinfo);
+ JUMP_TAG(state);
+ }
}
-void
-rb_load(VALUE fname, int wrap)
+static VALUE
+file_to_load(VALUE fname)
{
VALUE tmp = rb_find_file(FilePathValue(fname));
if (!tmp) load_failed(fname);
- rb_load_internal(tmp, wrap);
+ return tmp;
+}
+
+void
+rb_load(VALUE fname, int wrap)
+{
+ rb_load_internal(file_to_load(fname), wrap);
}
void
rb_load_protect(VALUE fname, int wrap, int *state)
{
int status;
+ volatile VALUE path = 0;
PUSH_TAG();
if ((status = EXEC_TAG()) == 0) {
- rb_load(fname, wrap);
+ path = file_to_load(fname);
}
POP_TAG();
+ if (!status) status = rb_load_internal0(GET_THREAD(), path, wrap);
if (state)
*state = status;
}
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index 33aea6082a..1b87246e4e 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -701,4 +701,33 @@ class TestRequire < Test::Unit::TestCase
}
rescue Errno::ENOENT
end unless /mswin|mingw/ =~ RUBY_PLATFORM
+
+ def test_throw_while_loading
+ Tempfile.create(%w'bug-11404 .rb') do |f|
+ f.puts 'sleep'
+ f.close
+
+ assert_separately(["-", f.path], <<-'end;')
+ path = ARGV[0]
+ class Error < RuntimeError
+ def exception(*)
+ begin
+ throw :blah
+ rescue UncaughtThrowError
+ end
+ self
+ end
+ end
+
+ assert_throw(:blah) do
+ x = Thread.current
+ y = Thread.start {
+ sleep 0.00001
+ x.raise Error.new
+ }
+ load path
+ end
+ end;
+ end
+ end
end
diff --git a/version.h b/version.h
index 8b9a9646fa..9c9a265f99 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.2.4"
#define RUBY_RELEASE_DATE "2015-11-19"
-#define RUBY_PATCHLEVEL 191
+#define RUBY_PATCHLEVEL 192
#define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 11