Skip to content

Commit

Permalink
Implement raising a single string argument and global error trap.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jonathanbranam committed Dec 15, 2008
1 parent c8351c6 commit ff87d0d
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 7 deletions.
6 changes: 6 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

12/15/2008

Todo:
* Exception handling
* Ruby -> Flash bytecode format (JSON issues)
2 changes: 1 addition & 1 deletion chromosphere/src/Chromosphere.mxml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
protected function cc():void
{
dir_root = File.userDirectory.nativePath + "/work/ruby/redsun";
ti.text = "research/rubyconf.rb";
ti.text = "research/exceptions.rb";
read_file(ti.text);
sp = new UIComponent();
sp.y = 50;
Expand Down
29 changes: 27 additions & 2 deletions flash/src/ruby/internals/Error_c.as
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,18 @@ public class Error_c

public function Init_Exception():void {
rb_eException = rc.class_c.rb_define_class("Exception", rc.object_c.rb_cObject);
// exception methods

//rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
//rb_define_method(rb_eException, "exception", exc_exception, -1);
rc.class_c.rb_define_method(rb_eException, "initialize", exc_initialize, -1);
/*
rb_define_method(rb_eException, "==", exc_equal, 1);
rb_define_method(rb_eException, "to_s", exc_to_s, 0);
rb_define_method(rb_eException, "message", exc_message, 0);
rb_define_method(rb_eException, "inspect", exc_inspect, 0);
rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
*/

rb_eSystemExit = rc.class_c.rb_define_class("SystemExit", rb_eException);
rb_eFatal = rc.class_c.rb_define_class("fatal", rb_eException);
Expand Down Expand Up @@ -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, "01", &arg);
arg = argv.get_at(0);
rc.variable_c.rb_iv_set(exc, "mesg", arg);
rc.variable_c.rb_iv_set(exc, "bt", 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
Expand Down
84 changes: 81 additions & 3 deletions flash/src/ruby/internals/Eval_c.as
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ public class Eval_c
public function
Init_eval():void
{
/* TODO: fix position */
/*
GET_THREAD()->vm->mark_object_ary = rb_ary_new();
rb_define_virtual_variable("$@", errat_getter, errat_setter);
rb_define_virtual_variable("$!", errinfo_getter, 0);
rb_define_global_function("eval", rb_f_eval, -1);
rb_define_global_function("iterator?", rb_f_block_given_p, 0);
rb_define_global_function("block_given?", rb_f_block_given_p, 0);
*/

rc.class_c.rb_define_global_function("raise", rb_f_raise, -1);
rc.class_c.rb_define_global_function("fail", rb_f_raise, -1);

/*
rb_define_global_function("global_variables", rb_f_global_variables, 0); / * in variable.c * /
rb_define_global_function("local_variables", rb_f_local_variables, 0);
rb_define_global_function("__method__", rb_f_method_name, 0);
rb_define_global_function("__callee__", rb_f_method_name, 0);
*/

rc.class_c.rb_define_private_method(rc.object_c.rb_cModule, "append_features", rb_mod_append_features, 1);
rc.class_c.rb_define_private_method(rc.object_c.rb_cModule, "extend_object", rb_mod_extend_object, 1);
Expand All @@ -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("raise with zero arguments is not implemented");
argc = 1;
argv = new StackPointer([rc.string_c.rb_str_new("Raise called without argument")]);
/*
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 && 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("rb_make_exception: doesn't handle this case yet.");
return rc.error_c.rb_exc_new3(rc.error_c.rb_eRuntimeError,
rc.string_c.rb_str_new("rb_make_exception: doesn't handle this case yet."));
}
}

// 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
Expand Down Expand Up @@ -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");
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;
}

}
Expand Down
2 changes: 1 addition & 1 deletion flash/src/ruby/internals/RbThread.as
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions flash/src/ruby/internals/RbVmTag.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ruby.internals
{
public class RbVmTag
{
public var buf:*;
public var tag:Value;
public var retval:Value;
public var prev:RbVmTag;

}
}
18 changes: 18 additions & 0 deletions flash/src/ruby/internals/RubyCore.as
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

}
}

10 changes: 10 additions & 0 deletions research/exceptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

# Testing exceptions
puts "Before Raise"
#begin
raise "Something"
puts "Not Rescued"
#rescue
# puts "Rescued"
#end

0 comments on commit ff87d0d

Please sign in to comment.