[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