Kod bajtowy Perla – Wikipedia, wolna encyklopedia

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

[edytuj | edytuj kod]

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 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

[edytuj | edytuj kod]

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

[edytuj | edytuj kod]

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 $x | $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 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

[edytuj | edytuj kod]
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