Kod bajtowy Perla

Kod bajtowy Perla używany w Perlu 5 jest maszyną stosową z operacjami umiarkowanie wysokiego poziomu. Perl 6 używać będzie maszyny wirtualnej Parrot.

Wynikiem kompilacji:

print "Hello, world!\n";

jest następujący bytecode:

OP     enter
COP    nextstate
OP     pushmark
SVOP   const PV "Hello, world!\n"
LISTOP print
LISTOP leave

Klasy opcodów

Opcody są pogrupowane w kilka klas zależnie od tego na jakich argumentach działają. Klasy te to:

  • OP – ogólna klasa,
  • COP – informacja dla debugera,
  • SVOP – operacje na skalarach,
  • PADOP,
  • UNOP – operacje unarne,
  • LOGOP – operacje logiczne (sterujące),
  • BINOP – operacje binarne,
  • LISTOP – operacje działające na listach,
  • PMOP – operacje na wyrażeniach regularnych,
  • LOOPOP – operacje pętli,

Stos

Stos nie zawiera obiektów, a jedynie wskaźniki do nich.

Żeby wywołać operacje unarną lub binarną umieszczamy jej argumenty na stosie i wywołujemy ją.

Na przykład operacja unarna UNOP negate pobierze najwyższy element ze stosu i wstawi na stos jego zanegowaną wartość, operacja binarna BINOP add pobierze dwa najwyższe elementy ze stosu i wstawi ich sumę.

Żeby wywołać operację wymagającą większej ilości argumentów:

  • zaznaczamy za pomocą OP pushmark, że zaczyna się nowa ramka stosu,
  • umieszczamy na stosie wszystkie argumenty zaczynając od pierwszego,
  • wywołujemy odpowiednią operację (np. LISTOP print), lub umieszczamy na stosie adres funkcji do wywołania (PADOP gv GV *foo), po czym ją wywołujemy za pomocą UNOP entersub.

Przykład wywołania $x = "Hello, world!\n":

COP    nextstate
SVOP   const PV "Hello, world!\n"
PADOP  gvsv GV *x
BINOP  sassign

Przykład wywołania $x = -$y:

PADOP  gvsv GV *y
UNOP   negate
PADOP  gvsv GV *x
BINOP  sassign

Przykład wywołania $x = $y + $z:

PADOP  gvsv GV *y
PADOP  gvsv GV *z
BINOP  add
PADOP  gvsv GV *x
BINOP  sassign

Przykład wywołania print(1,2,3):

OP     pushmark
SVOP   const IV 1
SVOP   const IV 2
SVOP   const IV 3
LISTOP print

Przykład wywołania foo(1,2,3):

COP    nextstate
OP     pushmark
SVOP   const IV 1
SVOP   const IV 2
SVOP   const IV 3
PADOP  gv GV *foo
UNOP   entersub

Operacje na zmiennych skalarnych

Opcode PADOP gvsv umieszcza na stosie adres zmiennej.
Opcode SVOP const umieszcza na stosie stałą.

Opcode BINOP sassign przypisuje zmiennej, odnośnik do której adres znajduje się na najwyższej pozycji stosu. Adres zostaje zdjęty ze stosu, ale wartość zostaje.

Przykład wywołania $x = $y:

PADOP gvsv  GV *y
PADOP gvsv  GV *x
BINOP sassign

Przykład wywołania $x = $y = $z:

PADOP  gvsv GV *z
PADOP  gvsv GV *y
BINOP  sassign
PADOP  gvsv GV *x
BINOP  sassign

Operacje na liczbach

Podstawowe operacje arytmetyczne to:

OperacjaPerlBytecode
dodawanie$x + $yBINOP add
odejmowanie$x – $yBINOP substract
mnożenie$x * $yBINOP multiply
dzielenie$x / $yBINOP divide
reszta modulo$x % $yBINOP modulo
bitowe AND$x & $yBINOP bit_and
bitowe OR$x | $yBINOP bit_or
bitowe XOR$x ^ $yBINOP bit_xor
negacja arytmetyczna-$xUNOP negate
negacja bitowa~$xUNOP complement
sinussin($x)UNOP sin
cosinuscos($x)UNOP cos
funkcja wykładniczaexp($x)UNOP exp
logarytmlog($x)UNOP log
pierwiasteksqrt($x)UNOP sqrt
większe$x > $yBINOP gt
większe równe$x >= $yBINOP ge
mniejsze$x < $yBINOP lt
mniejsze równe$x <= $yBINOP le
równe$x == $yBINOP eq
nierówne$x != $yBINOP ne
porównanie$x <=> $yBINOP ncmp
przesunięcie bitowe w lewo$x << $yBINOP left_shift
przesunięcie bitowe w prawo$x >> $yBINOP right_shift
preinkrementacja++$xUNOP preinc
predekrementacja--$xUNOP predec
postinkrementacja$x++UNOP postinc
postdekrementacja$y--UNOP postdec

Operatory ++ i -- działają też na łańcuchach. Wersje pre- i post- różnią się tym, co zostaje na stosie.

Operacje na łańcuchach znaków

OperacjaPerlBytecode
sklejenie$x . $yBINOP concat
długośćlength($x)UNOP length
zamiana wszystkich liter na wielkieuc($x)UNOP uc
zamiana wszystkich liter na małelc($x)UNOP lc
zamiana pierwszego znaku na wielką literęucfirst($x)UNOP ucfirst
zamiana pierwszego znaku na małą literęlcfirst($x)UNOP lcfirst
większe$x gt $yBINOP sgt
większe równe$x ge $yBINOP sge
mniejsze$x lt $yBINOP slt
mniejsze równe$x le $yBINOP sle
równe$x eq $yBINOP seq
nierówne$x ne $yBINOP sne
porównanie$x cmp $yBINOP scmp