src/multidispatch.c - Multimethod dispatch for binary opcode functions
This system is set up to handle type-based dispatching for binary (two argument) functions.
This includes,
though isn't necessarily limited to,
binary operators such as addition or subtraction.
The MMD system is straightforward,
and currently must be explicitly invoked,
for example by a vtable function.
(We reserve the right to use MMD in all circumstances,
but currently do not).
For the purposes of the API,
each MMD-able function is assigned a unique number which is used to find the correct function table.
This is the func_num
parameter in the following functions.
While Parrot isn't restricted to a predefined set of functions,
it does set things up so that all the binary vtable functions have a MMD table preinstalled for them,
with default behaviour.
binop_mmd_funcs->x
and ->y
are table sizes not highest type in table.
static void dump_mmd
- RT #48260: Not yet documented!!!
funcptr_t get_mmd_dispatch_type
- RT #48260: Not yet documented!!!
PMC *Parrot_mmd_find_multi_from_sig_obj
- Collect a list of possible candidates for a given sub name and call signature.
Rank the possible candidates by Manhattan Distance,
and return the best matching candidate.
The candidate list is cached in the CallSignature object,
to allow for iterating through it.
- Currently this only looks in the global "MULTI" namespace.
static PMC *Parrot_mmd_deref
- If
value
is a reference-like PMC,
dereference it so we can make an MMD call on the 'real' value.
- {{**DEPRECATE**}}
static void Parrot_mmd_ensure_writable
- Make sure
pmc
is writable enough for function
.
- {{**DEPRECATE**}}
PMC *Parrot_build_sig_object_from_varargs
- Take a varargs list,
and convert it into a CallSignature PMC.
The CallSignature stores the original short signature string,
and an array of integer types to pass on to the multiple dispatch search.
void Parrot_mmd_multi_dispatch_from_c_args
- Dispatch to a MultiSub,
from a variable-sized list of C arguments.
The multiple dispatch system will figure out which sub should be called based on the types of the arguments passed in.
- Return arguments must be passed as a reference to the PMC,
string,
number,
or integer,
so the result can be set.
void mmd_add_function
- Add a new binary MMD function to the list of functions the MMD system knows of.
func_num
is the number of the new function.
function
is ignored.
- RT #45941 change this to a MMD register interface that takes a function *name*.
- {{**DEPRECATE**}}
static void mmd_expand_x
- Expands the function table in the X dimension to include
new_x
.
- {{**DEPRECATE**}}
static void mmd_expand_y
- Expands the function table in the Y direction.
- {{**DEPRECATE**}}
void mmd_add_by_class
- Add a function to the MMD table by class name,
rather than class number.
Handles the case where the named class isn't loaded yet.
- Adds a new MMD function
funcptr
to the func_num
function table that will be invoked when the left parameter is of class left_class
and the right parameter is of class right_class
.
Both classes are STRING *
s that hold the PMC class names for the left and right sides.
If either class isn't yet loaded,
Parrot will cache the information such that the function will be installed if at some point in the future both classes are available.
- Currently this is done by just assigning class numbers to the classes,
which the classes will pick up and use if they're later loaded,
but we may later put the functions into a deferred table that we scan when PMC classes are loaded.
Either way,
the function will be guaranteed to be installed when it's needed.
- The function table must exist,
but if it is too small,
it will automatically be expanded.
- {{**DEPRECATE**}}
void Parrot_mmd_register
- Register a function
funcptr
for MMD function table func_num
for classes left_type
and right_type
.
The left and right types are INTVAL
s that represent the class ID numbers.
- The function table must exist,
but if it is too small,
it will automatically be expanded.
- Adding a new function to the table can be interestingly non-trivial,
so we get to be tricky.
- If the left or right types are larger than anything we've seen so far,
it means that we have to expand the table.
Making Y larger is simple -- just realloc with some more rows.
Making X larger is less simple.
In either case,
we punt to other functions.
- RT #45943 - Currently the MMD system doesn't handle inheritance and best match searching,
as it assumes that all PMC types have no parent type.
This can be considered a bug,
and will be resolved at some point in the future.
- {{**DEPRECATE**}}
void Parrot_mmd_register_sub
- RT #48260: Not yet documented!!!
- {{**DEPRECATE**}}
void mmd_destroy
- Frees all the memory allocated used the MMD subsystem.
- {{**DEPRECATE**}}
PMC *Parrot_mmd_find_multi_from_long_sig
- Find the best candidate multi for a given sub name and signature.
The signature is a string containing a comma-delimited list of type names.
- Currently only searches the global MULTI namespace.
PMC *Parrot_MMD_search_default_infix
- RT #48260: Not yet documented!!!
- {{**DEPRECATE**}}
PMC *Parrot_mmd_sort_manhattan_by_sig_pmc
- Given an array PMC (usually a MultiSub) and a CallSignature PMC sort the mmd candidates by their manhattan distance to the signature args.
PMC *Parrot_mmd_sort_manhattan
- Given an array PMC (usually a MultiSub) sort the mmd candidates by their manhatten distance to the current args.
static PMC *mmd_arg_tuple_inline
- Return a list of argument types.
PMC arguments are specified as function arguments.
- {{**DEPRECATE** Not actually called anywhere.}}
static PMC *Parrot_mmd_arg_tuple_func
- Return a list of argument types.
PMC arguments are taken from registers according to calling conventions.
static PMC *Parrot_mmd_search_default
- Default implementation of MMD search.
Search scopes for candidates,
walk the class hierarchy,
sort all candidates by their Manhattan distance,
and return result
- {{**DEPRECATE??
**}}
static void Parrot_mmd_search_classes
- Search all the classes in all MultiSubs of the candidates
cl
and return a list of all candidates.
start_at_parent
is 0 to start at the class itself or 1 to search from the first parent class.
static INTVAL distance_cmp
- RT #48260: Not yet documented!!!
static PMC *mmd_build_type_tuple_from_type_list
- Construct a FixedIntegerArray of type numbers from an array of type names.
Used for multiple dispatch.
static PMC *mmd_build_type_tuple_from_long_sig
- Construct a FixedIntegerArray of type numbers from a comma-delimited string of type names.
Used for multiple dispatch.
static PMC *mmd_cvt_to_types
- RT #48260: Not yet documented!!!
- {{**DEPRECATE**}}
static UINTVAL mmd_distance
- Create Manhattan Distance of sub
pmc
against given argument types.
0xffff is the maximum distance
static void Parrot_mmd_sort_candidates
- Sort the candidate list
cl
by Manhattan Distance
static PMC *Parrot_mmd_search_scopes
- Search all scopes for MMD candidates matching the arguments given in
arg_tuple
.
static int mmd_maybe_candidate
- If the candidate
pmc
is a Sub PMC,
push it on the candidate list and return TRUE to stop further search.
- If the candidate is a MultiSub remember all matching Subs and return FALSE to continue searching outer scopes.
static int mmd_search_local
- Search the current package namespace for matching candidates.
Return TRUE if the MMD search should stop.
static void mmd_search_by_sig_obj
- Search the namespace of the first argument to the sub call for matching candidates.
static void mmd_search_global
- Search the builtin namespace for matching candidates.
static void mmd_add_multi_global
- Create a MultiSub,
or add a variant to an existing MultiSub.
The MultiSub is stored in the global MULTI namespace.
static void mmd_add_multi_to_namespace
- Create a MultiSub,
or add a variant to an existing MultiSub.
The MultiSub is added as a method to a class.
void Parrot_mmd_add_multi_from_long_sig
- Create a MultiSub,
or add a variant to an existing MultiSub.
The MultiSub is stored in the global MULTI namespace.
void Parrot_mmd_add_multi_from_c_args
- Create a MultiSub,
or add a variant to an existing MultiSub.
The MultiSub is stored in the specified namespace.
void Parrot_mmd_add_multi_list_from_c_args
- Create a collection of multiple dispatch subs from a C structure of information.
Iterate through the list of details passed in.
For each entry create a MultiSub or add a variant to an existing MultiSub.
MultiSubs are created in the global 'MULTI' namespace in the Parrot HLL.
- Typically used to create all the multiple dispatch routines declared in a PMC from the PMC's class initialization function.
void Parrot_mmd_rebuild_table
- Rebuild the static MMD_table for the given class type and MMD function number.
If
type
is negative all classes are rebuilt.
If func_nr
is negative all MMD functions are rebuilt.
- {{**DEPRECATE**}}
include/parrot/multidispatch.h,
http://svn.perl.org/perl6/doc/trunk/design/apo/A12.pod,
http://svn.perl.org/perl6/doc/trunk/design/syn/S12.pod