[macruby-changes] [1386] MacRuby/branches/experimental/roxor.cpp

source_changes at macosforge.org source_changes at macosforge.org
Mon Apr 6 16:22:36 PDT 2009


Revision: 1386
          http://trac.macosforge.org/projects/ruby/changeset/1386
Author:   lsansonetti at apple.com
Date:     2009-04-06 16:22:35 -0700 (Mon, 06 Apr 2009)
Log Message:
-----------
a better implementation for catch/throw

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-04-06 17:34:01 UTC (rev 1385)
+++ MacRuby/branches/experimental/roxor.cpp	2009-04-06 23:22:35 UTC (rev 1386)
@@ -381,6 +381,12 @@
     struct rb_vm_outer *outer;
 };
 
+typedef struct {
+    jmp_buf buf;
+    VALUE throw_value;
+    int nested;
+} rb_vm_catch_t;
+
 class RoxorVM
 {
     private:
@@ -418,7 +424,7 @@
 	rb_vm_block_t *previous_block;
 	bool parse_in_eval;
 
-	CFMutableDictionaryRef catch_jmp_bufs;
+	std::map<VALUE, rb_vm_catch_t *> catch_jmp_bufs;
 	std::vector<jmp_buf *> return_from_block_jmp_bufs;
 
 	RoxorVM(void);
@@ -2185,8 +2191,6 @@
     previous_block = NULL;
     parse_in_eval = false;
 
-    catch_jmp_bufs = NULL;
-
     load_path = rb_ary_new();
     rb_objc_retain((void *)load_path);
     loaded_features = rb_ary_new();
@@ -6697,43 +6701,45 @@
     }
 }
 
-typedef struct {
-    jmp_buf *buf;
-    VALUE throw_value;
-} rb_vm_catch_t;
-
 extern "C"
 VALUE
 rb_vm_catch(VALUE tag)
 {
-    CFMutableDictionaryRef dict = GET_VM()->catch_jmp_bufs;
-    if (dict == NULL) {
-	dict = CFDictionaryCreateMutable(NULL, 0,
-		&kCFTypeDictionaryKeyCallBacks, NULL);
-	GET_VM()->catch_jmp_bufs = dict;
-    }
-    
-    void *key = RB2OC(tag);
+    std::map<VALUE, rb_vm_catch_t *>::iterator iter =
+	GET_VM()->catch_jmp_bufs.find(tag);
     rb_vm_catch_t *s = NULL;
-    if (!CFDictionaryGetValueIfPresent(dict, (void *)key, (const void **)&s)) {
+    if (iter == GET_VM()->catch_jmp_bufs.end()) {
 	s = (rb_vm_catch_t *)malloc(sizeof(rb_vm_catch_t));
-	s->buf = (jmp_buf *)malloc(sizeof(jmp_buf));
 	s->throw_value = Qnil;
-	CFDictionarySetValue(dict, (void *)key, (void *)s);
+	s->nested = 1;
+	GET_VM()->catch_jmp_bufs[tag] = s;
+	rb_objc_retain((void *)tag);
     }
+    else {
+	s = iter->second;
+	s->nested++;
+    }
 
-    if (setjmp(*s->buf) == 0) {
-        return rb_vm_yield(1, &tag);
+    VALUE retval;
+    if (setjmp(s->buf) == 0) {
+	retval = rb_vm_yield(1, &tag);
     }
+    else {
+	retval = s->throw_value;
+	rb_objc_release((void *)retval);
+	s->throw_value = Qnil;
+    }
 
-    VALUE retval = s->throw_value;
-    rb_objc_release((void *)retval);
+    iter = GET_VM()->catch_jmp_bufs.find(tag);
+    assert(iter != GET_VM()->catch_jmp_bufs.end());
+    s->nested--;
+    if (s->nested == 0) {
+	s = iter->second;
+	free(s);
+	GET_VM()->catch_jmp_bufs.erase(iter);
+	rb_objc_release((void *)tag);
+    }
 
-    // FIXME this crashes for a strange reason - to investigate
-    //CFDictionaryRemoveValue(GET_VM()->catch_jmp_bufs, key); 
-    //free(s->buf);
-    //free(s);
-
     return retval;
 }
 
@@ -6741,21 +6747,19 @@
 VALUE
 rb_vm_throw(VALUE tag, VALUE value)
 {
-    CFMutableDictionaryRef dict = GET_VM()->catch_jmp_bufs;
-    rb_vm_catch_t *s = NULL;
-    void *key = RB2OC(tag);
-    if (dict != NULL) {
-	CFDictionaryGetValueIfPresent(dict, (void *)key, (const void **)&s);
-    }
-    if (s == NULL) {
+    std::map<VALUE, rb_vm_catch_t *>::iterator iter =
+	GET_VM()->catch_jmp_bufs.find(tag);
+    if (iter == GET_VM()->catch_jmp_bufs.end()) {
         VALUE desc = rb_inspect(tag);
         rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
     }
+    rb_vm_catch_t *s = iter->second;
 
     rb_objc_retain((void *)value);
     s->throw_value = value;
-    longjmp(*s->buf, 1);
 
+    longjmp(s->buf, 1);
+
     return Qnil; // never reached
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090406/aa7e85f7/attachment.html>


More information about the macruby-changes mailing list