mruby/cがサポートするmrubyバイトコード命令の範囲

Techc, Japanese, mruby/c

mruby/cを理解するために、mrubyバイトコードを勉強している。
実装をコンパクトにするため(もしくは開発中のため)、mruby/cはmrubyのすべての命令をサポートしていない。
mruby/cのvm.cとmrubyのopcode.hを参照して、mruby/cが現時点でサポートしている命令を調べてみた。
自分のリファレンス用に表を残しておく。mruby/cにも存在している命令でも、Todoのコメントがあるので、実際は実装中であることもあると思うので、その点は留意。
Array関連や、Moduleの命令が欠けていることなどが分かる。

mruby 32bit byte code
mruby 32bit byte code
mruby/c mruby v1.3 Arg Usage
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
RSVD2 reserved instruction #2
RSVD3 reserved instruction #3
RSVD4 reserved instruction #4
RSVD5 reserved instruction #5
ABORT (mruby/c only)