chromatic wrote:
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...
Replace "callback registry" with "concurrency scheduler" and we're on
the same page.
.. 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.
I have doubts about how stable/cross-platform compatible any solution
that involves rewriting parts of a function pointer in memory will be.
It's likely to cause problems on exactly the same platforms that have
trouble with the JIT solution. Between the two, the JIT solution seems
preferable. But, feel free to prototype it.
Also, no, I never wrote viruses. Why do you ask?
Stack smasher,
Allison