Revision
1947
Author
lsansonetti@apple.com
Date
2009-06-27 13:36:06 -0700 (Sat, 27 Jun 2009)

Log Message

Thread#raise: added

Modified Paths

Diff

Modified: MacRuby/branches/experimental/eval.c (1946 => 1947)


--- MacRuby/branches/experimental/eval.c	2009-06-27 06:39:27 UTC (rev 1946)
+++ MacRuby/branches/experimental/eval.c	2009-06-27 20:36:06 UTC (rev 1947)
@@ -350,8 +350,6 @@
  *     raise ArgumentError, "No parameters", caller
  */
 
-VALUE rb_make_exception(int, VALUE *);
-
 static VALUE
 rb_f_raise(VALUE klass, SEL sel, int argc, VALUE *argv)
 {

Modified: MacRuby/branches/experimental/include/ruby/intern.h (1946 => 1947)


--- MacRuby/branches/experimental/include/ruby/intern.h	2009-06-27 06:39:27 UTC (rev 1946)
+++ MacRuby/branches/experimental/include/ruby/intern.h	2009-06-27 20:36:06 UTC (rev 1947)
@@ -204,6 +204,7 @@
 NORETURN(void rb_error_frozen(const char*));
 void rb_check_frozen(VALUE);
 /* eval.c */
+VALUE rb_make_exception(int, VALUE *);
 int rb_sourceline(void);
 const char *rb_sourcefile(void);
 

Modified: MacRuby/branches/experimental/thread.c (1946 => 1947)


--- MacRuby/branches/experimental/thread.c	2009-06-27 06:39:27 UTC (rev 1946)
+++ MacRuby/branches/experimental/thread.c	2009-06-27 20:36:06 UTC (rev 1947)
@@ -242,9 +242,19 @@
  */
 
 static VALUE
-thread_raise_m(int argc, VALUE *argv, VALUE self)
+thread_raise_m(VALUE self, SEL sel, int argc, VALUE *argv)
 {
-    // TODO
+    VALUE exc = rb_make_exception(argc, argv);
+
+    rb_vm_thread_t *t = GetThreadPtr(self);
+
+    if (t->thread == pthread_self()) {
+	rb_exc_raise(exc);
+    }
+    else if (t->status != THREAD_DEAD) {
+	rb_vm_thread_raise(t, exc);
+    }
+
     return Qnil;
 }
 
@@ -1358,7 +1368,7 @@
     rb_objc_define_method(*(VALUE *)rb_cThread, "abort_on_exception=", rb_thread_s_abort_exc_set, 1);
 
     rb_objc_define_method(rb_cThread, "initialize", thread_initialize, -1);
-    rb_define_method(rb_cThread, "raise", thread_raise_m, -1);
+    rb_objc_define_method(rb_cThread, "raise", thread_raise_m, -1);
     rb_objc_define_method(rb_cThread, "join", thread_join_m, -1);
     rb_objc_define_method(rb_cThread, "value", thread_value, 0);
     rb_objc_define_method(rb_cThread, "kill", rb_thread_kill, 0);

Modified: MacRuby/branches/experimental/vm.cpp (1946 => 1947)


--- MacRuby/branches/experimental/vm.cpp	2009-06-27 06:39:27 UTC (rev 1946)
+++ MacRuby/branches/experimental/vm.cpp	2009-06-27 20:36:06 UTC (rev 1947)
@@ -4604,6 +4604,17 @@
 
 extern "C"
 void
+rb_vm_thread_raise(rb_vm_thread_t *t, VALUE exc)
+{
+    // XXX we should lock here
+    RoxorVM *vm = (RoxorVM *)t->vm;
+    vm->push_current_exception(exc);
+
+    rb_vm_thread_cancel(t);
+}
+
+extern "C"
+void
 rb_thread_sleep(int sec)
 {
     struct timeval time;

Modified: MacRuby/branches/experimental/vm.h (1946 => 1947)


--- MacRuby/branches/experimental/vm.h	2009-06-27 06:39:27 UTC (rev 1946)
+++ MacRuby/branches/experimental/vm.h	2009-06-27 20:36:06 UTC (rev 1947)
@@ -359,6 +359,7 @@
 VALUE rb_vm_thread_locals(VALUE thread, bool create_storage);
 void rb_vm_thread_wakeup(rb_vm_thread_t *t);
 void rb_vm_thread_cancel(rb_vm_thread_t *t);
+void rb_vm_thread_raise(rb_vm_thread_t *t, VALUE exc);
 
 bool rb_vm_abort_on_exception(void);
 void rb_vm_set_abort_on_exception(bool flag);