Skip to content

Proc#arity and Proc#parameters for cfunc methods: storing aspec on RProc #6764

@khasinski

Description

@khasinski

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:

  1. 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.
  2. 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.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions