[macruby-changes] [1566] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Mon May 11 17:47:07 PDT 2009
Revision: 1566
http://trac.macosforge.org/projects/ruby/changeset/1566
Author: lsansonetti at apple.com
Date: 2009-05-11 17:47:06 -0700 (Mon, 11 May 2009)
Log Message:
-----------
now keeping the current exceptions in a stack, which fixes several bugs
Modified Paths:
--------------
MacRuby/branches/experimental/roxor.cpp
MacRuby/branches/experimental/test_vm/exception.rb
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-05-11 22:50:13 UTC (rev 1565)
+++ MacRuby/branches/experimental/roxor.cpp 2009-05-12 00:47:06 UTC (rev 1566)
@@ -369,6 +369,7 @@
void compile_landing_pad_header(void);
void compile_landing_pad_footer(void);
void compile_rethrow_exception(void);
+ void compile_pop_exception(void);
Value *compile_lvar_slot(ID name);
bool compile_lvars(ID *tbl);
Value *compile_new_struct(Value *klass, std::vector<Value *> &fields);
@@ -503,13 +504,13 @@
to_rval_convertors, to_ocval_convertors;
std::vector<rb_vm_block_t *> current_blocks;
+ std::vector<VALUE> current_exceptions;
public:
static RoxorVM *current;
Class current_class;
VALUE current_top_object;
- VALUE current_exception;
VALUE loaded_features;
VALUE load_path;
VALUE backref;
@@ -561,6 +562,25 @@
return b;
}
+ VALUE current_exception(void) {
+ return current_exceptions.empty()
+ ? Qnil : current_exceptions.back();
+ }
+
+ void push_current_exception(VALUE exc) {
+ assert(!NIL_P(exc));
+ rb_objc_retain((void *)exc);
+ current_exceptions.push_back(exc);
+ }
+
+ VALUE pop_current_exception(void) {
+ assert(!current_exceptions.empty());
+ VALUE exc = current_exceptions.back();
+ rb_objc_release((void *)exc);
+ current_exceptions.pop_back();
+ return exc;
+ }
+
std::map<VALUE, rb_vm_catch_t *> catch_jmp_bufs;
std::vector<jmp_buf *> return_from_block_jmp_bufs;
@@ -1817,7 +1837,9 @@
switch (nd_type(node)) {
case NODE_RETRY:
- // Simply jump to the nearest begin label.
+ // Simply jump to the nearest begin label, after poping the
+ // current exception.
+ compile_pop_exception();
if (begin_bb == NULL) {
rb_raise(rb_eSyntaxError, "unexpected retry");
}
@@ -1967,7 +1989,7 @@
}
void
-RoxorCompiler::compile_landing_pad_footer(void)
+RoxorCompiler::compile_pop_exception(void)
{
if (popExceptionFunc == NULL) {
// void rb_vm_pop_exception(void);
@@ -1976,7 +1998,13 @@
Type::VoidTy, NULL));
}
CallInst::Create(popExceptionFunc, "", bb);
+}
+void
+RoxorCompiler::compile_landing_pad_footer(void)
+{
+ compile_pop_exception();
+
Function *endCatchFunc = NULL;
if (endCatchFunc == NULL) {
// void __cxa_end_catch(void);
@@ -2636,7 +2664,6 @@
{
running = false;
current_top_object = Qnil;
- current_exception = Qnil;
safe_level = 0;
backref = Qnil;
@@ -8697,9 +8724,11 @@
void
rb_vm_raise(VALUE exception)
{
- rb_objc_retain((void *)exception);
rb_iv_set(exception, "bt", rb_vm_backtrace(100));
- GET_VM()->current_exception = exception;
+ if (exception != GET_VM()->current_exception()) {
+ rb_objc_retain((void *)exception);
+ GET_VM()->push_current_exception(exception);
+ }
void *exc = __cxa_allocate_exception(0);
__cxa_throw(exc, NULL, NULL);
}
@@ -8769,8 +8798,10 @@
rb_vm_is_eh_active(int argc, ...)
{
assert(argc > 0);
- assert(GET_VM()->current_exception != Qnil);
+ VALUE current_exception = GET_VM()->current_exception();
+ assert(current_exception != Qnil);
+
va_list ar;
unsigned char active = 0;
@@ -8780,13 +8811,13 @@
if (TYPE(obj) == T_ARRAY) {
for (int j = 0, count = RARRAY_LEN(obj); j < count; ++j) {
VALUE obj2 = RARRAY_AT(obj, j);
- if (rb_obj_is_kind_of(GET_VM()->current_exception, obj2)) {
+ if (rb_obj_is_kind_of(current_exception, obj2)) {
active = 1;
}
}
}
else {
- if (rb_obj_is_kind_of(GET_VM()->current_exception, obj)) {
+ if (rb_obj_is_kind_of(current_exception, obj)) {
active = 1;
}
}
@@ -8800,30 +8831,28 @@
void
rb_vm_pop_exception(void)
{
- VALUE exc = GET_VM()->current_exception;
- assert(exc != Qnil);
- rb_objc_release((void *)exc);
- GET_VM()->current_exception = Qnil;
+ GET_VM()->pop_current_exception();
}
extern "C"
VALUE
rb_vm_current_exception(void)
{
- return GET_VM()->current_exception;
+ return GET_VM()->current_exception();
}
extern "C"
void
rb_vm_set_current_exception(VALUE exception)
{
- if (GET_VM()->current_exception != exception) {
- if (GET_VM()->current_exception != Qnil) {
- rb_objc_release((void *)GET_VM()->current_exception);
- }
- rb_objc_retain((void *)exception);
- GET_VM()->current_exception = exception;
+ assert(!NIL_P(exception));
+
+ VALUE current = GET_VM()->current_exception();
+ assert(exception != current);
+ if (!NIL_P(current)) {
+ GET_VM()->pop_current_exception();
}
+ GET_VM()->push_current_exception(exception);
}
extern "C"
@@ -8837,7 +8866,7 @@
void
rb_vm_print_current_exception(void)
{
- VALUE exc = GET_VM()->current_exception;
+ VALUE exc = GET_VM()->current_exception();
if (exc == Qnil) {
printf("uncatched Objective-C/C++ exception...");
return;
Modified: MacRuby/branches/experimental/test_vm/exception.rb
===================================================================
--- MacRuby/branches/experimental/test_vm/exception.rb 2009-05-11 22:50:13 UTC (rev 1565)
+++ MacRuby/branches/experimental/test_vm/exception.rb 2009-05-12 00:47:06 UTC (rev 1566)
@@ -178,3 +178,45 @@
p :ok if $! == e
end
}
+
+assert ":ok\n:ok\n:ok", %{
+ e1 = RuntimeError.new('e1')
+ e2 = RuntimeError.new('e2')
+ e3 = RuntimeError.new('e3')
+ begin
+ raise e1
+ rescue
+ begin
+ raise e2
+ rescue
+ begin
+ raise e3
+ rescue
+ p :ok if $! == e3
+ end
+ p :ok if $! == e2
+ end
+ p :ok if $! == e1
+ end
+}
+
+assert ":ok\n:ok\n:ok\n:ok", %{
+ x = 0
+ e = RuntimeError.new('foo')
+ begin
+ p :ok if $!.nil?
+ x += 1
+ raise e
+ rescue
+ p :ok if $! == e
+ retry if x < 2
+ end
+}
+
+assert ":ok", %{
+ begin
+ eval("1==2==3")
+ rescue Exception
+ end
+ p :ok if $!.nil?
+}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090511/b058b320/attachment.html>
More information about the macruby-changes
mailing list