Here's my crazy idea. When you register a callback into PIR from C, you need to pass a few arguments: the interpreter into which to call, the PMC Sub to call, and the C signature of the C function which gets called from C.
I presume that the PIR function will get called through one of the external API calls which need to know the interpreter, the PMC to invoke, and the C signature of the incoming arguments. The callback registry stores this information in a hash (or array) or other registry and... ... looks up a function pointer in a table of precompiled function pointers keyed off of C signatures. These functions call a "return a varargs pointer from my arguments" function, then call the "invoke registered PIR callback" function with the varargs and an identifier. (I'll get to where the identifier comes from in a moment.) Instead of returning that function pointer directly, the registry copies it (we have to know its size somehow, but I think we can guess pretty well) and changes one spot which records its identifier. It's an integer, probably unsigned. Relying on a JIT might make this easier, but I think we can use this scheme with a fair degree of ease. We do need to make sure that the copied functions are on executable and writeable memory pages, but otherwise I think we're fine. Also, no, I never wrote viruses. Why do you ask? -- c