<commit_before>=pod

=head1 Opcodes and Runcores

Z<CHP-11>

The smallest executable component is not the compilation unit or even the subroutine,
but is in fact the opcode. Opcodes in PASM, like opcodes in other assembly languages,
are individual instructions that implement low-level operations in Parrot N<In the
world of microprocessors, the word "opcode" typically refers to the numeric identifier
for each instructions. The human-readable word used in the associated assembly language
is called the "mnemonic". An assembler, among other tasks, is responsble for converting
mnemonics into opcodes for execution. In Parrot, instead of referring to an instruction
by different names depending on what form it's in, we just call them all "opcodes">. Of
course the list of things that qualify as "low-level" in Parrot can be pretty advanced
compared to the functionality supplied by regular assembly language opcodes.

Before we talk about opcodes, we have to a little bit of talking about the various
runcores that invoke them.

=head2 Runcores

During execution, the runcore is like the heart of Parrot. The runcore controls calling
the various opcodes with the correct data, and making sure that program flow moves
properly. Some runcores, such as the I<precomputed C goto runcore> are optimized for
speed and don't perform many tasks beyond finding and dispatching opcodes. Other runcores,
such as the I<GC-Debug>, I<debug> and I<profiling> runcores help with typical software
maintenance and analysis tasks. Different runcores, because of the way they are structured,
require the opcodes to be compiled into different forms. Because of this, understanding
opcodes first requires an understanding of the Parrot runcores.

=head3 Types of Runcores

Parrot has multiple runcores. Some are useful for particular maintenance tasks, some are
only available as optimizations in certain compilers, some are intended for general use,
and some are just interesing flights of fancy with no practical benefits.

=over 4

=item*

=item*

=item*

=back

=head2 Writing Opcodes

Writing Opcodes, like writing PMCs, is done in a C-like language which is later
compiled into C code by the X<opcode compiler> opcode compiler. The opcode script
represents a thin overlay on top of ordinary C code: All valid C code is valid
Opcode script. There are a few neat additions that make writing Opcodes easier.

=head3 Opcode Parameters

=head3 Opcode Control Flow

=head2 The Opcode Compiler 

=head2 Opcode Multiple Dispatch

##########################################################################
#                              PSEUDOPOD LEGEND
#
#  Interior Sequences
#  ..................
#  A<>         link anchor (source)
#  B<>         bold text
#  C<>         monospace text
#  E<>         named character
#  F<>         file name
#  G<>         superscript
#  H<>         subscript
#  I<>         italicized text
#  L<>         link to other manpage (see A<>)
#  M<>         firstterm
#  N<>         footnote
#  Q<>         quoted text
#  R<>         replaceable item<commit_msg>[Book] Add a little bit more about opcodes and runcores.<commit_after>=pod

=head1 Opcodes and Runcores

Z<CHP-11>

The smallest executable component is not the compilation unit or even the subroutine,
but is in fact the opcode. Opcodes in PASM, like opcodes in other assembly languages,
are individual instructions that implement low-level operations in Parrot N<In the
world of microprocessors, the word "opcode" typically refers to the numeric identifier
for each instructions. The human-readable word used in the associated assembly language
is called the "mnemonic". An assembler, among other tasks, is responsble for converting
mnemonics into opcodes for execution. In Parrot, instead of referring to an instruction
by different names depending on what form it's in, we just call them all "opcodes">. Of
course the list of things that qualify as "low-level" in Parrot can be pretty advanced
compared to the functionality supplied by regular assembly language opcodes.

Before we talk about opcodes, we have to a little bit of talking about the various
runcores that invoke them.

=head2 Runcores

During execution, the runcore is like the heart of Parrot. The runcore controls calling
the various opcodes with the correct data, and making sure that program flow moves
properly. Some runcores, such as the I<precomputed C goto runcore> are optimized for
speed and don't perform many tasks beyond finding and dispatching opcodes. Other runcores,
such as the I<GC-Debug>, I<debug> and I<profiling> runcores help with typical software
maintenance and analysis tasks. Different runcores, because of the way they are structured,
require the opcodes to be compiled into different forms. Because of this, understanding
opcodes first requires an understanding of the Parrot runcores.

=head3 Types of Runcores

Parrot has multiple runcores. Some are useful for particular maintenance tasks, some are
only available as optimizations in certain compilers, some are intended for general use,
and some are just interesing flights of fancy with no practical benefits. One runcore that
we've already seen is the debugging runcore which prompts the user for commands between
executing each opcode. Another valuable mainteance runcore is the GC dubug core (which runs a
full sweep of the garbage collector between each opcode). 

=over 4

=item* Slow Core

The slow core is a basic runcore design that treats each opcode as a separate function
at the C level. Each function is called, and returns the address of the next opcode
to be called by the core. The slow core performs bounds checking to ensure that the next
opcode to be called is properly in bounds. Because of this modular approach where opcodes
are treated as separate executable entities many other runcores, especially diagnostic and
maintenance cores are based on this design. 

=item* Fast Core

The fast core is a bare-bones core that doesn't do any of the bounds-checking or context
updating that the slow core does.

=item* Computed Goto Core

I<Computed Goto> is a feature of some C compilers where a label is treated as a piece of
data that can be stored in an array. Each opcode is simply a lable in a very large
function, and the labels are stored in an array. Calling an opcode is as easy as taking
that opcode's number as the index of the label array, and calling the associated label.
Sound complicated? It is a little, especially to C programmers who are not used to these
kinds of features, and who have been taught that the C<goto> keyword is to be avoided.

As was mentioned earlier, not all compilers support computed goto, which means that this
core will not be built on platforms that don't support it.

=item* Precomputed Goto Core

Thought the Computed Goto core was hard enough to understand? Precomputed goto takes the
concept a little further.

=item* Tracing Core

=item* Profiling Core

=item* GC Debug Core

=item* Debug Core

=back

=head2 Opcodes

Opcodes are the smallest logical execution element in Parrot. An individual opcode
corresponds, in an abstract kind of way, with a single machine code instruction
for a particular hardware processor architecture. The difference is that Parrot's
opcodes can perform some very complex tasks. Also, Parrot's opcodes can be dynamically
loaded in from a special library file called a I<dynop library>. We'll talk about
dynops a little bit later

=head3 Opcode naming

=head3 Opcode Multiple Dispatch

=head2 Writing Opcodes

Writing Opcodes, like writing PMCs, is done in a C-like language which is later
compiled into C code by the X<opcode compiler> opcode compiler. The opcode script
represents a thin overlay on top of ordinary C code: All valid C code is valid
Opcode script. There are a few neat additions that make writing Opcodes easier.

=head3 Opcode Parameters

=head3 Opcode Control Flow

=head2 The Opcode Compiler 

=head2 Dynops


##########################################################################
#                              PSEUDOPOD LEGEND
#
#  Interior Sequences
#  ..................
#  A<>         link anchor (source)
#  B<>         bold text
#  C<>         monospace text
#  E<>         named character
#  F<>         file name
#  G<>         superscript
#  H<>         subscript
#  I<>         italicized text
#  L<>         link to other manpage (see A<>)
#  M<>         firstterm
#  N<>         footnote
#  Q<>         quoted text
#  R<>         replaceable item
{'fraction_non_alphanumeric': 0.06202189007885136, 'fraction_numerical': 0.0029422148993762504, 'mean_word_length': 3.8755020080321283, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '783817', 'n_tokens_mistral': 2215, 'n_tokens_neox': 2132, 'n_words': 1246}