PRIMITIVE VALUE vm_rary_new(int len) { VALUE ary = rb_ary_new2(len); RARY(ary)->len = len; return ary; }
PRIMITIVE VALUE vm_rary_new(int argc, VALUE *argv) { VALUE ary = rb_ary_new2(argc); int i; for (i = 0; i < argc; i++) { rary_elt_set(ary, i, argv[i]); } RARY(ary)->len = argc; return ary; }
PRIMITIVE VALUE vm_dispatch(VALUE top, VALUE self, void *sel, void *block, unsigned char opt, int argc, VALUE *argv) { if (opt & DISPATCH_SUPER) { if (sel == 0) { rb_raise(rb_eNoMethodError, "super called outside of method"); } } VALUE buf[100]; if (opt & DISPATCH_SPLAT) { if (argc == 1 && !SPECIAL_CONST_P(argv[1]) && *(VALUE *)argv[1] == rb_cRubyArray) { argc = RARY(argv[1])->len; argv = rary_ptr(argv[1]); } else { VALUE *new_argv = buf; vm_resolve_args(&new_argv, 100, &argc, argv); argv = new_argv; } if (argc == 0) { const char *selname = sel_getName((SEL)sel); const size_t selnamelen = strlen(selname); if (selname[selnamelen - 1] == ':') { // Because // def foo; end; foo(*[]) // creates foo but dispatches foo:. char buf[100]; strncpy(buf, selname, sizeof buf); buf[selnamelen - 1] = '\0'; sel = sel_registerName(buf); } } } void *vm = rb_vm_current_vm(); VALUE klass = vm_class_of(self); return rb_vm_call0(vm, top, self, (Class)klass, (SEL)sel, (rb_vm_block_t *)block, opt, argc, argv); }
PRIMITIVE VALUE vm_yield_args(int argc, unsigned char opt, VALUE *argv) { VALUE buf[100]; if (opt & DISPATCH_SPLAT) { if (argc == 1 && !SPECIAL_CONST_P(argv[1]) && *(VALUE *)argv[1] == rb_cRubyArray) { argc = RARY(argv[1])->len; argv = rary_ptr(argv[1]); } else { VALUE *new_argv = buf; vm_resolve_args(&new_argv, 100, &argc, argv); argv = new_argv; } } void *vm = rb_vm_current_vm(); return rb_vm_yield_args(vm, argc, argv); }