summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c154
1 files changed, 84 insertions, 70 deletions
diff --git a/eval.c b/eval.c
index d19f41f271..e597ea00ae 100644
--- a/eval.c
+++ b/eval.c
@@ -3359,7 +3359,7 @@ rb_yield_0(val, self, klass, acheck)
rb_gc_force_recycle((VALUE)vars);
vars = vars->next;
}
- if (ruby_dyna_vars->id == 0) {
+ if (ruby_dyna_vars && ruby_dyna_vars->id == 0) {
rb_gc_force_recycle((VALUE)ruby_dyna_vars);
}
}
@@ -3720,7 +3720,7 @@ rb_f_missing(argc, argv, obj)
if (argc == 0) rb_raise(rb_eArgError, "no id given");
- id = FIX2INT(argv[0]);
+ id = NUM2INT(argv[0]);
argc--; argv++;
switch (TYPE(obj)) {
@@ -5789,7 +5789,7 @@ proc_arity(proc)
int n;
Data_Get_Struct(proc, struct BLOCK, data);
- if (data->var == 0) return FIX2INT(-1);
+ if (data->var == 0) return INT2FIX(-1);
switch (nd_type(data->var)) {
default:
return INT2FIX(-2);
@@ -5986,7 +5986,7 @@ method_arity(method)
body = body->nd_head;
if (!body) return INT2FIX(0);
n = body->nd_cnt;
- if (body->nd_rest) n = -n-1;
+ if (body->nd_rest >= 0) n = -n-1;
return INT2FIX(n);
}
}
@@ -6261,13 +6261,30 @@ rb_thread_check(data)
return (thread_t)RDATA(data)->data;
}
+static int th_raise_argc;
+static VALUE th_raise_argv[2];
+static char *th_raise_file;
+static int th_raise_line;
+static VALUE th_cmd;
+static int th_sig;
+static char *th_signm;
+
+#define RESTORE_NORMAL 1
+#define RESTORE_FATAL 2
+#define RESTORE_INTERRUPT 3
+#define RESTORE_TRAP 4
+#define RESTORE_RAISE 5
+#define RESTORE_SIGNAL 6
+
static void
rb_thread_save_context(th)
thread_t th;
{
VALUE v;
- int len = stack_length();
+ int len;
+
+ len = stack_length();
th->stk_len = 0;
th->stk_pos = (rb_gc_stack_start<(VALUE*)&v)?rb_gc_stack_start
:rb_gc_stack_start - len;
@@ -6299,6 +6316,41 @@ rb_thread_save_context(th)
th->line = ruby_sourceline;
}
+static int
+thread_switch(n)
+ int n;
+{
+ switch (n) {
+ case 0:
+ return 0;
+ case RESTORE_FATAL:
+ JUMP_TAG(TAG_FATAL);
+ break;
+ case RESTORE_INTERRUPT:
+ rb_interrupt();
+ break;
+ case RESTORE_TRAP:
+ rb_trap_eval(th_cmd, th_sig);
+ errno = EINTR;
+ break;
+ case RESTORE_RAISE:
+ ruby_frame->last_func = 0;
+ ruby_sourcefile = th_raise_file;
+ ruby_sourceline = th_raise_line;
+ rb_f_raise(th_raise_argc, th_raise_argv);
+ break;
+ case RESTORE_SIGNAL:
+ rb_raise(rb_eSignal, "SIG%s", th_signm);
+ break;
+ case RESTORE_NORMAL:
+ default:
+ return 1;
+ }
+}
+
+#define THREAD_SAVE_CONTEXT(th) \
+ (rb_thread_save_context(th),thread_switch(setjmp((th)->context)))
+
static void rb_thread_restore_context _((thread_t,int));
static void
@@ -6312,21 +6364,6 @@ stack_extend(th, exit)
rb_thread_restore_context(th, exit);
}
-static int th_raise_argc;
-static VALUE th_raise_argv[2];
-static char *th_raise_file;
-static int th_raise_line;
-static VALUE th_cmd;
-static int th_sig;
-static char *th_signm;
-
-#define RESTORE_NORMAL 0
-#define RESTORE_FATAL 1
-#define RESTORE_INTERRUPT 2
-#define RESTORE_TRAP 3
-#define RESTORE_RAISE 4
-#define RESTORE_SIGNAL 5
-
static void
rb_thread_restore_context(th, exit)
thread_t th;
@@ -6373,35 +6410,7 @@ rb_thread_restore_context(th, exit)
rb_lastline_set(tmp->last_line);
rb_backref_set(tmp->last_match);
- switch (ex) {
- case RESTORE_FATAL:
- JUMP_TAG(TAG_FATAL);
- break;
-
- case RESTORE_INTERRUPT:
- rb_interrupt();
- break;
-
- case RESTORE_TRAP:
- rb_trap_eval(th_cmd, th_sig);
- errno = EINTR;
- break;
-
- case RESTORE_SIGNAL:
- rb_raise(rb_eSignal, "SIG%s", th_signm);
- break;
-
- case RESTORE_RAISE:
- ruby_frame->last_func = 0;
- ruby_sourcefile = th_raise_file;
- ruby_sourceline = th_raise_line;
- rb_f_raise(th_raise_argc, th_raise_argv);
- break;
-
- case RESTORE_NORMAL:
- default:
- longjmp(tmp->context, 1);
- }
+ longjmp(tmp->context, ex);
}
static void
@@ -6639,8 +6648,7 @@ rb_thread_schedule()
/* context switch */
if (curr == curr_thread) {
- rb_thread_save_context(curr);
- if (setjmp(curr->context)) {
+ if (THREAD_SAVE_CONTEXT(curr)) {
return;
}
}
@@ -7209,15 +7217,13 @@ rb_thread_create_0(fn, arg, klass)
scope_dup(ruby_scope);
FL_SET(ruby_scope, SCOPE_SHARED);
- rb_thread_save_context(curr_thread);
- if (setjmp(curr_thread->context)) {
+ if (THREAD_SAVE_CONTEXT(curr_thread)) {
return thread;
}
PUSH_TAG(PROT_THREAD);
if ((state = EXEC_TAG()) == 0) {
- rb_thread_save_context(th);
- if (setjmp(th->context) == 0) {
+ if (THREAD_SAVE_CONTEXT(th) == 0) {
curr_thread = th;
th->result = (*fn)(arg, th);
}
@@ -7384,8 +7390,7 @@ rb_thread_interrupt()
if (curr_thread == main_thread) {
rb_interrupt();
}
- rb_thread_save_context(curr_thread);
- if (setjmp(curr_thread->context)) {
+ if (THREAD_SAVE_CONTEXT(curr_thread)) {
return;
}
curr_thread = main_thread;
@@ -7403,8 +7408,7 @@ rb_thread_signal_raise(sig)
rb_raise(rb_eSignal, "SIG%s", sig);
}
rb_thread_ready(main_thread);
- rb_thread_save_context(curr_thread);
- if (setjmp(curr_thread->context)) {
+ if (THREAD_SAVE_CONTEXT(curr_thread)) {
return;
}
th_signm = sig;
@@ -7417,6 +7421,7 @@ rb_thread_trap_eval(cmd, sig)
VALUE cmd;
int sig;
{
+#if 0
rb_thread_critical = 0;
if (!rb_thread_dead(curr_thread)) {
rb_thread_ready(curr_thread);
@@ -7424,14 +7429,26 @@ rb_thread_trap_eval(cmd, sig)
return;
}
rb_thread_ready(main_thread);
- rb_thread_save_context(curr_thread);
- if (setjmp(curr_thread->context)) {
+ if (THREAD_SAVE_CONTEXT(curr_thread)) {
return;
}
th_cmd = cmd;
th_sig = sig;
curr_thread = main_thread;
rb_thread_restore_context(curr_thread, RESTORE_TRAP);
+#else
+ rb_thread_critical = 0;
+ if (!rb_thread_dead(curr_thread)) {
+ if (THREAD_SAVE_CONTEXT(curr_thread)) {
+ return;
+ }
+ }
+ rb_thread_ready(main_thread);
+ th_cmd = cmd;
+ th_sig = sig;
+ curr_thread = main_thread;
+ rb_thread_restore_context(curr_thread, RESTORE_TRAP);
+#endif
}
static VALUE
@@ -7442,17 +7459,15 @@ rb_thread_raise(argc, argv, thread)
{
thread_t th = rb_thread_check(thread);
- if (rb_thread_dead(th)) return thread;
+ if (rb_thread_dead(th)) return Qnil;
if (curr_thread == th) {
rb_f_raise(argc, argv);
}
- if (th->safe < 4) {
+ if (ruby_safe_level > th->safe) {
rb_secure(4);
}
- if (curr_thread->status != THREAD_KILLED)
- rb_thread_save_context(curr_thread);
- if (setjmp(curr_thread->context)) {
+ if (THREAD_SAVE_CONTEXT(curr_thread)) {
return thread;
}
@@ -7613,8 +7628,7 @@ rb_callcc(self)
for (tag=prot_tag; tag; tag=tag->prev) {
scope_dup(tag->scope);
}
- rb_thread_save_context(th);
- if (setjmp(th->context)) {
+ if (THREAD_SAVE_CONTEXT(th)) {
return th->result;
}
else {
@@ -7793,7 +7807,7 @@ static VALUE
catch_i(tag)
ID tag;
{
- return rb_funcall(Qnil, rb_intern("catch"), 0, FIX2INT(tag));
+ return rb_funcall(Qnil, rb_intern("catch"), 0, INT2FIX(tag));
}
VALUE
@@ -7846,7 +7860,7 @@ rb_throw(tag, val)
VALUE argv[2];
ID t = rb_intern(tag);
- argv[0] = FIX2INT(t);
+ argv[0] = INT2FIX(t);
argv[1] = val;
rb_f_throw(2, argv);
}