int rb_proc_arity(VALUE proc) { rb_vm_block_t *b; GetProcPtr(proc, b); return rb_vm_arity_n(b->arity); }
rb_vm_method_t * rb_vm_get_method(VALUE klass, VALUE obj, ID mid, int scope) { SEL sel = 0; IMP imp = NULL; rb_vm_method_node_t *node = NULL; // TODO honor scope if (!rb_vm_lookup_method2((Class)klass, mid, &sel, &imp, &node)) { rb_print_undef(klass, mid, 0); } Class k, oklass = (Class)klass; while ((k = class_getSuperclass(oklass)) != NULL) { if (!rb_vm_lookup_method(k, sel, NULL, NULL)) { break; } oklass = k; } Method method = class_getInstanceMethod((Class)klass, sel); assert(method != NULL); int arity; rb_vm_method_node_t *new_node; if (node == NULL) { arity = rb_method_getNumberOfArguments(method) - 2; new_node = NULL; } else { 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)); } rb_vm_method_t *m = (rb_vm_method_t *)xmalloc(sizeof(rb_vm_method_t)); m->oclass = (VALUE)oklass; m->rclass = klass; GC_WB(&m->recv, obj); m->sel = sel; m->arity = arity; GC_WB(&m->node, new_node); // Let's allocate a static cache here, since a rb_vm_method_t must always // point to the method it was created from. struct mcache *c = (struct mcache *)xmalloc(sizeof(struct mcache)); if (new_node == NULL) { fill_ocache(c, obj, oklass, imp, sel, method, arity); } else { fill_rcache(c, oklass, sel, new_node); } GC_WB(&m->cache, c); return m; }