Kod bajtowy Perla
Z Wikipedii
Kod bajtowy Perla używany w Perl 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
Spis treści |
[edytuj] 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 debuggera,
- 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,
- …
[edytuj] 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
[edytuj] 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
[edytuj] Operacje na liczbach
Podstawowe operacje arytmetyczne to:
operacja | Perl | bytecode |
dodawanie | $x + $y | BINOP add |
odejmowanie | $x - $y | BINOP substract |
mnożenie | $x * $y | BINOP multiply |
dzielenie | $x / $y | BINOP divide |
reszta modulo | $x % $y | BINOP modulo |
bitowe AND | $x & $y | BINOP bit_and |
bitowe OR | $y | BINOP bit_or |
bitowe XOR | $x ^ $y | BINOP bit_xor |
negacja arytmetyczna | -$x | UNOP negate |
negacja bitowa | ~$x | UNOP complement |
sinus | sin($x) | UNOP sin |
cosinus | cos($x) | UNOP cos |
funkcja wykładnicza | exp($x) | UNOP exp |
logarytm | log($x) | UNOP log |
pierwiastek | sqrt($x) | UNOP sqrt |
większe | $x > $y | BINOP gt |
większe równe | $x >= $y | BINOP ge |
mniejsze | $x < $y | BINOP lt |
mniejsze równe | $x <= $y | BINOP le |
równe | $x == $y | BINOP eq |
nierówne | $x != $y | BINOP ne |
porównanie | $x <=> $y | BINOP ncmp |
przesunięcie bitowe w lewo | $x << $y | BINOP left_shift |
przesunięcie bitowe w prawo | $x >> $y | BINOP right_shift |
preinkrementacja | ++$x | UNOP preinc |
predekrementacja | --$x | UNOP predec |
postinkrementacja | $x++ | UNOP preinc |
postdekrementacja | $y++ | UNOP preinc |
Operatory ++ i -- działają też na łańcuchach. Wersje pre- i post- różnią się tym co zostaje na stosie.
[edytuj] Operacje na łańcuchach znaków
operacja | Perl | bytecode |
sklejenie | $x . $y | BINOP concat |
długość | length($x) | UNOP length |
zamiana wszystkich liter na wielkie | uc($x) | UNOP uc |
zamiana wszystkich liter na małe | lc($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 $y | BINOP sgt |
większe równe | $x ge $y | BINOP sge |
mniejsze | $x lt $y | BINOP slt |
mniejsze równe | $x le $y | BINOP sle |
równe | $x eq $y | BINOP seq |
nierówne | $x ne $y | BINOP sne |
porównanie | $x cmp $y | BINOP scmp |