Skip to content

Latest commit

 

History

History
72 lines (50 loc) · 2.7 KB

framebuilder.pod

File metadata and controls

72 lines (50 loc) · 2.7 KB

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.