Permalink
Browse files

Symbol#to_proc now generates a Proc that can accept a variable number…

… of arguments

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@4048 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent 4b9b95e commit dfec2d3e208745516b35e161d95ef9431907f4b6 @lrz lrz committed May 8, 2010
Showing with 28 additions and 10 deletions.
  1. +2 −2 symbol.c
  2. +25 −7 vm.cpp
  3. +1 −1 vm.h
View
@@ -557,8 +557,8 @@ rsym_inspect(VALUE sym, SEL sel)
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);
}
View
32 vm.cpp
@@ -3339,27 +3339,45 @@ rb_vm_create_block_from_method(rb_vm_method_t *method)
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;
}
View
2 vm.h
@@ -368,7 +368,7 @@ VALUE rb_proc_alloc_with_block(VALUE klass, rb_vm_block_t *proc);
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 *

0 comments on commit dfec2d3

Please sign in to comment.