NAME ^

src/pmc/perl6multisub.pmc - Perl 6 MultiSub PMC

DESCRIPTION ^

Subclass of MultiSub that overrides invoke to implement the Perl 6 multiple dispatch algorithm, along with providing various other pieces.

Since we need to store some extra information, we cannot just actually be a ResizablePMCArray, but rather we need to have one.

TODO ^

This is a list of things that I need to deal with/come back and worry about later (it's not a complete todo list for finishing up the PMC itself, just of fixup tasks in what is already done).

Use Perl 6 types when boxing native arguments in the arg list
Make sure we override everything that ResizablePMCArray and its parents would provide us with. Otherwise, we'll just get segfaults 'cus we don't store stuff the way it does.

INTERNAL STRUCTURES ^

We have some structures that we use to keep data around internally.

candidate_info
Represents a candidate. We extract various bits of information about it when we are building the sorted candidate list and store them in here for fast access during a dispatch.*/#include "parrot/oplib/ops.h"typedef struct candidate_info { PMC *sub; /* The sub that is the candidate. */ PMC **types; /* Class or role type constraints for each parameter. */ PMC **constraints; /* Refinement type constraints for each parameter * (if there are many, this will be a junction). */ INTVAL num_types; /* Number of entries in the above two arrays. */ INTVAL min_arity; /* The number of required positonal arguments. */ INTVAL max_arity; /* # of required and optional positional arguments. */ } candidate_info;/*
candidate_graph_node
Represents the produced information about a candidate as well as the graph edges originating from it. The edges array contains pointers to the edges in the graph that we have arrows to.*/typedef struct candidate_graph_node { candidate_info *info; struct candidate_graph_node **edges; INTVAL edges_in; INTVAL edges_out; } candidate_graph_node;/* Some constants for candidate sorter. */ #define EDGE_REMOVAL_TODO -1 #define EDGE_REMOVED -2/* Some constants for the dispatcher. */ #define MMD_ONE_RESULT 0 #define MMD_MANY_RESULTS 1/*

FUNCTIONS ^

These are worker functions used by the methods of the PMC, and not visible from the outside.

static PMC *get_args()
Gets a list of the arguments that are being passed, taking them from the registers and the constants table and flattening any :flat arguments as required. Returns a ResizablePMCArray of them.
static INTVAL is_narrower(PARROT_INTERP, candidate_info *a, candidate_info *b)
Takes two candidates and determines if the first one is narrower than the second. Returns a true value if they are.
static candidate_info** sort_candidiates(PMC *candidates)
Takes a ResizablePMCArray of the candidates, collects information about them and then does a topological sort of them.
static INTVAL has_junctional_args(PARROT_INTERP, PMC *args)
Checks if any of the args are junctional.
static PMC *do_dispatch(PARROT_INTERP, PMC *self, candidate_info **candidates, PMC *proto, PMC *args, int many, int num_candidates, opcode_t *next, MMD_Cache *cache)
Runs the Perl 6 MMD algorithm. If many is set to a true value, returns a ResizablePMCArray of all possible candidates, which may be empty. If many is false, then returns either the one winning unambiguous candidate or throws an error saying that the dispatch failed if there were no candidates or that it was ambiguous if there were tied candidates.
static int assert_invokable(PARROT_INTERP, PMC *value)
Checks if a PMC is invokable; returns a true value if so and a false value if not.

ATTRIBUTES ^

candidates
Unsorted list of all candidates.
candidates_sorted
C array of canididate_info structures. It stores a sequence of candidates length one or greater that are tied, followed by a NULL, followed by the next bunch that are less narrow but tied and so forth. It is terminated by a double NULL.
cache
A multiple dispatch cache, which memorizes the types we were invoked with so we can dispatch more quickly.
proto
The proto that is in effect.

METHODS ^

VTABLE void init()
Allocates the PMC's underlying storage.
VTABLE void destroy()
Frees the memory associated with this PMC's underlying storage.
VTABLE opcode_t invoke()
Does a dispatch to the best candidate with the current arguments, according to the Perl 6 MMD algorithm.
METHOD PMC *find_possible_candidates()
Takes an array of arguments and finds all possible matching candidates.
VTABLE void mark()
Marks the candidate list.
VTABLE void push_pmc(PMC *sub)
Adds a new candidate to the candidate list.
VTABLE INTVAL elements()
Gets the number of candidate on the candidate list.
VTABLE PMC * get_iter()
Get an iterator over the candidates.
VTABLE PMC * get_pmc_keyed_int()
Gets the candidate at index i.
VTABLE PMC * get_pmc_keyed_str()
Converts s to an integer and gets the key at that index.
VTABLE PMC * get_pmc_keyed()
Converts p to an integer and gets the key at that index.
VTABLE PMC * clone()
Makes a copy of this Perl6MultiSub PMC.


parrot