[macruby-changes] [2029] MacRuby/branches/experimental/vm.cpp
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jul 16 18:39:06 PDT 2009
Revision: 2029
http://trac.macosforge.org/projects/ruby/changeset/2029
Author: lsansonetti at apple.com
Date: 2009-07-16 18:39:05 -0700 (Thu, 16 Jul 2009)
Log Message:
-----------
fixed a bug in the super dispatcher: now ignoring all call stack items before the receiver's implementation, to work around false positives in our stack check
Modified Paths:
--------------
MacRuby/branches/experimental/vm.cpp
Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp 2009-07-15 20:13:06 UTC (rev 2028)
+++ MacRuby/branches/experimental/vm.cpp 2009-07-17 01:39:05 UTC (rev 2029)
@@ -1234,7 +1234,7 @@
static inline void
resolve_method_type(char *buf, const size_t buflen, Class klass, Method m,
- SEL sel, const unsigned int oc_arity)
+ SEL sel, const unsigned int oc_arity)
{
bs_element_method_t *bs_method = GET_CORE()->find_bs_method(klass, sel);
@@ -2044,31 +2044,50 @@
abort();
}
+static inline IMP
+objc_imp(IMP imp)
+{
+ rb_vm_method_node_t *node = GET_CORE()->method_node_get(imp);
+ if (node != NULL && node->ruby_imp == imp) {
+ imp = node->objc_imp;
+ }
+ return imp;
+}
+
static inline Method
-rb_vm_super_lookup(VALUE klass, SEL sel, VALUE *klassp)
+rb_vm_super_lookup(VALUE klass, SEL sel)
{
- VALUE k, ary;
- int i, count;
- bool klass_located;
+ // Locate the current method implementation.
+ Method m = class_getInstanceMethod((Class)klass, sel);
+ assert(m != NULL);
+ IMP self = objc_imp(method_getImplementation(m));
- ary = rb_mod_ancestors_nocopy(klass);
-
+ // Compute the stack call implementations right after our current method.
void *callstack[128];
int callstack_n = backtrace(callstack, 128);
-
std::vector<void *> callstack_funcs;
- for (int i = 0; i < callstack_n; i++) {
+ bool skip = true;
+ for (int i = callstack_n - 1; i >= 0; i--) {
void *start = NULL;
if (GET_CORE()->symbolize_call_address(callstack[i],
&start, NULL, NULL, 0)) {
- rb_vm_method_node_t *node = GET_CORE()->method_node_get((IMP)start);
- if (node != NULL && node->ruby_imp == start) {
- start = (void *)node->objc_imp;
+ start = (void *)objc_imp((IMP)start);
+ if (start == (void *)self) {
+ skip = false;
}
- callstack_funcs.push_back(start);
+ if (!skip) {
+ callstack_funcs.push_back(start);
+ }
}
}
+ // Iterate over ancestors and return the first method that isn't on
+ // the stack.
+ VALUE ary = rb_mod_ancestors_nocopy(klass);
+ const int count = RARRAY_LEN(ary);
+ VALUE k = klass;
+ bool klass_located = false;
+
#if ROXOR_VM_DEBUG
printf("locating super method %s of class %s in ancestor chain %s\n",
sel_getName(sel), rb_class2name(klass),
@@ -2082,11 +2101,7 @@
printf("\n");
#endif
- count = RARRAY_LEN(ary);
- k = klass;
- klass_located = false;
-
- for (i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
if (!klass_located && RARRAY_AT(ary, i) == klass) {
klass_located = true;
}
@@ -2407,7 +2422,7 @@
recache:
Method method;
if (opt == DISPATCH_SUPER) {
- method = rb_vm_super_lookup((VALUE)klass, sel, NULL);
+ method = rb_vm_super_lookup((VALUE)klass, sel);
}
else {
method = class_getInstanceMethod(klass, sel);
@@ -2437,7 +2452,7 @@
// Method is not found...
// Does the receiver implements -forwardInvocation:?
- if (can_forwardInvocation(self, sel)) {
+ if (opt != DISPATCH_SUPER && can_forwardInvocation(self, sel)) {
fill_ocache(cache, self, klass, (IMP)objc_msgSend, sel, NULL,
argc);
goto dispatch;
@@ -3993,7 +4008,7 @@
VALUE exc = GET_VM()->current_exception();
if (exc == Qnil) {
printf("uncatched Objective-C/C++ exception...\n");
- return;
+ std::terminate();
}
static SEL sel_message = 0;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090716/898607c3/attachment.html>
More information about the macruby-changes
mailing list