mruby
My study about mruby
mruby 2.0.0
こちらを参照ください。
mruby 1.4.1
Learn mruby byte-code
I’m learning mruby v1.3 byte-code instructions one by one. I’ll put links once I write an article about an instruction.
mruby/cの勉強のため、mruby v1.3のバイトコードの命令を一つずつ説明をまとめていく。
他の方が説明されたありがたい資料を参考にしつつ、説明されていないものも多いので、自分なりに調べてみる。
https://qiita.com/miura1729/items/256d205bc2a464bfb3c6
http://www.dzeta.jp/~junjis/code_reading/index.php?mruby%2F%E3%82%B3%E3%83%BC%E3%83%89%E5%AE%9F%E8%A1%8C%E3%82%92%E8%AA%AD%E3%82%80
Policy
- Investigate instructions related to mruby/c at first
- Investigate usage based on mruby/c VM implementation (Sometimes behavior is not same as original mruby VM.)
List of byte code instruction
mruby/c | mruby v1.3 | Arg | Usage | Article |
---|---|---|---|---|
NOP | NOP | – | 記事へ | |
MOVE | MOVE | A B | R(A) := R(B) | 記事へ |
LOADL | LOADL | A Bx | R(A) := Pool(Bx) | 記事へ |
LOADI | LOADI | A sBx | R(A) := sBx | 記事へ |
LOADSYM | LOADSYM | A Bx | R(A) := Syms(Bx) | 記事へ |
LOADNIL | LOADNIL | A | R(A) := nil | 記事へ |
LOADSELF | LOADSELF | A | R(A) := self | 記事へ |
LOADT | LOADT | A | R(A) := true | 記事へ |
LOADF | LOADF | A | R(A) := false | 記事へ |
GETGLOBAL | GETGLOBAL | A Bx | R(A) := getglobal(Syms(Bx)) | 記事へ |
SETGLOBAL | SETGLOBAL | A Bx | setglobal(Syms(Bx), R(A)) | 記事へ |
GETSPECIAL | A Bx | R(A) := Special[Bx] | 記事へ | |
SETSPECIAL | A Bx | Special[Bx] := R(A) | 記事へ | |
GETIV | GETIV | A Bx | R(A) := ivget(Syms(Bx)) | 記事へ |
SETIV | SETIV | A Bx | ivset(Syms(Bx),R(A)) | |
GETCV | A Bx | R(A) := cvget(Syms(Bx)) | ||
SETCV | A Bx | cvset(Syms(Bx),R(A)) | ||
GETCONST | GETCONST | A Bx | R(A) := constget(Syms(Bx)) | |
SETCONST | SETCONST | A Bx | constset(Syms(Bx),R(A)) | |
GETMCNST | A Bx | R(A) := R(A)::Syms(Bx) | ||
SETMCNST | A Bx | R(A+1)::Syms(Bx) := R(A) | ||
GETUPVAR | GETUPVAR | A B C | R(A) := uvget(B,C) | |
SETUPVAR | SETUPVAR | A B C | uvset(B,C,R(A)) | |
JMP | JMP | sBx | pc+=sBx | |
JMPIF | JMPIF | A sBx | if R(A) pc+=sBx | |
JMPNOT | JMPNOT | A sBx | if !R(A) pc+=sBx | |
ONERR | sBx | rescue_push(pc+sBx) | ||
RESCUE | A B C | if A (if C exc=R(A) else R(A) := exc) | ||
POPERR | A | A.times{rescue_pop()} | ||
RAISE | A | raise(R(A)) | ||
EPUSH | Bx | ensure_push(SEQ[Bx]) | ||
EPOP | A | A.times{ensure_pop().call} | ||
SEND | SEND | A B C | R(A) := call(R(A),Syms(B),R(A+1),…,R(A+C)) | |
SENDB | SENDB | A B C | R(A) := call(R(A),Syms(B),R(A+1),…,R(A+C),&R(A+C+1)) | |
FSEND | A B C | R(A) := fcall(R(A),Syms(B),R(A+1),…,R(A+C-1)) | ||
CALL | CALL | A | R(A) := self.call(frame.argc, frame.argv) | |
SUPER | A C | R(A) := super(R(A+1),… ,R(A+C+1)) | ||
ARGARY | A Bx | R(A) := argument array (16=6:1:5:4) | ||
ENTER | ENTER | Ax | arg setup according to flags (23=5:5:1:5:5:1:1) | |
KARG | A B C | R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) | ||
KDICT | A C | R(A) := kdict | ||
RETURN | RETURN | A B | return R(A) (B=normal,in-block return/break) | |
TAILCALL | A B C | return call(R(A),Syms(B),*R(C)) | ||
BLKPUSH | BLKPUSH | A Bx | R(A) := block (16=6:1:5:4) | |
ADD | ADD | A B C | R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1) | |
ADDI | ADDI | A B C | R(A) := R(A)+C (Syms[B]=:+) | |
SUB | SUB | A B C | R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1) | |
SUBI | SUBI | A B C | R(A) := R(A)-C (Syms[B]=:-) | |
MUL | MUL | A B C | R(A) := R(A)R(A+1) (Syms[B]=:,C=1) | |
DIV | DIV | A B C | R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1) | |
EQ | EQ | A B C | R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1) | |
LT | LT | A B C | R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1) | |
LE | LE | A B C | R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1) | |
GT | GT | A B C | R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1) | |
GE | GE | A B C | R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1) | |
ARRAY | ARRAY | A B C | R(A) := ary_new(R(B),R(B+1)..R(B+C)) | |
ARYCAT | A B | ary_cat(R(A),R(B)) | ||
ARYPUSH | A B | ary_push(R(A),R(B)) | ||
AREF | A B C | R(A) := R(B)[C] | ||
ASET | A B C | R(B)[C] := R(A) | ||
APOST | A B C | *R(A),R(A+1)..R(A+C) := R(A) | ||
STRING | STRING | A Bx | R(A) := str_dup(Lit(Bx)) | |
STRCAT | STRCAT | A B | str_cat(R(A),R(B)) | |
HASH | HASH | A B C | R(A) := hash_new(R(B),R(B+1)..R(B+C)) | |
LAMBDA | LAMBDA | A Bz Cz | R(A) := lambda(SEQ[Bz],Cz) | |
RANGE | RANGE | A B C | R(A) := range_new(R(B),R(B+1),C) | |
OCLASS | A | R(A) := ::Object | ||
CLASS | CLASS | A B | R(A) := newclass(R(A),Syms(B),R(A+1)) | |
MODULE | A B | R(A) := newmodule(R(A),Syms(B)) | ||
EXEC | EXEC | A Bx | R(A) := blockexec(R(A),SEQ[Bx]) | |
METHOD | METHOD | A B | R(A).newmethod(Syms(B),R(A+1)) | |
SCLASS | A B | R(A) := R(B).singleton_class | ||
TCLASS | TCLASS | A | R(A) := target_class | |
DEBUG | A B C | print R(A),R(B),R(C) | ||
STOP | STOP | stop VM | ||
ERR | Bx | raise RuntimeError with message Lit(Bx) | ||
RSVD1 | reserved instruction #1 | N/A | ||
RSVD2 | reserved instruction #2 | N/A | ||
RSVD3 | reserved instruction #3 | N/A | ||
RSVD4 | reserved instruction #4 | N/A | ||
RSVD5 | reserved instruction #5 | N/A | ||
ABORT | (mruby/c only) |
Recent Comments