[macruby-changes] [1571] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Tue May 12 22:31:54 PDT 2009


Revision: 1571
          http://trac.macosforge.org/projects/ruby/changeset/1571
Author:   lsansonetti at apple.com
Date:     2009-05-12 22:31:53 -0700 (Tue, 12 May 2009)
Log Message:
-----------
fixing some bugs in Method, started to work on #to_proc

Modified Paths:
--------------
    MacRuby/branches/experimental/proc.c
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/roxor.h
    MacRuby/branches/experimental/test_vm/method.rb

Modified: MacRuby/branches/experimental/proc.c
===================================================================
--- MacRuby/branches/experimental/proc.c	2009-05-12 09:43:57 UTC (rev 1570)
+++ MacRuby/branches/experimental/proc.c	2009-05-13 05:31:53 UTC (rev 1571)
@@ -41,7 +41,9 @@
     obj = Data_Wrap_Struct(klass, NULL, NULL, proc);
     if (!(proc->flags & VM_BLOCK_PROC)) {
 	proc->flags |= VM_BLOCK_PROC;
-	rb_vm_add_var_use(proc);
+	if (!(proc->flags & VM_BLOCK_METHOD)) {
+	    rb_vm_add_var_use(proc);
+	}
     }
     return obj;
 }
@@ -1382,22 +1384,12 @@
 static VALUE
 method_proc(VALUE method, SEL sel)
 {
-#if 0 // TODO
-    VALUE procval;
-    rb_proc_t *proc;
-    /*
-     * class Method
-     *   def to_proc
-     *     proc{|*args|
-     *       self.call(*args)
-     *     }
-     *   end
-     * end
-     */
-    procval = rb_iterate(mlambda, 0, bmcall, method);
-    GetProcPtr(procval, proc);
-    proc->is_from_method = 1;
-    return procval;
+#if 0
+    // TODO
+    rb_vm_method_t *data;
+    Data_Get_Struct(method, rb_vm_method_t, data);
+    rb_vm_block_t *block = rb_vm_create_block_from_method(data);
+    return rb_proc_alloc_with_block(rb_cProc, block);
 #endif
     return Qnil;
 }

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-05-12 09:43:57 UTC (rev 1570)
+++ MacRuby/branches/experimental/roxor.cpp	2009-05-13 05:31:53 UTC (rev 1571)
@@ -41,6 +41,8 @@
 #include <execinfo.h>
 #include <dlfcn.h>
 
+#define force_inline __attribute__((always_inline))
+
 #define FROM_GV(gv,t) ((t)(gv.IntVal.getZExtValue()))
 static GenericValue
 value2gv(VALUE v)
@@ -449,6 +451,9 @@
 	    rb_vm_c_stub_t *stub;
 	} fcall;
     } as;
+#define rcache cache->as.rcall
+#define ocache cache->as.ocall
+#define fcache cache->as.fcall
 };
 
 extern "C" void *__cxa_allocate_exception(size_t);
@@ -2595,6 +2600,14 @@
 }
 
 static inline rb_vm_arity_t
+rb_vm_arity(int argc)
+{
+    rb_vm_arity_t arity;
+    arity.left_req = arity.min = arity.max = arity.real = argc;
+    return arity;
+}
+
+static inline rb_vm_arity_t
 rb_vm_node_arity(NODE *node)
 {
     const int type = nd_type(node);
@@ -7251,8 +7264,7 @@
     }
 }
 
-__attribute__((always_inline))
-static void
+static force_inline void
 __rb_vm_fix_args(const VALUE *argv, VALUE *new_argv, const rb_vm_arity_t &arity, int argc)
 {
     assert(argc >= arity.min);
@@ -7299,8 +7311,7 @@
     }
 }
 
-__attribute__((always_inline))
-static VALUE
+static force_inline VALUE
 __rb_vm_bcall(VALUE self, VALUE dvars, rb_vm_block_t *b,
 	      IMP pimp, const rb_vm_arity_t &arity, int argc, const VALUE *argv)
 {
@@ -7341,8 +7352,7 @@
     abort();
 }
 
