# Dispatchers available in Rakudo on MoarVM

Recommended reading to understand what dispatchers are and why they exist:
- [Towards a new general dispatch mechanism in MoarVM](https://6guts.wordpress.com/2021/03/15/towards-a-new-general-dispatch-mechanism-in-moarvm/)
- [Raku multiple dispatch with the new MoarVM dispatcher](https://6guts.wordpress.com/2021/04/15/raku-multiple-dispatch-with-the-new-moarvm-dispatcher/)
- [The new MoarVM dispatch mechanism is here!](https://6guts.wordpress.com/2021/09/29/the-new-moarvm-dispatch-mechanism-is-here/)

## MoarVM

Dispatchers provided by MoarVM.

---

### all-thread-bt
```
nqp::syscall("all-thread-bt");    # continues
nqp::syscall("all-thread-bt",1);  # exits
```
Produces a backtrace of *all* threads on STDERR.  If 1 is specified
as an additional argument, the program will immediately exit after
producing the backtrace.

### async-unix-connect
```
nqp::syscall('async-unix-connect',queue,code,path,class);
```
Establish an asychronous connection for the given queue (an instantiated
object with `ConcBlockingQueue` REPR, a `Callable` taking 6 positional
arguments, the path for which to open the socket, and a type object
having the `AsyncTask` REPR.

The 6 positional arguments of the `Callable` should be:
- socket
- error
- peer-host
- peer-port
- socket-host
- socket-post

The `Callable` is expected to process the given information in the
appropriate way, e.g. by creating an `IO::Socket::Async` object if
no error was encountered.

### async-unix-listen
```
nqp::syscall('async-unix-connect',queue,code,path,backlog,class);
```
The listening equivalent of `async-unix-connect`.  It takes an
additional integer value `backlog` to indicate the size of the
backlog queue of the listening socket.

The `Callable` is expected to set up a tap for any incoming
connection.

### boot-code
```
nqp::dispatch('boot-code', $vmhandle, …);
```
Take the first argument, which must be a VM bytecode handle, and run that
bytecode, passing the rest of the arguments as its parameters; evaluate to
the return value of the bytecode.

### boot-code-constant
```
nqp::dispatch('boot-code-constant', $vmhandle, …);
```
Take the first argument, which must be a VM bytecode handle, and run that
bytecode, passing the rest of the arguments as its parameters; evaluate to
the return value of the bytecode.  Treat the VM bytecode handle as
immutable, thus providing the optimizer with options.

### boot-constant
```
nqp::dispatch('boot-constant', $value, …);
```
Take the first argument and produce it as the result, but also treat it as
a constant value that will always be produced (thus meaning the optimizer
could consider any pure code used to calculate the value as dead).

Ignores all other arguments: this allows calls to this dispatcher to be
using an existing capture by just inserting a value as the first argument,
thus removing the need to remove any superfluous arguments.

### boot-resume
```
nqp::dispatch('boot-resume');
```
Resume the topmost ongoing dispatch.

### boot-syscall
```
nqp::dispatch('boot-syscall', $name, …);
nqp::syscall($name, …);                   # same, using shortcut NQP op
```
Treat the first argument as the name of a VM-provided built-in operation
(or operation added later with `'dispatcher-register'`) and call it,
providing the remaining arguments as its parameters

### boot-value
```
nqp::dispatch('boot-value', $value, …);
```
Take the first argument and use it as the result (the identity function,
except discarding any further arguments).

### can-unbox-to-int
```
nqp::syscall("can-unbox-to-int",42.Int);  # 1
nqp::syscall("can-unbox-to-int",42.Str);  # 0
```
Takes the argument (a non-native object) and returns non-zero if it can be
unboxed to a native integer, and 0 otherwise.

### can-unbox-to-num
```
nqp::syscall("can-unbox-to-num",42.Num);  # 2
nqp::syscall("can-unbox-to-num",42.Str);  # 0
```
Takes the argument (a non-native object) and returns non-zero if it can be
unboxed to a native num, and 0 otherwise.

### can-unbox-to-str
```
nqp::syscall("can-unbox-to-str",42.Int);  # 0
nqp::syscall("can-unbox-to-str",42.Str);  # 4
```
Takes the argument (a non-native object) and returns non-zero if it can be
unboxed to a native integer, and 0 otherwise.

### capture-arg-prim-spec
```
my $primspec := nqp::syscall("capture-arg-prim-spec",$capture,$index);
```
Takes the first argument (made with nqp::savecapture) and returns the
primspec value indicated by the second argument.  Valid values are:
- 0 a non-native value
- 1 native integer (int)
- 2 native floating point (num)
- 3 native string (str)
- 10 native unsigned integer (uint)

### capture-arg-value
```
nqp::syscall("capture-arg-value",$capture,$index);
```
Takes the first argument (made with nqp::savecapture) and returns the
value of the positional argument of the capture indicated by the
second argument.

### capture-is-literal-arg
```
nqp::syscall("capture-is-literal-arg",$capture);
```
Takes the argument (made with nqp::savecapture) and returns non-zero if it
consists of a single literal argument, and 0 otherwise.

### capture-named-args
```
my $nameds := nqp::syscall("capture-named-args",$capture);
```
Takes the argument (made with nqp::savecapture) and returns an `nqp::hash`
with the named arguments of the capture.

### capture-names-list
```
my $names := nqp::syscall("capture-names-list",$capture);
```
Takes the argument (made with nqp::savecapture) and returns an `nqp::list`
with the names of the named arguments of the capture.

### capture-num-args
```
my $count := nqp::syscall("capture-num-args",$capture);
```
Takes the argument (made with nqp::savecapture) and returns an integer
with the number of positional arguments of the capture.

### capture-pos-args
```
my $args := nqp::syscall("capture-pos-args",$capture);
```
Takes the argument (made with nqp::savecapture) and returns an `nqp::list`
with the positional arguments of the capture.

### code-bytecode-size
```
nqp::syscall("code-bytecode-size",$mvmcode);
```
Takes the argument (a low-level MoarVM code object) and returns the size
of the bytecode of that code object in bytes.

### code-is-stub
```
nqp::syscall("code-is-stub",$mvmcode);
```
Takes the argument (a low-level MoarVM code object) and returns non-zero if
it it is a stub, and 0 otherwise.

### Notes on dispatcher- calls

The `dispatcher-` prefix means that it's part of specifying the dispatch
program.  So you're not only getting a return value, but the dispatch
recording has tracked the operation.  For instance, in case of these calls
taking and returning a capture, it also internally builds up a tree of
relationships between the various captures.  And so knows what they are
made up of.

### dispatcher-delegate
```
nqp::dispatch('boot-syscall', 'dispatcher-delegate', $name, …);
nqp::delegate($name, …);              # same, using shortcut NQP op
```
Delegate control to the given dispatcher by name (either pre-defined, or
user-defined) and pass any given additional arguments to it.

### dispatcher-do-not-install
```
nqp::syscall("dispatcher-do-not-install");
```
Marks the current dispatch program as to not be installed upon completion.
Returns VMNull.

### dispatcher-drop-arg
```
nqp::syscall("dispatcher-drop-arg", $capture, int $index);
```
Takes the specified capture and returns a capture with the positional
argument at the given $index removed.

### dispatcher-drop-n-args
```
nqp::syscall("dispatcher-drop-n-args", $capture, int $index, int $count);
```
Takes the specified capture and returns a capture with the $count positional
argument at the given $index removed.

### dispatcher-get-resume-init-args
```
nqp::syscall("dispatcher-get-resume-init-args");
```
Returns the capture that was previously saved with
`nqp::syscall("dispatcher-set-resume-init-args", $capture)`.

### dispatcher-get-resume-state
```
nqp::syscall("dispatcher-get-resume-state");
```
Returns the resume state that was previously saved with
`nqp::syscall("dispatcher-set-resume-state", $state)` or 
`nqp::syscall("dispatcher-set-resume-state-literal", $state)`.

### dispatcher-guard-concreteness
```
nqp::syscall("dispatcher-guard-concreteness", $tracker);
nqp::guard('concreteness", $tracker);
```
Record a guard for the concreteness of the given $tracker in the current
dispatch program.  Returns the given $tracker.

### dispatcher-guard-literal
```
nqp::syscall("dispatcher-guard-literal", $tracker);
nqp::guard("literal", $tracker);
```
Record a guard for the given $tracker in the current dispatch program on
whether the tracked objects is a literal or not.  Returns the given $tracker.

### dispatcher-guard-type
```
nqp::syscall("dispatcher-guard-type", $tracker);
nqp::guard("type", $tracker);
```
Record a guard for the type of the given $tracker in the current dispatch
program.  Returns the given $tracker.

### dispatcher-index-lookup-table
```
nqp::syscall("dispatcher-index-lookup-table", %lookup, $tracker);
```
Adds a (mega-morphic) %lookup hash table to the current dispatch program,
tracked by the given tracker.

### dispatcher-index-tracked-lookup-table
```
nqp::syscall("dispatcher-index-tracked-lookup-table", $tracked-lookup, $tracker);
```
Adds a (mega-morphic) tracked lookup hash table to the current dispatch
program, tracked by the given tracker.

### dispatcher-inline-cache-size
```
nqp::syscall("dispatcher-inline-cache-size");
```
Returns a native integer with the number of entries that are being held in
the inline cache.

### dispatcher-insert-arg
```
nqp::syscall("dispatcher-insert-arg", $capture, int $index, $value);
```
Returns a capture based on the given $capture, but with the $value (regardless
of being a native type or not) inserted at position $index.

### dispatcher-insert-arg-literal-int
```
nqp::syscall("dispatcher-insert-arg-literal-int", $capture, int $index, int $value);
```
Returns a capture based on the given $capture, but with a native integer
$value inserted at position $index.

### dispatcher-insert-arg-literal-num
```
nqp::syscall("dispatcher-insert-arg-literal-num", $capture, int $index, num $value);
```
Returns a capture based on the given $capture, but with a native num
$value inserted at position $index.

### dispatcher-insert-arg-literal-obj
```
nqp::syscall("dispatcher-insert-arg-literal-obj", $capture, int $index, $object);
```
Returns a capture based on the given $capture, but with an object $object
inserted at position $index.

### dispatcher-insert-arg-literal-str
```
nqp::syscall("dispatcher-insert-arg-literal-str", $capture, int $index, str $value);
```
Returns a capture based on the given $capture, but with a native string
$value inserted at position $index.

### dispatcher-is-arg-literal
```
nqp::syscall("dispatcher-is-arg-literal", $capture, int $index);
```
Returns 1 if the argument at position $index in the given $capture, is a
literal value.  0 if not.

### dispatcher-next-resumption
```
nqp::syscall("dispatcher-next-resumption");
nqp::syscall("dispatcher-next-resumption", $capture);
```
Returns 1 if there is a next resumption for the current dispatcher, optionally
for the given $capture.  0 if not.

### dispatcher-register
```
nqp::dispatch('boot-syscall', 'dispatcher-register', $name, -> $capture {
    …
});
nqp::register($name, -> $capture {    # same, using shortcut NQP op
    …
});
```
Register a dispatcher.  Takes a name for the dispatcher along with a closure,
which will be called each time we need to handle the dispatch (the
"dispatch callback"). It receives a single argument, which is a capture of
arguments (see
[Captures](https://github.com/Raku/nqp/blob/main/docs/ops.markdown#captures)).

### dispatcher-replace-arg
```
nqp::syscall("dispatcher-replace-arg", $capture, int $index, $value);
```
Returns a capture based on the given $capture, but with the positional
argument at position $index replaced by $value (regardless of being a
native type or not).

### dispatcher-replace-arg-literal-obj
```
nqp::syscall("dispatcher-replace-arg-literal-obj", $capture, int $index, $object);
```
Returns a capture based on the given $capture, but with the positional
argument at position $index replaced by $object.

### dispatcher-resume-after-bind
```
nqp::syscall("dispatcher-resume-after-bind", int $success, int $failure);
```
Mark the current dispatch program to resume after a successful bind with the
given $success kind of dispatch, otherwise with the $failure kind of dispatch.
(both are nqp::const::DISP_xxx values).

### dispatcher-resume-on-bind-failure
```
nqp::syscall("dispatcher-resume-on-bind-failure", int $kind);
```
Mark the current dispatch program to resume after a unsuccessful bind with
the given kind of dispatch (an nqp::const::DISP_xxx value).

### dispatcher-set-resume-init-args
```
nqp::syscall("dispatcher-set-resume-init-args", $capture);
```
Set the capture to be returned with
`nqp::syscall("dispatcher-get-resume-init-args")`.

### dispatcher-set-resume-state
```
nqp::syscall("dispatcher-set-resume-state", $state);
```
Set the resume $state that to be returned by
`nqp::syscall("dispatcher-get-resume-state")`.

### dispatcher-set-resume-state-literal
```
nqp::syscall("dispatcher-set-resume-state-literal", $state);
```
Set the resume $state that to be returned by
`nqp::syscall("dispatcher-get-resume-state")`.  This is usually used to mark
the dispatch as exhausted.

### dispatcher-track-arg
```
nqp::syscall("dispatcher-track-arg", $capture, int $index);
nqp::track("arg", $capture, int $index);
```
Returns a tracker object for the positional argument in the given $capture
at the given $index.

### dispatcher-track-attr
```
nqp::syscall("dispatcher-track-attr", $tracker, $type, $name);
nqp::track("attr", $tracker, $type, $name);
```
Returns a tracker object for the attribute in the object of the given
$tracker object for the given $type and $name.

### dispatcher-track-how
```
nqp::syscall("dispatcher-track-how", $tracker);
nqp::track("how", $tracker);
```
Returns a tracker object for the HOW of the object of the given $tracker
object.

### dispatcher-track-resume-state
```
nqp::syscall("dispatcher-track-resume-state");
nqp::track("resume-state");
```
Returns a tracker object for the current resume state as set with
`nqp::syscall("dispatcher-set-resume-state", $state)`.

### dispatcher-track-unbox-int
```
nqp::syscall("dispatcher-track-unbox-int", $tracker);
nqp::track("unbox-int", $tracker);
```
Returns a tracker object for the unboxed integer for the given tracker of a
a boxed integer.

### dispatcher-track-unbox-num
```
nqp::syscall("dispatcher-track-unbox-num", $tracker);
nqp::track("unbox-num", $tracker);
```
Returns a tracker object for the unboxed num for the given tracker of a
a boxed num.

### dispatcher-track-unbox-str
```
nqp::syscall("dispatcher-track-unbox-str", $tracker);
nqp::track("unbox-str", $tracker);
```
Returns a tracker object for the unboxed string for the given tracker of a
a boxed string.

### file-stat
```
my $stat  := nqp::syscall("file-stat",$path,0);  # stat
my $lstat := nqp::syscall("file-stat",$path,1);  # lstat
```
Takes a native string value containing an absolute path, and an integer
value and returns a `BOOTStat` object that can be used an an argument
to a "stat-flags" syscall.

The integer value indicates whether symbolic links should be followed
(0) or whether information about any symbolic link itself should be
returned (1).

### has-type-check-cache
```
nqp::syscall("has-type-check-cache", $object);
```
Takes the argument (a HLL object) and returns non-zero if the class of the
object has a cache for type checking, and 0 if not.

### handle-open-mode
```
my $open = nqp::syscall("handle-open-mode",$PIO);
```
Takes a native descriptor value, and returns an integer value with one
of the following meanings, defined by the `nqp::const::OPEN_MODE_xx`
constants:
- nqp::const::OPEN_MODE_RO
- nqp::const::OPEN_MODE_WO
- nqp::const::OPEN_MODE_RW

### is-debugserver-running
```
nqp::syscall("is-debugserver-running");
```
Returns an integer value with the following meaning:
- 0 debugserver has *not* been activated
- 1 debugserver port is listening, but no connection made
- 2 debugserver has been activated

### lang-call
```
nqp::delegate("lang-call", $capture);
```
Call the code given by the first argument in the $capture, and pass any other
arguments to that code.

### lang-meth-call
```
nqp::delegate("lang-meth-call", $capture);
```
Call the method given of which the name is given by the second argument in
the $capture, on the invocant in the first argument of the capture, and pass
any other arguments to that method.

### lang-meth-not-found
```
nqp::delegate("lang-meth-not-found", $capture);
```
Delegate as if a method was not found.

### set-cur-hll-config-key
```
nqp::syscall("set-cur-hll-config-key", $key, $value);
```
Takes two arguments: a string key and a value, and sets that in the
configuration information of the current HLL language.  Returns VMNull.

### stat-flags
```
say "exists" if nqp::syscall("stat-flags",$stat,nqp::const::STAT_EXISTS);
```
Takes a `BOOTStat` object (returned by `nqp::syscall("file-stat",...)`)
and returns various types of information about it dependinding on the
second (integer) argument, which is usually specified with one of the
`nqp::const::STAT_xxx` constants:
- nqp::const::STAT_EXISTS
- nqp::const::STAT_FILESIZE
- nqp::const::STAT_ISDIR
- nqp::const::STAT_ISREG
- nqp::const::STAT_ISDEV
- nqp::const::STAT_ISLNK
- nqp::const::STAT_GID
- nqp::const::STAT_UID
- nqp::const::STAT_PLATFORM_DEV
- nqp::const::STAT_PLATFORM_INODE
- nqp::const::STAT_PLATFORM_MODE
- nqp::const::STAT_PLATFORM_NLINKS
- nqp::const::STAT_PLATFORM_DEV
- nqp::const::STAT_PLATFORM_BLOCKSIZE
- nqp::const::STAT_PLATFORM_BLOCKS

### stat-is-executable
```
say "executable" if nqp::syscall("stat-is-executable",$stat);
```
Takes a `BOOTStat` object (returned by `nqp::syscall("file-stat",...)`)
and returns 1 if the path is executable, else 0.

### stat-is-readable
```
say "readable" if nqp::syscall("stat-is-readable",$stat);
```
Takes a `BOOTStat` object (returned by `nqp::syscall("file-stat",...)`)
and returns 1 if the path is readable, else 0.

### stat-is-writable
```
say "writable" if nqp::syscall("stat-is-writable",$stat);
```
Takes a `BOOTStat` object (returned by `nqp::syscall("file-stat",...)`)
and returns 1 if the path is writable, else 0.

### stat-time-nanos
```
say nqp::syscall("stat-time-nanos",$stat,nqp::const::STAT_xxxTIME);
```
Takes a `BOOTStat` object (returned by `nqp::syscall("file-stat",...)`)
and returns an integer value in nano seconds, depending on the integer
value of the second argument, usually expressed as one of the constants:
- nqp::const::STAT_CREATETIME
- nqp::const::STAT_ACCESSTIME
- nqp::const::STAT_MODIFYTIME
- nqp::const::STAT_CHANGETIME
- nqp::const::STAT_BACKUPTIME

### type-check-mode-flags
```
nqp::syscall("type-check-mode-flags", $object);
```
Returns the type check mode flags of the given object.  Possible values are:
- 0 no typecheck (?)
- 1 check type using "type_check" method
- 2 check type using "accepts-type" method

---

## Rakudo

These dispatcher are provided by the Rakudo bootstrap.

---

### raku-assign
```
nqp::dispatch("raku-assign", $container, $value);
```
Assigns the given $value to the given $container, and produces the $container.

### raku-bind-assert
```
nqp::dispatch("raku-bind-assert", $value, $deconted, $type);
```
Returns the given $value if the $deconted value type matches against $type.
Otherwise throws.

### raku-boolify
```
nqp::dispatch("raku-boolify", $value);
```
Returns `True` if the given $value is true, else returns `False`.

### raku-call
```
nqp::dispatch("raku-call", $callee, …);
```
Calls the given $callee with the given arguments, and returns the result.
The $callee can be a sub / method / code object.  

### raku-capture-lex
```
nqp::dispatch("raku-capture-lex", $code);
```
Returns a capture of the lexical environment of the given $code object.
Workhorse of `nqp::p6capturelex`.

### raku-capture-lex-callers
```
nqp::dispatch("raku-capture-lex-callers", $code);
```
Returns a capture of the environment of the caller matching the outer of
the given $code object.  Workhorse of `nqp::p6capturelexwhere`.

### raku-class-archetypes
```
nqp::dispatch("raku-class-archetypes", $HOW, $object);
```
Returns a list of archetypes of the given $HOW and $object.

### raku-coercion
```
nqp::dispatch("raku-coercion", $coercion-type, $value);
```
Returns a coerced value for the given $coercion-type and $value.

### raku-find-meth
```
nqp::dispatch("raku-find-meth", $invocant, str $method, int $throw);
```
Returns the `Method` object for the given $invocant and $method name if
it can be found.  If it is not found, the $throw determines whether this
will cause a "method not found" dispatch (if 1) or `nqp::null` (if 0).

### raku-get-code-outer-ctx
```
nqp::dispatch("raku-get-outer-ctx", $code);
```
Returns the context of the outer of the given $code object.  Workhorse of
`nqp::p6getouterctx`.

### raku-hllize
```
nqp::dispatch("raku-hllize", $value);
```
Returns a Raku HLLized version of the given value, if it needs HLLizing..

### raku-is-attr-inited
```
nqp::dispatch("raku-is-attr-inited", $attribute);
```
Returns 1 if the given $attribute is initialized, 0 if not.

### raku-isinvokable
```
nqp::dispatch("raku-isinvokable", $object);
```
Returns 1 if the given $object can be invoked (aka, is a `Code` object).
Returns 0 if not.

### raku-meth-call
```
nqp::dispatch("raku-meth-call", $invocant, str $method, …);
```
Calls the given $method (by name) on the given $invocant with the given
arguments, and return the result.

### raku-meth-call-me-maybe
```
nqp::dispatch("raku-meth-call-me-maybe", $invocant, str $method, …);
```
Calls the given $method (by name) on the given $invocant with the given
arguments if the method can be found, and return the result.  Otherwise
returns `Nil`.

### raku-meth-call-qualified
```
nqp::dispatch("raku-meth-callqualified", $invocant, str $method, $type, …);
```
Calls the given $method (by name) on the given $invocant but starting method
lookup with the given $type, then call that resolved method with the rest of
the arguments, and return the result.

### raku-meth-private
```
nqp::dispatch("raku-meth-private", $invocant, str $method, …);
```
Calls the given private $method (by name) on the given $invocant with the
given arguments, and return the result.

### raku-nativecall
### raku-nativecall-core
### raku-nativecall-deproxy
### raku-resume-error
```
nqp::dispatch("raku-resume-error");
```
Throws an `X::NoDispatcher` error with the name of the calling dispatcher.

### raku-rv-decont
```
nqp::dispatch("raku-rv-decont", $value);
```
Returns the given $value without any container.

### raku-rv-decont-6c
```
nqp::dispatch("raku-rv-decont-6c", $value);
```
Returns the given $value without any container using 6.c semantics, which
implies that any `Proxy` object will **not** be decontainerized.  This was
an error in the 6.c implementation on which some modules in the ecosystem
depend.

### raku-rv-typecheck-generic
```
nqp::dispatch("raku-rv-typecheck", $value, $generic-type);
```
Returns the given $value if the typecheck with the **generic** type-value
is successful: assumes the actual type value can vary due to its
genericness.  Otherwise throw an error.

### raku-rv-typecheck
```
nqp::dispatch("raku-rv-typecheck", $value, $type);
```
Returns the given $value if the typecheck with the type-value is successful
assuming the type at the call-site is a constant.  Otherwise throw an error.

### raku-sink
```
nqp::dispatch("raku-sink", $value);
```
Perform any non-standard sink logic on the potentially containerized value,
or don't do anything otherwise.

### raku-smartmatch
### raku-wrapper-deferral
