NAME
src/nci/framebuilder.pod - Parrot Native Call Frame Builder API
DESCRIPTION
Parrot's frame builder is fully pluggable at runtime. That is to say, a new implementation of the frame builder can be installed at any time.
REGISTRATION
Parrot has 2 slots for the frame builder function - a callback PMC and a user data PMC. The callback PMC is expected to return a valid nci_fb_func_t
native function from its get_pointer
vtable.
The callback for a framebuilder should be registerd in parrot's iglobals
array under NCI_FB_CB
. The user data is likewise registered in iglobals
under NCI_FB_UD
.
nci_fb_func_t
nci_fb_func_t
functions receive an interpreter, the registered frame builder user data, and a signature string. They are expected to produce a thunk PMC, and throw an exception or return NULL
on failure. IMPORTANT: frame builders should not parse the signature string themselves but delegate to Parrot_nci_parse_signature
to ensure consistency between implementations.
Thunk PMCs
Thunk PMCs, produced by the frame builder callback, are expected to return a valid nci_thunk_t
native function from their get_pointer
vtables.
nci_thunk_t
functions receive an interpreter, an NCI PMC, and a thunk PMC. They are expected to unpack Parrot's PCC arguments and pass them to the native function pointer in the NCI PMC using the appropriate native function calling conventions and to do the reverse with return values. The exact details of what operations to perform are specified in the signature supplied to the frame builder when the thunk is created.
The Thunk Cache
Thunks are generated lazily on demand and cached. Generally, only one thunk will exist for a given NCI signature. The cache is held in iglobals
under NCI_FUNCS
. This cache can be operated on directly, for example, clearing the cache is possible by running the following PIR code:
.include 'iglobals.pasm'
.sub 'clear-nci-cache'
$P0 = getinterp
$P0 = $P0[.IGLOBALS_NCI_FUNCS]
$P1 = iter $P0
loop:
unless $P1 goto end_loop
$S0 = shift $P1
delete $P0[$S0]
goto loop
end_loop:
.end
Note however, that this will not remove thunks from NCI PMCs which have already been invoked (these cache their Thunk PMC locally).
Another use of direct manipulation of the NCI_FUNCS
cache is nci thunk dynext libraries, generated by nci_thunk_gen
, which add additional statically compiled thunks to parrot at runtime.
WARNING
The frame builder API is currently in a state of flux. Expected improvements are to isolate frame builders further from the signature strings and also to reduce the C-bias in the API.