-__attribute__((always_inline))
-static VALUE
+static force_inline VALUE
 __rb_vm_rcall(VALUE self, SEL sel, NODE *node, IMP pimp,
 	      const rb_vm_arity_t &arity, int argc, const VALUE *argv)
 {
@@ -7671,8 +7681,7 @@
     return new_sel;
 }
 
-__attribute__((always_inline))
-static VALUE
+static force_inline VALUE
 __rb_vm_ruby_dispatch(VALUE self, SEL sel, NODE *node, IMP imp,
 		      rb_vm_arity_t &arity, int argc, const VALUE *argv)
 {
@@ -7707,12 +7716,43 @@
 	}
     }
 
-    return __rb_vm_rcall(self, sel, node, imp, arity,
-	    argc, argv);
+    return __rb_vm_rcall(self, sel, node, imp, arity, argc, argv);
 }
 
-__attribute__((always_inline))
-static VALUE
+static force_inline void
+fill_rcache(struct mcache *cache, Class klass, IMP imp, NODE *node,
+	    const rb_vm_arity_t &arity)
+{ 
+    cache->flag = MCACHE_RCALL;
+    rcache.klass = klass;
+    rcache.imp = imp;
+    rcache.node = node;
+    rcache.arity = arity;
+}
+
+static force_inline void
+fill_ocache(struct mcache *cache, VALUE self, Class klass, IMP imp, SEL sel,
+	    int argc)
+{
+    cache->flag = MCACHE_OCALL;
+    ocache.klass = klass;
+    ocache.imp = imp;
+    ocache.bs_method = GET_VM()->find_bs_method(klass, sel);
+
+    char types[200];
+    if (!rb_objc_get_types(self, klass, sel, ocache.bs_method,
+		types, sizeof types)) {
+	printf("cannot get encoding types for %c[%s %s]\n",
+		class_isMetaClass(klass) ? '+' : '-',
+		class_getName(klass),
+		sel_getName(sel));
+	abort();
+    }
+    ocache.stub = (rb_vm_objc_stub_t *)GET_VM()->gen_stub(types, 
+	    argc, true);
+}
+
+static force_inline VALUE
 __rb_vm_dispatch(struct mcache *cache, VALUE self, Class klass, SEL sel,
 		 rb_vm_block_t *block, unsigned char opt, int argc,
 		 const VALUE *argv)
@@ -7737,10 +7777,6 @@
 	    method = class_getInstanceMethod(klass, sel);
 	}
 
-#define rcache cache->as.rcall
-#define ocache cache->as.ocall
-#define fcache cache->as.fcall
-
 	if (method != NULL) {
 	    IMP imp = method_getImplementation(method);
 	    struct RoxorFunctionIMP *func_imp =
@@ -7748,30 +7784,12 @@
 
 	    if (func_imp != NULL) {
 		// ruby call
-		cache->flag = MCACHE_RCALL;
-		rcache.klass = klass;
-		rcache.imp = func_imp->ruby_imp;
-		rcache.node = func_imp->node;
-		rcache.arity = rb_vm_node_arity(func_imp->node);
+		fill_rcache(cache, klass, func_imp->ruby_imp, func_imp->node,
+			rb_vm_node_arity(func_imp->node));
 	    }
 	    else {
 		// objc call
-		cache->flag = MCACHE_OCALL;
-		ocache.klass = klass;
-		ocache.imp = imp;
-		ocache.bs_method = GET_VM()->find_bs_method(klass, sel);
-
-		char types[200];
-		if (!rb_objc_get_types(self, klass, sel, ocache.bs_method,
-				       types, sizeof types)) {
-		    printf("cannot get encoding types for %c[%s %s]\n",
-			    class_isMetaClass(klass) ? '+' : '-',
-			    class_getName(klass),
-			    sel_getName(sel));
-		    abort();
-		}
-		ocache.stub = (rb_vm_objc_stub_t *)GET_VM()->gen_stub(types, 
-			argc, true);
+		fill_ocache(cache, self, klass, imp, sel, argc);
 	    }
 	}
 	else {
@@ -7917,18 +7935,13 @@
 	return (*fcache.stub)(fcache.imp, argc, argv);
     }
 
