[macruby-changes] [4048] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri May 7 18:30:21 PDT 2010


Revision: 4048
          http://trac.macosforge.org/projects/ruby/changeset/4048
Author:   lsansonetti at apple.com
Date:     2010-05-07 18:30:20 -0700 (Fri, 07 May 2010)
Log Message:
-----------
Symbol#to_proc now generates a Proc that can accept a variable number of arguments

Modified Paths:
--------------
    MacRuby/trunk/symbol.c
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h

Modified: MacRuby/trunk/symbol.c
===================================================================
--- MacRuby/trunk/symbol.c	2010-05-08 00:12:01 UTC (rev 4047)
+++ MacRuby/trunk/symbol.c	2010-05-08 01:30:20 UTC (rev 4048)
@@ -557,8 +557,8 @@
 static VALUE
 rsym_to_proc(VALUE sym, SEL sel)
 {
-    SEL msel = sel_registerName(rb_id2name(SYM2ID(sym)));
-    rb_vm_block_t *b = rb_vm_create_block_calling_sel(msel);
+    ID mid = SYM2ID(sym);
+    rb_vm_block_t *b = rb_vm_create_block_calling_mid(mid);
     return rb_proc_alloc_with_block(rb_cProc, b);
 }
 

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2010-05-08 00:12:01 UTC (rev 4047)
+++ MacRuby/trunk/vm.cpp	2010-05-08 01:30:20 UTC (rev 4048)
@@ -3339,28 +3339,46 @@
 
 static VALUE
 rb_vm_block_call_sel(VALUE rcv, SEL sel, VALUE **dvars, rb_vm_block_t *b,
-	VALUE x)
+	VALUE args)
 {
-    if (x == Qnil) {
+    const VALUE *argv = RARRAY_PTR(args);
+    const long argc = RARRAY_LEN(args);
+    if (argc == 0) {
 	rb_raise(rb_eArgError, "no receiver given");
     }
-    return rb_vm_call(x, (SEL)dvars[0], 0, NULL, false);
+    SEL msel = argc - 1 == 0 ? (SEL)dvars[0] : (SEL)dvars[1];
+    return rb_vm_call(argv[0], msel, argc - 1, &argv[1], false);
 }
 
 extern "C"
 rb_vm_block_t *
-rb_vm_create_block_calling_sel(SEL sel)
+rb_vm_create_block_calling_mid(ID mid)
 {
     rb_vm_block_t *b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t)
-	    + sizeof(VALUE *));
+	    + (2 * sizeof(VALUE *)));
 
     b->klass = 0;
     b->proc = Qnil;
-    b->arity = rb_vm_arity(1);
     b->flags = VM_BLOCK_PROC;
     b->imp = (IMP)rb_vm_block_call_sel;
-    b->dvars[0] = (VALUE *)sel;
 
+    // Arity is -1.
+    b->arity.min = 0;
+    b->arity.max = -1;
+    b->arity.left_req = 0;
+    b->arity.real = 1;
+
+    // Prepare 2 selectors for the dispatcher later. One for 0 arity, one for
+    // 1 or more arity.
+    const char *midstr = rb_id2name(mid);
+    if (midstr[strlen(midstr) - 1] == ':') {
+	rb_raise(rb_eArgError, "invalid method name `%s'", midstr);
+    }
+    char buf[100];
+    snprintf(buf, sizeof buf, "%s:", midstr);
+    b->dvars[0] = (VALUE *)sel_registerName(midstr);
+    b->dvars[1] = (VALUE *)sel_registerName(buf);
+
     return b;
 }
 

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2010-05-08 00:12:01 UTC (rev 4047)
+++ MacRuby/trunk/vm.h	2010-05-08 01:30:20 UTC (rev 4048)
@@ -368,7 +368,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);
-rb_vm_block_t *rb_vm_create_block_calling_sel(SEL sel);
+rb_vm_block_t *rb_vm_create_block_calling_mid(ID mid);
 VALUE rb_vm_make_curry_proc(VALUE proc, VALUE passed, VALUE arity);
 
 static inline rb_vm_block_t *
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100507/499ae5d4/attachment.html>


More information about the macruby-changes mailing list