[macruby-changes] [4097] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu May 13 20:40:41 PDT 2010


Revision: 4097
          http://trac.macosforge.org/projects/ruby/changeset/4097
Author:   lsansonetti at apple.com
Date:     2010-05-13 20:40:36 -0700 (Thu, 13 May 2010)
Log Message:
-----------
fixed #define_method with a Proc to compile a stub with the same arity as the block

Modified Paths:
--------------
    MacRuby/trunk/compiler.cpp
    MacRuby/trunk/dispatcher.cpp
    MacRuby/trunk/eval.c
    MacRuby/trunk/proc.c
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h

Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp	2010-05-14 01:58:28 UTC (rev 4096)
+++ MacRuby/trunk/compiler.cpp	2010-05-14 03:40:36 UTC (rev 4097)
@@ -7576,21 +7576,6 @@
 Function *
 RoxorCompiler::compile_block_caller(rb_vm_block_t *block)
 {
-    // VALUE foo(VALUE rcv, SEL sel, int argc, VALUE *argv)
-    // {
-    //     return rb_vm_block_eval2(block, rcv, sel, argc, argv);
-    // }
-    Function *f = cast<Function>(module->getOrInsertFunction("",
-		RubyObjTy, RubyObjTy, PtrTy, Int32Ty, RubyObjPtrTy,
-		NULL));
-    Function::arg_iterator arg = f->arg_begin();
-    Value *rcv = arg++;
-    Value *sel = arg++;
-    Value *argc = arg++;
-    Value *argv = arg++;
-
-    bb = BasicBlock::Create(context, "EntryBlock", f);
-
     if (blockEvalFunc == NULL) {
 	// VALUE rb_vm_block_eval2(rb_vm_block_t *b, VALUE self, SEL sel,
 	//	int argc, const VALUE *argv)
@@ -7599,6 +7584,60 @@
 		    RubyObjTy, PtrTy, RubyObjTy, PtrTy, Int32Ty, RubyObjPtrTy,
 		    NULL));
     }
+
+    Function *f;
+    Value *rcv;
+    Value *sel;
+    Value *argc;
+    Value *argv;
+
+    const int arity = rb_vm_arity_n(block->arity);
+    if (arity < 0) {
+	// VALUE foo(VALUE rcv, SEL sel, int argc, VALUE *argv)
+	// {
+	//     return rb_vm_block_eval2(block, rcv, sel, argc, argv);
+	// }
+	f = cast<Function>(module->getOrInsertFunction("",
+		    RubyObjTy, RubyObjTy, PtrTy, Int32Ty, RubyObjPtrTy,
+		    NULL));
+	Function::arg_iterator arg = f->arg_begin();
+	rcv = arg++;
+	sel = arg++;
+	argc = arg++;
+	argv = arg++;
+
+	bb = BasicBlock::Create(context, "EntryBlock", f);
+    }
+    else {
+	// VALUE foo(VALUE rcv, SEL sel, VALUE arg1, ...)
+	// {
+	//     VALUE argv[n] = {arg1, ...};
+	//     return rb_vm_block_eval2(block, rcv, sel, n, argv);
+	// }
+	std::vector<const Type *> stub_types;
+	stub_types.push_back(RubyObjTy);
+	stub_types.push_back(PtrTy);
+	for (int i = 0; i < arity; i++) {
+	    stub_types.push_back(RubyObjTy);
+	}
+	FunctionType *ft = FunctionType::get(RubyObjTy, stub_types, false);
+	f = cast<Function>(module->getOrInsertFunction("", ft));
+
+	Function::arg_iterator arg = f->arg_begin();
+	rcv = arg++;
+	sel = arg++;
+	argc = ConstantInt::get(Int32Ty, arity);
+
+	bb = BasicBlock::Create(context, "EntryBlock", f);
+
+	argv = new AllocaInst(RubyObjTy, argc, "", bb);
+	for (int i = 0; i < arity; i++) {
+	    Value *index = ConstantInt::get(Int32Ty, i);
+	    Value *slot = GetElementPtrInst::Create(argv, index, "", bb);
+	    new StoreInst(arg++, slot, "", bb);
+	}
+    }
+
     std::vector<Value *> params;
     params.push_back(compile_const_pointer(block));
     params.push_back(rcv);
@@ -7608,7 +7647,7 @@
 
     Value *retval = compile_protected_call(blockEvalFunc, params);
 
-    ReturnInst::Create(context, retval, bb);
+    ReturnInst::Create(context, retval, bb);	
 
     return f;
 }

Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp	2010-05-14 01:58:28 UTC (rev 4096)
+++ MacRuby/trunk/dispatcher.cpp	2010-05-14 03:40:36 UTC (rev 4097)
@@ -1864,10 +1864,7 @@
 	new_node = NULL;
     }
     else {
-	arity = node->arity.min;
-	if (node->arity.min != node->arity.max) {
-	    arity = -arity - 1;
-	}
+	arity = rb_vm_arity_n(node->arity);
 	new_node = (rb_vm_method_node_t *)xmalloc(sizeof(rb_vm_method_node_t));
 	memcpy(new_node, node, sizeof(rb_vm_method_node_t));
     }

