<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>TODO</filename>
    </added>
    <added>
      <filename>flash/src/ruby/internals/RbVmTag.as</filename>
    </added>
    <added>
      <filename>research/exceptions.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -32,7 +32,7 @@
   protected function cc():void
   {
     dir_root = File.userDirectory.nativePath + &quot;/work/ruby/redsun&quot;;
-    ti.text = &quot;research/rubyconf.rb&quot;;
+    ti.text = &quot;research/exceptions.rb&quot;;
     read_file(ti.text);
     sp = new UIComponent();
     sp.y = 50;</diff>
      <filename>chromosphere/src/Chromosphere.mxml</filename>
    </modified>
    <modified>
      <diff>@@ -42,7 +42,18 @@ public class Error_c
 
   public function Init_Exception():void {
     rb_eException = rc.class_c.rb_define_class(&quot;Exception&quot;, rc.object_c.rb_cObject);
-    // exception methods
+
+    //rb_define_singleton_method(rb_eException, &quot;exception&quot;, rb_class_new_instance, -1);
+    //rb_define_method(rb_eException, &quot;exception&quot;, exc_exception, -1);
+    rc.class_c.rb_define_method(rb_eException, &quot;initialize&quot;, exc_initialize, -1);
+    /*
+    rb_define_method(rb_eException, &quot;==&quot;, exc_equal, 1);
+    rb_define_method(rb_eException, &quot;to_s&quot;, exc_to_s, 0);
+    rb_define_method(rb_eException, &quot;message&quot;, exc_message, 0);
+    rb_define_method(rb_eException, &quot;inspect&quot;, exc_inspect, 0);
+    rb_define_method(rb_eException, &quot;backtrace&quot;, exc_backtrace, 0);
+    rb_define_method(rb_eException, &quot;set_backtrace&quot;, exc_set_backtrace, 1);
+    */
 
     rb_eSystemExit = rc.class_c.rb_define_class(&quot;SystemExit&quot;, rb_eException);
     rb_eFatal = rc.class_c.rb_define_class(&quot;fatal&quot;, rb_eException);
@@ -88,12 +99,26 @@ public class Error_c
     return rc.Qnil;
   }
 
+  // error.c:369
+  public function
+  exc_initialize(argc:int, argv:StackPointer, exc:Value):Value
+  {
+    var arg:Value;
+
+    //rb_scan_args(argc, argv, &quot;01&quot;, &amp;arg);
+    arg = argv.get_at(0);
+    rc.variable_c.rb_iv_set(exc, &quot;mesg&quot;, arg);
+    rc.variable_c.rb_iv_set(exc, &quot;bt&quot;, rc.Qnil);
+
+    return exc;
+  }
+
   public function
   rb_raise(exc:RClass, mesg:String):void
   {
     var rstring:RString = rc.string_c.rb_str_new(mesg);
     rc.eval_c.rb_exc_raise(rc.error_c.rb_exc_new3(exc, rstring));
-    //throw new Error(exc.toString() + mesg);
+    throw new Error(exc.toString() + mesg);
   }
 
   public function</diff>
      <filename>flash/src/ruby/internals/Error_c.as</filename>
    </modified>
    <modified>
      <diff>@@ -14,6 +14,28 @@ public class Eval_c
   public function
   Init_eval():void
   {
+    /* TODO: fix position */
+    /*
+    GET_THREAD()-&gt;vm-&gt;mark_object_ary = rb_ary_new();
+
+    rb_define_virtual_variable(&quot;$@&quot;, errat_getter, errat_setter);
+    rb_define_virtual_variable(&quot;$!&quot;, errinfo_getter, 0);
+
+    rb_define_global_function(&quot;eval&quot;, rb_f_eval, -1);
+    rb_define_global_function(&quot;iterator?&quot;, rb_f_block_given_p, 0);
+    rb_define_global_function(&quot;block_given?&quot;, rb_f_block_given_p, 0);
+    */
+
+    rc.class_c.rb_define_global_function(&quot;raise&quot;, rb_f_raise, -1);
+    rc.class_c.rb_define_global_function(&quot;fail&quot;, rb_f_raise, -1);
+
+    /*
+    rb_define_global_function(&quot;global_variables&quot;, rb_f_global_variables, 0);	/ * in variable.c * /
+    rb_define_global_function(&quot;local_variables&quot;, rb_f_local_variables, 0);
+
+    rb_define_global_function(&quot;__method__&quot;, rb_f_method_name, 0);
+    rb_define_global_function(&quot;__callee__&quot;, rb_f_method_name, 0);
+    */
 
     rc.class_c.rb_define_private_method(rc.object_c.rb_cModule, &quot;append_features&quot;, rb_mod_append_features, 1);
     rc.class_c.rb_define_private_method(rc.object_c.rb_cModule, &quot;extend_object&quot;, rb_mod_extend_object, 1);
@@ -28,6 +50,52 @@ public class Eval_c
 
   }
 
+  // eval.c:468
+  public function
+  rb_f_raise(argc:int, argv:StackPointer, recv:Value):Value
+  {
+    var err:Value;
+
+    if (argc == 0) {
+      trace(&quot;raise with zero arguments is not implemented&quot;);
+      argc = 1;
+      argv = new StackPointer([rc.string_c.rb_str_new(&quot;Raise called without argument&quot;)]);
+      /*
+      err = get_errinfo();
+      if (!rc.NIL_P(err)) {
+        argc = 1;
+        argv = new StackPointer([err]);
+      }
+      */
+    }
+    rb_raise_jump(rb_make_exception(argc, argv));
+
+    return rc.Qnil; // not reached
+  }
+
+  // eval.c:483
+  public function
+  rb_make_exception(argc:int, argv:StackPointer):Value
+  {
+    if (argc == 1 &amp;&amp; rc.TYPE(argv.get_at(0)) == Value.T_STRING) {
+      return rc.error_c.rb_exc_new3(rc.error_c.rb_eRuntimeError, argv.get_at(0));
+    } else {
+      trace(&quot;rb_make_exception: doesn't handle this case yet.&quot;);
+      return rc.error_c.rb_exc_new3(rc.error_c.rb_eRuntimeError,
+        rc.string_c.rb_str_new(&quot;rb_make_exception: doesn't handle this case yet.&quot;));
+    }
+  }
+
+  // eval.c:529
+  public function
+  rb_raise_jump(mesg:Value):void
+  {
+    var th:RbThread = rc.GET_THREAD();
+    th.cfp = rc.vm_c.RUBY_VM_PREVIOUS_CONTROL_FRAME(th, th.cfp);
+    /* TODO: fix me */
+    throw new RTag(RTag.TAG_RAISE, mesg);
+  }
+
   // eval.c:544
   public function
   rb_block_given_p():Boolean
@@ -178,13 +246,23 @@ public class Eval_c
   public function
   ruby_exec_node(n:Value, file:String):int
   {
+    var state:int;
     var iseq:Value = n;
     var th:RbThread = rc.GET_THREAD();
 
     // TODO: @skipped PUSH_TAG, EXEC_TAG, POP_TAG&quot;);
-    th.base_block = null;
-    rc.vm_c.rb_iseq_eval(iseq);
-    return 0;
+    var tag:RbVmTag = rc.PUSH_TAG(th);
+    try { // EXEC_TAG()
+      // state = EXEC_TAG();
+      // TODO: @skip SAVE_ROOT_JMPBUF
+      th.base_block = null;
+      rc.vm_c.rb_iseq_eval(iseq);
+    } catch (e:RTag) {
+      // state
+      state = e.tag;
+    }
+    rc.POP_TAG(tag, th);
+    return state;
   }
 
 }</diff>
      <filename>flash/src/ruby/internals/Eval_c.as</filename>
    </modified>
    <modified>
      <diff>@@ -58,7 +58,7 @@ public class RbThread extends Value
   public var keeping_mutexes:*;
   public var transition_for_lock:int;
 
-  public var tag:*;
+  public var tag:RbVmTag;
   public var trap_tag:*;
 
   public var parse_in_eval:int;</diff>
      <filename>flash/src/ruby/internals/RbThread.as</filename>
    </modified>
    <modified>
      <diff>@@ -1268,6 +1268,24 @@ public class RubyCore
     }
   }
 
+  // eval_intern.h:146
+  public function
+  PUSH_TAG(th:RbThread):RbVmTag
+  {
+    var _tag:RbVmTag = new RbVmTag();
+    _tag.tag = null;
+    _tag.prev = th.tag;
+    th.tag = _tag;
+    return _tag;
+  }
+
+  // eval_intern
+  public function
+  POP_TAG(tag:RbVmTag, th:RbThread):void
+  {
+    th.tag = tag.prev;
+  }
+
 }
 }
 </diff>
      <filename>flash/src/ruby/internals/RubyCore.as</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>c8351c6e3988b5f9935cfd92b27715763770189d</id>
    </parent>
  </parents>
  <author>
    <name>Jonathan Branam</name>
    <email>github@jonathanbranam.net</email>
  </author>
  <url>http://github.com/jonathanbranam/redsun/commit/ff87d0d2bee00da7a0649e5fa57dd95d8e8651ab</url>
  <id>ff87d0d2bee00da7a0649e5fa57dd95d8e8651ab</id>
  <committed-date>2008-12-15T08:05:05-08:00</committed-date>
  <authored-date>2008-12-15T08:05:05-08:00</authored-date>
  <message>Implement raising a single string argument and global error trap.
raise will correctly throw a Flash Error (RTag class) when executed.
Exception will only be properly caught at the outermost execution frame
of the interpreter.</message>
  <tree>b24f9b26e5f4904ce68824f418a197aaf41b7c04</tree>
  <committer>
    <name>Jonathan Branam</name>
    <email>github@jonathanbranam.net</email>
  </committer>
</commit>
