[macruby-changes] [1844] MacRuby/branches/experimental/vm.cpp
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jun 11 23:28:29 PDT 2009
Revision: 1844
http://trac.macosforge.org/projects/ruby/changeset/1844
Author: lsansonetti at apple.com
Date: 2009-06-11 23:28:12 -0700 (Thu, 11 Jun 2009)
Log Message:
-----------
support for -forwardInvocation: style message forwarding
Modified Paths:
--------------
MacRuby/branches/experimental/vm.cpp
Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp 2009-06-12 03:41:50 UTC (rev 1843)
+++ MacRuby/branches/experimental/vm.cpp 2009-06-12 06:28:12 UTC (rev 1844)
@@ -2169,6 +2169,21 @@
rcache.node = node;
}
+static force_inline bool
+can_forwardInvocation(VALUE recv, SEL sel)
+{
+ if (!SPECIAL_CONST_P(recv)) {
+ static SEL methodSignatureForSelector = 0;
+ if (methodSignatureForSelector == 0) {
+ methodSignatureForSelector =
+ sel_registerName("methodSignatureForSelector:");
+ }
+ return objc_msgSend((id)recv, methodSignatureForSelector, (id)sel)
+ != nil;
+ }
+ return false;
+}
+
static force_inline void
fill_ocache(struct mcache *cache, VALUE self, Class klass, IMP imp, SEL sel,
Method method, int argc)
@@ -2187,7 +2202,8 @@
sel_getName(sel));
abort();
}
- if (ocache.bs_method != NULL && ocache.bs_method->variadic) {
+ if (ocache.bs_method != NULL && ocache.bs_method->variadic
+ && method != NULL) {
const int real_argc = method_getNumberOfArguments(method) - 2;
if (real_argc < argc) {
const size_t s = strlen(types);
@@ -2250,12 +2266,19 @@
}
else {
// Method is not found...
- const char *selname = (const char *)sel;
- size_t selname_len = strlen(selname);
+ // Does the receiver implements -forwardInvocation:?
+ if (can_forwardInvocation(self, sel)) {
+ fill_ocache(cache, self, klass, (IMP)objc_msgSend, sel, NULL,
+ argc);
+ goto dispatch;
+ }
+
// Let's see if are not trying to call a Ruby method that accepts
// a regular argument then a optional Hash argument, to be
// compatible with the Ruby specification.
+ const char *selname = (const char *)sel;
+ size_t selname_len = strlen(selname);
if (argc > 1) {
const char *p = strchr(selname, ':');
if (p != NULL && p + 1 != '\0') {
@@ -2331,6 +2354,7 @@
}
}
+dispatch:
if (cache->flag == MCACHE_RCALL) {
if (rcache.klass != klass) {
goto recache;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090611/4b31c78a/attachment.html>
More information about the macruby-changes
mailing list