source: EcnlProtoTool/trunk/mruby-2.1.1/doc/opcode.md@ 439

Last change on this file since 439 was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

File size: 6.7 KB
Line 
1# The new bytecode
2
3We will reimplement VM to use 8bit instruction code. By
4bytecode, we mean real byte code. The whole purpose is
5reducing the memory consumption of mruby VM.
6
7# Instructions
8
9Instructions are bytes. There can be 256 instructions. Currently we
10have 94 instructions. Instructions can take 0 to 3 operands.
11
12## operands
13
14The size of operands can be either 8bits, 16bits or 24bits.
15In the table.1 below, the second field describes the size (and
16sign) of operands.
17
18* B: 8bit
19* sB: signed 8bit
20* S: 16bit
21* sS: signed 16bit
22* W: 24bit
23
24First two byte operands may be extended to 16bit. When those byte
25operands are bigger than 256, the instruction will be prefixed by
26`OP_EXT1` (means 1st operand is 16bit) or `OP_EXT2` (means 2nd operand
27is 16bit) or `OP_EXT3` (means 1st and 2nd operands are 16bit).
28
29For instructions marked by `'`, `OP_EXT1` can be prefixed. For those
30with `"`, either `OP_EXT1` or `OP_EXT2` or `OP_EXT2` can be prefixed.
31
32## table.1 Instruction Table
33
34| Instruction Name | Operand type | Semantics |
35|:-----------------|--------------|---------------------|
36| OP_NOP | - | |
37| OP_MOVE" | BB | R(a) = R(b)
38| OP_LOADL" | BB | R(a) = Pool(b)
39| OP_LOADI" | BsB | R(a) = mrb_int(b)
40| OP_LOADI_0' | B | R(a) = 0
41| OP_LOADI_1' | B | R(a) = 1
42| OP_LOADI_2' | B | R(a) = 2
43| OP_LOADI_3' | B | R(a) = 3
44| OP_LOADSYM" | BB | R(a) = Syms(b)
45| OP_LOADNIL' | B | R(a) = nil
46| OP_LOADSELF' | B | R(a) = self
47| OP_LOADT' | B | R(a) = true
48| OP_LOADF' | B | R(a) = false
49| OP_GETGV" | BB | R(a) = getglobal(Syms(b))
50| OP_SETGV" | BB | setglobal(Syms(b), R(a))
51| OP_GETSV" | BB | R(a) = Special[b]
52| OP_SETSV" | BB | Special[b] = R(a)
53| OP_GETIV" | BB | R(a) = ivget(Syms(b))
54| OP_SETIV" | BB | ivset(Syms(b),R(a))
55| OP_GETCV" | BB | R(a) = cvget(Syms(b))
56| OP_SETCV" | BB | cvset(Syms(b),R(a))
57| OP_GETCONST" | BB | R(a) = constget(Syms(b))
58| OP_SETCONST" | BB | constset(Syms(b),R(a))
59| OP_GETMCNST" | BB | R(a) = R(a)::Syms(b)
60| OP_SETMCNST" | BB | R(a+1)::Syms(b) = R(a)
61| OP_GETUPVAR' | BBB | R(a) = uvget(b,c)
62| OP_SETUPVAR' | BBB | uvset(b,c,R(a))
63| OP_JMP | S | pc+=a
64| OP_JMPIF' | SB | if R(b) pc+=a
65| OP_JMPNOT' | SB | if !R(b) pc+=a
66| OP_ONERR | sS | rescue_push(pc+a)
67| OP_EXCEPT' | B | R(a) = exc
68| OP_RESCUE" | BB | R(b) = R(a).isa?(R(b))
69| OP_POPERR | B | a.times{rescue_pop()}
70| OP_RAISE' | B | raise(R(a))
71| OP_EPUSH' | B | ensure_push(SEQ[a])
72| OP_EPOP | B | A.times{ensure_pop().call}
73| OP_SENDV" | BB | R(a) = call(R(a),Syms(b),*R(a+1))
74| OP_SENDVB" | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2))
75| OP_SEND" | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))
76| OP_SENDB" | BBB | R(a) = call(R(a),Syms(Bx),R(a+1),...,R(a+c),&R(a+c+1))
77| OP_CALL' | B | R(a) = self.call(frame.argc, frame.argv)
78| OP_SUPER' | BB | R(a) = super(R(a+1),... ,R(a+b+1))
79| OP_ARGARY' | BS | R(a) = argument array (16=5:1:5:1:4)
80| OP_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1)
81| OP_KARG" | BB | R(a) = kdict[Syms(Bx)] # todo
82| OP_KARG2" | BB | R(a) = kdict[Syms(Bx)]; kdict.rm(Syms(b)) # todo
83| OP_RETURN' | B | return R(a) (normal)
84| OP_RETURN_BLK' | B | return R(a) (in-block return)
85| OP_BREAK' | B | break R(a)
86| OP_BLKPUSH' | BS | R(a) = block (16=5:1:5:1:4)
87| OP_ADD" | BB | R(a) = R(a)+R(a+1)
88| OP_ADDI" | BBB | R(a) = R(a)+mrb_int(c)
89| OP_SUB" | BB | R(a) = R(a)-R(a+1)
90| OP_SUBI" | BB | R(a) = R(a)-C
91| OP_MUL" | BB | R(a) = R(a)*R(a+1)
92| OP_DIV" | BB | R(a) = R(a)/R(a+1)
93| OP_EQ" | BB | R(a) = R(a)==R(a+1)
94| OP_LT" | BB | R(a) = R(a)<R(a+1)
95| OP_LE" | BB | R(a) = R(a)<=R(a+1)
96| OP_GT" | BB | R(a) = R(a)>R(a+1)
97| OP_GE" | BB | R(a) = R(a)>=R(a+1)
98| OP_ARRAY' | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b))
99| OP_ARRAY2" | BB | R(a) = ary_new(R(b),R(b+1)..R(b+c))
100| OP_ARYCAT' | B | ary_cat(R(a),R(a+1))
101| OP_ARYPUSH' | B | ary_push(R(a),R(a+1))
102| OP_AREF' | BB | R(a) = R(a)[b]
103| OP_ASET' | BB | R(a)[b] = R(a+1)
104| OP_APOST' | BB | *R(a),R(A+1)..R(A+C) = R(a)[B..]
105| OP_STRING" | BB | R(a) = str_dup(Lit(b))
106| OP_STRCAT' | B | str_cat(R(a),R(a+1))
107| OP_HASH' | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b))
108| OP_HASHADD' | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b))
109| OP_LAMBDA" | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA)
110| OP_BLOCK" | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK)
111| OP_METHOD" | BB | R(a) = lambda(SEQ[b],OP_L_METHOD)
112| OP_RANGE_INC' | B | R(a) = range_new(R(a),R(a+1),FALSE)
113| OP_RANGE_EXC' | B | R(a) = range_new(R(a),R(a+1),TRUE)
114| OP_OCLASS' | B | R(a) = ::Object
115| OP_CLASS" | BB | R(a) = newclass(R(a),Syms(b),R(a+1))
116| OP_MODULE" | BB | R(a) = newmodule(R(a),Syms(b))
117| OP_EXEC" | BB | R(a) = blockexec(R(a),SEQ[b])
118| OP_DEF" | BB | R(a).newmethod(Syms(b),R(a+1))
119| OP_ALIAS' | B | alias_method(R(a),R(a+1),R(a+2))
120| OP_UNDEF" | BB | undef_method(R(a),Syms(b))
121| OP_SCLASS' | B | R(a) = R(a).singleton_class
122| OP_TCLASS' | B | R(a) = target_class
123| OP_ERR' | B | raise(RuntimeError, Lit(Bx))
124| OP_EXT1 | - | make 1st operand 16bit
125| OP_EXT2 | - | make 2nd operand 16bit
126| OP_EXT3 | - | make 1st and 2nd operands 16bit
127| OP_STOP | - | stop VM
Note: See TracBrowser for help on using the repository browser.