Modified: MacRuby/trunk/eval.c
===================================================================
--- MacRuby/trunk/eval.c	2010-05-14 01:58:28 UTC (rev 4096)
+++ MacRuby/trunk/eval.c	2010-05-14 03:40:36 UTC (rev 4097)
@@ -386,8 +386,9 @@
 	mesg = rb_exc_new2(rb_eRuntimeError, "");
 	break;
       case 1:
-	if (NIL_P(argv[0]))
+	if (NIL_P(argv[0])) {
 	    break;
+	}
 	if (TYPE(argv[0]) == T_STRING) {
 	    mesg = rb_exc_new3(rb_eRuntimeError, argv[0]);
 	    break;

Modified: MacRuby/trunk/proc.c
===================================================================
--- MacRuby/trunk/proc.c	2010-05-14 01:58:28 UTC (rev 4096)
+++ MacRuby/trunk/proc.c	2010-05-14 03:40:36 UTC (rev 4097)
@@ -503,20 +503,15 @@
 static VALUE
 proc_arity(VALUE self, SEL sel)
 {
-    rb_vm_block_t *b;
-    GetProcPtr(self, b);
-
-    int arity = b->arity.min;
-    if (b->arity.min != b->arity.max) {
-	arity = -arity - 1;
-    }
-    return INT2FIX(arity);
+    return INT2FIX(rb_proc_arity(self));
 }
 
 int
 rb_proc_arity(VALUE proc)
 {
-    return FIX2INT(proc_arity(proc, 0));
+    rb_vm_block_t *b;
+    GetProcPtr(proc, b);
+    return rb_vm_arity_n(b->arity);
 }
 
 #if 0
@@ -974,7 +969,6 @@
 	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
     }
 
-    SEL method_sel = sel_registerName(rb_id2name(id));
     if (rb_obj_is_method(body)) {
 	// TODO
 	abort();
@@ -998,7 +992,8 @@
     else {
 	rb_vm_block_t *proc;
 	GetProcPtr(body, proc);
-	rb_vm_define_method3((Class)mod, method_sel, proc);
+
+	rb_vm_define_method3((Class)mod, id, proc);
     }
 
     return body;

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2010-05-14 01:58:28 UTC (rev 4096)
+++ MacRuby/trunk/vm.cpp	2010-05-14 03:40:36 UTC (rev 4097)
@@ -2676,15 +2676,27 @@
 
 extern "C"
 void
-rb_vm_define_method3(Class klass, SEL sel, rb_vm_block_t *block)
+rb_vm_define_method3(Class klass, ID mid, rb_vm_block_t *block)
 {
     assert(block != NULL);
 
+    SEL sel;
+    const int arity = rb_vm_arity_n(block->arity);
+    const char *mid_name = rb_id2name(mid);
+    if (arity > 0) {
+	char buf[100];
+	snprintf(buf, sizeof buf, "%s:", mid_name);
+	sel = sel_registerName(buf);
+    }
+    else {
+	sel = sel_registerName(mid_name);
+    }
+
     Function *func = RoxorCompiler::shared->compile_block_caller(block);
     IMP imp = GET_CORE()->compile(func);
-    NODE *body = rb_vm_cfunc_node_from_imp(klass, -1, imp, 0);
-    rb_objc_retain(body);
-    rb_objc_retain(block);
+    NODE *body = rb_vm_cfunc_node_from_imp(klass, arity, imp, 0);
+    GC_RETAIN(body);
+    GC_RETAIN(block);
 
     rb_vm_define_method(klass, sel, imp, body, false);
 }

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2010-05-14 01:58:28 UTC (rev 4096)
+++ MacRuby/trunk/vm.h	2010-05-14 03:40:36 UTC (rev 4097)
@@ -175,6 +175,16 @@
     return arity;
 }
 
+static inline int
+rb_vm_arity_n(rb_vm_arity_t arity)
+{
+    int n = arity.min;
+    if (arity.min != arity.max) {
+	n = -n - 1;
+    }
+    return n;
+}
+
 static inline rb_vm_arity_t
 rb_vm_node_arity(NODE *node)
 {
@@ -293,7 +303,7 @@
 	NODE *node, bool direct);
 rb_vm_method_node_t *rb_vm_define_method2(Class klass, SEL sel,
 	rb_vm_method_node_t *node, long flags, bool direct);
-void rb_vm_define_method3(Class klass, SEL sel, rb_vm_block_t *node);
+void rb_vm_define_method3(Class klass, ID mid, rb_vm_block_t *node);
 bool rb_vm_resolve_method(Class klass, SEL sel);
 void *rb_vm_undefined_imp(void *rcv, SEL sel);
 void *rb_vm_removed_imp(void *rcv, SEL sel);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100513/e9806ed0/attachment.html>


More information about the macruby-changes mailing list