[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