Related to #5529 and the TODO comments in src/proc.c:415 and mrbgems/mruby-proc-ext/src/proc.c:186.
Currently mrb_proc_arity() returns -1 and Proc#parameters returns [] for all cfunc-backed Procs, because struct RProc has no field for the argument spec.
The aspec is already stored on mrb_method_t.flags (lower 24 bits) and used by the VM for direct cfunc dispatch (check_argument_count in vm.c). But when a cfunc method gets wrapped in an RProc (e.g. via Method#to_proc), that information is lost. The only thing carried over is MRB_PROC_NOARG for the zero-args case.
I looked into possible approaches and each has a tradeoff:
- Expand
RProc with an aspec field -- simple but increases memory for all Procs, and the struct currently fits in the 5-word object size limit.
- Compress aspec into remaining
flags bits -- only 13 bits are free (20-bit field, bits 7-13 used), not enough for the full 24-bit aspec. Could work for a subset (e.g. req + rest + opt) but would be lossy.
- Look up method table at runtime -- would need to know which class/method the Proc belongs to, which isn't always available from just an
RProc*.
Would any of these directions be acceptable, or is there a preferred approach? Happy to work on a PR if there's a green light on a direction.
Related to #5529 and the TODO comments in
src/proc.c:415andmrbgems/mruby-proc-ext/src/proc.c:186.Currently
mrb_proc_arity()returns -1 andProc#parametersreturns[]for all cfunc-backed Procs, becausestruct RProchas no field for the argument spec.The aspec is already stored on
mrb_method_t.flags(lower 24 bits) and used by the VM for direct cfunc dispatch (check_argument_countin vm.c). But when a cfunc method gets wrapped in anRProc(e.g. viaMethod#to_proc), that information is lost. The only thing carried over isMRB_PROC_NOARGfor the zero-args case.I looked into possible approaches and each has a tradeoff:
RProcwith an aspec field -- simple but increases memory for all Procs, and the struct currently fits in the 5-word object size limit.flagsbits -- only 13 bits are free (20-bit field, bits 7-13 used), not enough for the full 24-bit aspec. Could work for a subset (e.g. req + rest + opt) but would be lossy.RProc*.Would any of these directions be acceptable, or is there a preferred approach? Happy to work on a PR if there's a green light on a direction.