Parrot was implemented in C, and to my recollection implemented various iterations of bytecode syntaxes, notably PBC (parrot byte code).
Rakudo Perl 6 developers took the route of developing Perl 6 through an intermediary language NQP, which is a language aimed at making it easy to implement interpreted languages.
Rakudo (the implementation of Perl 6 that run on MoarVM) is implemented in NQP, and started out on Parrot through an implemention of NQP for Parrot.
NQP[1] stands for Not Quite Perl, and shares various features with Perl, but is much more constrained in features as capabilities, making it easier to implement in a VM.
Because it's mostly implemented in NQP, it's fairly easy to port to a new VM, as all you have to do is get NQP running on that VM, and Perl 6 is mostly ported. For example, this is how the Java port happened within a few months of announcement. NQP was implemented, and then 95% of Perl 6 was already working.
When a new VM instead of Parrot was desired, MoarVM was conceived of as a VM to natively run NQP (rather than NQP on top of the native VM bytecode). Porting Rakudo to it was relatively easy, since Rakudo targets NQP, not a specific VM.
Pugs, conversely, was an interpreter/VM for Perl back in the days of Parrot, and ran its own Perl 6 implementation directly (no intermediary language, and it wasn't Rakudo). It was writtem in Haskell.
Niecza was another direct implementation of Perl 6, but implemented in C# for .Net. I don't believe it used NQP.