mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
9d32d440eb
The GitHub Super Linter is a more robust and better supported tool than the current GitHub Actions we are using. Running these checks: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true VALIDATE_BASH_EXEC: true VALIDATE_EDITORCONFIG: true VALIDATE_MARKDOWN: true VALIDATE_SHELL_SHFMT: true VALIDATE_YAML: true https://github.com/marketplace/actions/super-linter https://github.com/github/super-linter Added the GitHub Super Linter badge to the README. Also updated the pre-commit framework and added more documentation on pre-commit. Added one more pre-commit check: check-executables-have-shebangs Added one extra check for merge conflicts to our GitHub Actions. EditorConfig and Markdown linting. Minor grammar and spelling fixes. Update linter.yml
136 lines
11 KiB
Markdown
136 lines
11 KiB
Markdown
# The new bytecode
|
|
|
|
We will reimplement the VM to use 8bit instruction code. By
|
|
bytecode, we mean real byte code. The whole purpose is
|
|
reducing the memory consumption of mruby VM.
|
|
|
|
# Instructions
|
|
|
|
Instructions are bytes. There can be 256 instructions. Currently, we
|
|
have 94 instructions. Instructions can take 0 to 3 operands.
|
|
|
|
## operands
|
|
|
|
The size of operands can be either 8bits, 16bits or 24bits.
|
|
In the table.1 below, the second field describes the size (and
|
|
sign) of operands.
|
|
|
|
* B: 8bit
|
|
* S: 16bit
|
|
* sS: signed 16bit
|
|
* W: 24bit
|
|
|
|
## table.1 Instruction Table
|
|
|
|
| Instruction Name | Operand type | Semantics |
|
|
|------------------|--------------|--------------------------------------------------------|
|
|
| OP_NOP | - | no operation |
|
|
| OP_MOVE | BB | R(a) = R(b) |
|
|
| OP_LOADL | BB | R(a) = Pool(b) |
|
|
| OP_LOADL16 | BS | R(a) = Pool(b) |
|
|
| OP_LOADI | BB | R(a) = mrb_int(b) |
|
|
| OP_LOADINEG | BB | R(a) = mrb_int(-b) |
|
|
| OP_LOADI__1 | B | R(a) = mrb_int(-1) |
|
|
| OP_LOADI_0 | B | R(a) = mrb_int(0) |
|
|
| OP_LOADI_1 | B | R(a) = mrb_int(1) |
|
|
| OP_LOADI_2 | B | R(a) = mrb_int(2) |
|
|
| OP_LOADI_3 | B | R(a) = mrb_int(3) |
|
|
| OP_LOADI_4 | B | R(a) = mrb_int(4) |
|
|
| OP_LOADI_5 | B | R(a) = mrb_int(5) |
|
|
| OP_LOADI_6 | B | R(a) = mrb_int(6) |
|
|
| OP_LOADI_7 | B | R(a) = mrb_int(7) |
|
|
| OP_LOADI16 | BS | R(a) = mrb_int(b) |
|
|
| OP_LOADI32 | BSS | R(a) = mrb_int((b<<16)+c) |
|
|
| OP_LOADSYM | BB | R(a) = Syms(b) |
|
|
| OP_LOADSYM16 | BS | R(a) = Syms(b) |
|
|
| OP_LOADNIL | B | R(a) = nil |
|
|
| OP_LOADSELF | B | R(a) = self |
|
|
| OP_LOADT | B | R(a) = true |
|
|
| OP_LOADF | B | R(a) = false |
|
|
| OP_GETGV | BB | R(a) = getglobal(Syms(b)) |
|
|
| OP_SETGV | BB | setglobal(Syms(b), R(a)) |
|
|
| OP_GETSV | BB | R(a) = Special[Syms(b)] |
|
|
| OP_SETSV | BB | Special[Syms(b)] = R(a) |
|
|
| OP_GETIV | BB | R(a) = ivget(Syms(b)) |
|
|
| OP_SETIV | BB | ivset(Syms(b),R(a)) |
|
|
| OP_GETCV | BB | R(a) = cvget(Syms(b)) |
|
|
| OP_SETCV | BB | cvset(Syms(b),R(a)) |
|
|
| OP_GETCONST | BB | R(a) = constget(Syms(b)) |
|
|
| OP_SETCONST | BB | constset(Syms(b),R(a)) |
|
|
| OP_GETMCNST | BB | R(a) = R(a)::Syms(b) |
|
|
| OP_SETMCNST | BB | R(a+1)::Syms(b) = R(a) |
|
|
| OP_GETUPVAR | BBB | R(a) = uvget(b,c) |
|
|
| OP_SETUPVAR | BBB | uvset(b,c,R(a)) |
|
|
| OP_JMP | S | pc+=a |
|
|
| OP_JMPIF | BS | if R(a) pc+=b |
|
|
| OP_JMPNOT | BS | if !R(a) pc+=b |
|
|
| OP_JMPNIL | BS | if R(a)==nil pc+=b |
|
|
| OP_JMPUW | S | unwind_and_jump_to(a) |
|
|
| OP_EXCEPT | B | R(a) = exc |
|
|
| OP_RESCUE | BB | R(b) = R(a).isa?(R(b)) |
|
|
| OP_RAISEIF | B | raise(R(a)) if R(a) |
|
|
| OP_SENDV | BB | R(a) = call(R(a),Syms(b),*R(a+1)) |
|
|
| OP_SENDVB | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) |
|
|
| OP_SEND | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) |
|
|
| OP_SENDB | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) |
|
|
| OP_SENDVK | BB | R(a) = call(R(a),Syms(b),*R(a+1),**(a+2),&R(a+3)) |
|
|
| OP_CALL | - | R(0) = self.call(frame.argc, frame.argv) |
|
|
| OP_SUPER | BB | R(a) = super(R(a+1),... ,R(a+b+1)) |
|
|
| OP_ARGARY | BS | R(a) = argument array (16=5:1:5:1:4) |
|
|
| OP_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1) |
|
|
| OP_KEY_P | BB | R(a) = kdict.key?(Syms(b)) |
|
|
| OP_KEYEND | - | raise unless kdict.empty? |
|
|
| OP_KARG | BB | R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) |
|
|
| OP_RETURN | B | return R(a) (normal) |
|
|
| OP_RETURN_BLK | B | return R(a) (in-block return) |
|
|
| OP_BREAK | B | break R(a) |
|
|
| OP_BLKPUSH | BS | R(a) = block (16=5:1:5:1:4) |
|
|
| OP_ADD | B | R(a) = R(a)+R(a+1) |
|
|
| OP_ADDI | BB | R(a) = R(a)+mrb_int(b) |
|
|
| OP_SUB | B | R(a) = R(a)-R(a+1) |
|
|
| OP_SUBI | BB | R(a) = R(a)-mrb_int(b) |
|
|
| OP_MUL | B | R(a) = R(a)*R(a+1) |
|
|
| OP_DIV | B | R(a) = R(a)/R(a+1) |
|
|
| OP_EQ | B | R(a) = R(a)==R(a+1) |
|
|
| OP_LT | B | R(a) = R(a)<R(a+1) |
|
|
| OP_LE | B | R(a) = R(a)<=R(a+1) |
|
|
| OP_GT | B | R(a) = R(a)>R(a+1) |
|
|
| OP_GE | B | R(a) = R(a)>=R(a+1) |
|
|
| OP_ARRAY | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b)) |
|
|
| OP_ARRAY2 | BBB | R(a) = ary_new(R(b),R(b+1)..R(b+c)) |
|
|
| OP_ARYCAT | B | ary_cat(R(a),R(a+1)) |
|
|
| OP_ARYPUSH | B | ary_push(R(a),R(a+1)) |
|
|
| OP_ARYDUP | B | R(a) = ary_dup(R(a)) |
|
|
| OP_AREF | BBB | R(a) = R(b)[c] | <!-- markdownlint-disable -->
|
|
| OP_ASET | BBB | R(a)[c] = R(b) | <!-- markdownlint-disable -->
|
|
| OP_APOST | BBB | *R(a),R(a+1)..R(a+c) = R(a)[b..] | <!-- markdownlint-disable -->
|
|
| OP_INTERN | B | R(a) = intern(R(a)) |
|
|
| OP_STRING | BB | R(a) = str_dup(Lit(b)) |
|
|
| OP_STRING16 | BS | R(a) = str_dup(Lit(b)) |
|
|
| OP_STRCAT | B | str_cat(R(a),R(a+1)) |
|
|
| OP_HASH | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) |
|
|
| OP_HASHADD | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) |
|
|
| OP_HASHCAT | B | R(a) = hash_cat(R(a),R(a+1)) |
|
|
| OP_LAMBDA | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA) |
|
|
| OP_LAMBDA16 | BS | R(a) = lambda(SEQ[b],OP_L_LAMBDA) |
|
|
| OP_BLOCK | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK) |
|
|
| OP_BLOCK16 | BS | R(a) = lambda(SEQ[b],OP_L_BLOCK) |
|
|
| OP_METHOD | BB | R(a) = lambda(SEQ[b],OP_L_METHOD) |
|
|
| OP_METHOD16 | BS | R(a) = lambda(SEQ[b],OP_L_METHOD) |
|
|
| OP_RANGE_INC | B | R(a) = range_new(R(a),R(a+1),FALSE) |
|
|
| OP_RANGE_EXC | B | R(a) = range_new(R(a),R(a+1),TRUE) |
|
|
| OP_OCLASS | B | R(a) = ::Object |
|
|
| OP_CLASS | BB | R(a) = newclass(R(a),Syms(b),R(a+1)) |
|
|
| OP_MODULE | BB | R(a) = newmodule(R(a),Syms(b)) |
|
|
| OP_EXEC | BB | R(a) = blockexec(R(a),SEQ[b]) |
|
|
| OP_EXEC16 | BS | R(a) = blockexec(R(a),SEQ[b]) |
|
|
| OP_DEF | BB | R(a).newmethod(Syms(b),R(a+1)) |
|
|
| OP_ALIAS | BB | alias_method(target_class,Syms(a),Syms(b)) |
|
|
| OP_UNDEF | B | undef_method(target_class,Syms(a)) |
|
|
| OP_SCLASS | B | R(a) = R(a).singleton_class |
|
|
| OP_TCLASS | B | R(a) = target_class |
|
|
| OP_DEBUG | BBB | print a,b,c |
|
|
| OP_ERR | B | raise(LocalJumpError, Lit(a)) |
|
|
| OP_STOP | - | stop VM |
|
|
|------------------|--------------|--------------------------------------------------------|
|