-#undef rcache
-#undef ocache
-#undef fcache
-
     printf("BOUH %s\n", (char *)sel);
     abort();
 }
 
 #define MAX_DISPATCH_ARGS 200
 
-__attribute__((always_inline))
-static int
+static force_inline int
 __rb_vm_resolve_args(VALUE *argv, int argc, va_list ar)
 {
     // TODO we should only determine the real argc here (by taking into
@@ -7969,9 +7982,9 @@
 }
 
 extern "C"
-    VALUE
+VALUE
 rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel, rb_vm_block_t *block, 
-	unsigned char opt, int argc, ...)
+	       unsigned char opt, int argc, ...)
 {
     VALUE argv[MAX_DISPATCH_ARGS];
     if (argc > 0) {
@@ -7981,7 +7994,8 @@
 	va_end(ar);
     }
 
-    VALUE retval = __rb_vm_dispatch(cache, self, NULL, sel, block, opt, argc, argv);
+    VALUE retval = __rb_vm_dispatch(cache, self, NULL, sel, block, opt, argc,
+	    argv);
 
     if (!GET_VM()->bindings.empty()) {
 	rb_objc_release(GET_VM()->bindings.back());
@@ -8143,7 +8157,9 @@
     rb_vm_block_t *b;
     bool cached = false;
 
-    if ((iter == GET_VM()->blocks.end()) || (iter->second->flags & (VM_BLOCK_ACTIVE | VM_BLOCK_PROC))) {
+    if ((iter == GET_VM()->blocks.end())
+	|| (iter->second->flags & (VM_BLOCK_ACTIVE | VM_BLOCK_PROC))) {
+
 	b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t)
 		+ (sizeof(VALUE *) * dvars_size));
 
@@ -8222,13 +8238,19 @@
 void
 rb_vm_add_var_use(rb_vm_block_t *block)
 {
-    for (rb_vm_block_t *block_for_uses = block; block_for_uses != NULL; block_for_uses = block_for_uses->parent_block) {
+    for (rb_vm_block_t *block_for_uses = block;
+	 block_for_uses != NULL;
+	 block_for_uses = block_for_uses->parent_block) {
+
 	rb_vm_var_uses **var_uses = block_for_uses->parent_var_uses;
 	if (var_uses == NULL) {
 	    continue;
 	}
-	if ((*var_uses == NULL) || ((*var_uses)->uses_count == VM_LVAR_USES_SIZE)) {
-	    rb_vm_var_uses* new_uses = (rb_vm_var_uses*)malloc(sizeof(rb_vm_var_uses));
+	if ((*var_uses == NULL)
+	    || ((*var_uses)->uses_count == VM_LVAR_USES_SIZE)) {
+
+	    rb_vm_var_uses* new_uses =
+		(rb_vm_var_uses*)malloc(sizeof(rb_vm_var_uses));
 	    new_uses->next = *var_uses;
 	    new_uses->uses_count = 0;
 	    *var_uses = new_uses;
@@ -8237,7 +8259,9 @@
 	rb_gc_assign_weak_ref(block, &(*var_uses)->uses[current_index]);
 	++(*var_uses)->uses_count;
     }
-    block->parent_block = NULL; // we should not keep references that won't be used
+
+    // we should not keep references that won't be used
+    block->parent_block = NULL;
 }
 
 struct rb_vm_kept_local {
@@ -8345,7 +8369,6 @@
     GET_VM()->bindings.pop_back();
 }
 
-
 extern "C"
 VALUE
 rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *argv, bool super)
@@ -8375,8 +8398,8 @@
 
 extern "C"
 VALUE
-rb_vm_call_with_cache2(void *cache, rb_vm_block_t *block, VALUE self, VALUE klass,
-		       SEL sel, int argc, const VALUE *argv)
+rb_vm_call_with_cache2(void *cache, rb_vm_block_t *block, VALUE self,
+		       VALUE klass, SEL sel, int argc, const VALUE *argv)
 {
     return __rb_vm_dispatch((struct mcache *)cache, self, (Class)klass, sel,
 	    block, 0, argc, argv);
@@ -8482,11 +8505,44 @@
     m->sel = sel;
     m->arity = arity;
     m->node = node;
-    m->cache = rb_vm_get_call_cache(sel);
 
+    // Let's allocate a static cache here, since a rb_vm_method_t must always
+    // point to the method it was created from.
+    struct mcache *c = (struct mcache *)xmalloc(sizeof(struct mcache));
+    if (node == NULL) {
+	fill_ocache(c, obj, oklass, imp, sel, arity);
+    }
+    else {
+	struct RoxorFunctionIMP *func_imp =
+	    GET_VM()->method_func_imp_get(imp);
+	assert(func_imp != NULL);
+	imp = func_imp->ruby_imp;
+	fill_rcache(c, oklass, imp, node, rb_vm_node_arity(node));
+    }
+    GC_WB(&m->cache, c);
+
     return m;
 }
 
+extern "C"
+rb_vm_block_t *
+rb_vm_create_block_from_method(rb_vm_method_t *method)
+{
+    rb_vm_block_t *b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t));
+
+    GC_WB(&b->self, method->recv);
+    b->node = method->node;
+    b->arity = rb_vm_node_arity(method->node);
+    b->imp = NULL; // TODO
+    b->flags = VM_BLOCK_PROC | VM_BLOCK_METHOD;
+    b->locals = NULL;
+    b->parent_var_uses = NULL;
+    b->parent_block = NULL;
+    b->dvars_size = 0;
+
+    return b;
+}
+
 static inline VALUE
 rb_vm_block_eval0(rb_vm_block_t *b, int argc, const VALUE *argv)
 {

Modified: MacRuby/branches/experimental/roxor.h
===================================================================
--- MacRuby/branches/experimental/roxor.h	2009-05-12 09:43:57 UTC (rev 1570)
+++ MacRuby/branches/experimental/roxor.h	2009-05-13 05:31:53 UTC (rev 1571)
@@ -22,6 +22,7 @@
 #define VM_BLOCK_PROC	0x0001	// block is a Proc object
 #define VM_BLOCK_LAMBDA 0x0002	// block is a lambda
 #define VM_BLOCK_ACTIVE 0x0004	// block is active (being executed)
+#define VM_BLOCK_METHOD 0x0008	// block is created from Method
 
 typedef struct rb_vm_block {
     VALUE self;
@@ -134,6 +135,7 @@
 }
 
 rb_vm_method_t *rb_vm_get_method(VALUE klass, VALUE obj, ID mid, int scope);
+rb_vm_block_t *rb_vm_create_block_from_method(rb_vm_method_t *method);
 
 static inline rb_vm_block_t *
 rb_proc_get_block(VALUE proc)

Modified: MacRuby/branches/experimental/test_vm/method.rb
===================================================================
--- MacRuby/branches/experimental/test_vm/method.rb	2009-05-12 09:43:57 UTC (rev 1570)
+++ MacRuby/branches/experimental/test_vm/method.rb	2009-05-13 05:31:53 UTC (rev 1571)
@@ -28,3 +28,24 @@
 assert '-5', "def f(a, b, d, g, c=1, e=2, f=3); end; p method(:f).arity"
 assert '-5', "def f(a, b, d, g, *args); end; p method(:f).arity"
 assert '4', "def f(a, b, d, g); end; p method(:f).arity"
+
+assert ":ok", %{
+  def foo; p :ok; end
+  m = method(:foo)
+  def foo; p :nok; end
+  m.call 
+}
+
+assert "42", %{
+  o = 42
+  m = o.method(:description)
+  puts m.call
+}
+
+assert ":ok", %{
+  o = {}
+  k = 'omg'
+  m = o.method(:"setObject:forKey:")
+  m.call(:ok, k)
+  p o[k]
+}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090512/48880742/attachment-0001.html>


More information about the macruby-changes mailing list