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