diff options
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/guides/compile.md | 100 | ||||
| -rw-r--r-- | doc/guides/mrbconf.md | 15 | ||||
| -rw-r--r-- | doc/guides/mrbgems.md | 158 | ||||
| -rw-r--r-- | doc/guides/symbol.md | 16 | ||||
| -rw-r--r-- | doc/limitations.md | 26 | ||||
| -rw-r--r-- | doc/mruby3.md | 17 | ||||
| -rw-r--r-- | doc/opcode.md | 218 |
7 files changed, 265 insertions, 285 deletions
diff --git a/doc/guides/compile.md b/doc/guides/compile.md index 7156b2b68..2923a2676 100644 --- a/doc/guides/compile.md +++ b/doc/guides/compile.md @@ -138,18 +138,18 @@ C Compiler has header searcher to detect installed library. If you need an include path of header file use `search_header_path`: ```ruby -# Searches ```iconv.h```. +# Searches `iconv.h`. # If found it will return include path of the header file. -# Otherwise it will return nil . +# Otherwise it will return nil. fail 'iconv.h not found' unless conf.cc.search_header_path 'iconv.h' ``` If you need a full file name of header file use `search_header`: ```ruby -# Searches ```iconv.h```. +# Searches `iconv.h`. # If found it will return full path of the header file. -# Otherwise it will return nil . +# Otherwise it will return nil. iconv_h = conf.cc.search_header 'iconv.h' print "iconv.h found: #{iconv_h}\n" ``` @@ -333,9 +333,9 @@ conf.enable_debug When debugging mode is enabled * Macro `MRB_DEBUG` would be defined. - * Which means `mrb_assert()` macro is enabled. + * Which means `mrb_assert()` macro is enabled. * Debug information of irep would be generated by `mrbc`. - * Because `-g` flag would be added to `mrbc` runner. + * Because `-g` flag would be added to `mrbc` runner. * You can have better backtrace of mruby scripts with this. ## Cross-Compilation @@ -379,23 +379,25 @@ end During the build process the directory `build` will be created in the root directory. The structure of this directory will look like this: - +- build - | - +- host - | - +- LEGAL <- License description - | - +- bin <- Binaries (mirb, mrbc and mruby) - | - +- lib <- Libraries (libmruby.a and libmruby_core.a) - | - +- mrbc <- Minimal mrbc place - | - +- mrbgems <- Compilation result from mrbgems - | - +- mrblib <- Compilation result from mrblib - | - +- src <- Compilation result from C sources +``` ++- build + | + +- host + | + +- LEGAL <- License description + | + +- bin <- Binaries (mirb, mrbc and mruby) + | + +- lib <- Libraries (libmruby.a and libmruby_core.a) + | + +- mrbc <- Minimal mrbc place + | + +- mrbgems <- Compilation result from mrbgems + | + +- mrblib <- Compilation result from mrblib + | + +- src <- Compilation result from C sources +``` The compilation workflow will look like this: @@ -425,31 +427,33 @@ The compilation workflow will look like this: In case of a cross-compilation to `i386` the `build` directory structure looks like this: - +- build - | - +- host - | | - | +- bin <- Native Binaries - | | - | +- lib <- Native Libraries - | | - | +- mrbgems - | | - | +- src - | - +- i386 - | - +- bin <- Cross-compiled Binaries - | - +- include <- Header Directory - | - +- lib <- Cross-compiled Libraries - | - +- mrbgems - | - +- mrblib - | - +- src +``` ++- build + | + +- host + | | + | +- bin <- Native Binaries + | | + | +- lib <- Native Libraries + | | + | +- mrbgems + | | + | +- src + | + +- i386 + | + +- bin <- Cross-compiled Binaries + | + +- include <- Header Directory + | + +- lib <- Cross-compiled Libraries + | + +- mrbgems + | + +- mrblib + | + +- src +``` An extra directory is created for the target platform. In case you compile for `i386` a directory called `i386` is created under the diff --git a/doc/guides/mrbconf.md b/doc/guides/mrbconf.md index b5bc8c85c..e71346ae6 100644 --- a/doc/guides/mrbconf.md +++ b/doc/guides/mrbconf.md @@ -151,17 +151,18 @@ largest value of required alignment. ## Reduce heap memory configuration -`MRB_USE_LINK_TIME_RO_DATA_P` +`MRB_USE_ETEXT_RO_DATA_P` -* Only available on ELF platforms. -* If you specify the address of a read-only section when creating a symbol or string, that string will be used as it is. -* Heap memory can be saved. -* Uses `__ehdr_start` and `__init_array_start`. -* It must be `__ehdr_start < data_addr < __init_array_start`. +* Use `etext` and `edata` section addresses defined by the linker to detect read-only data. +* Those addresses are widely available, but not portable, nor standardized. +* This macro is defined by default on User-mode Linux. + +`MRB_NO_DEFAULT_RO_DATA_P` + +* Define this macro when the default `mrb_ro_data_p()` does not work for any reason. `MRB_USE_CUSTOM_RO_DATA_P` -* Takes precedence over `MRB_USE_LINK_TIME_RO_DATA_P`. * Please try if `MRB_USE_LINK_TIME_RO_DATA_P` is not available. * The `mrb_ro_data_p()` function is implemented by the user in an arbitrary file. * The prototype declaration is `mrb_bool mrb_ro_data_p(const char *ptr)`. diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md index d4160ebc8..c08a09f4e 100644 --- a/doc/guides/mrbgems.md +++ b/doc/guides/mrbgems.md @@ -55,8 +55,8 @@ conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c4 If there are missing dependencies, mrbgem dependencies solver will reference mrbgem from the core or mgem-list. -To pull all gems from remote GIT repository on build, call ```rake -p```, -or ```rake --pull-gems```. +To pull all gems from remote GIT repository on build, call `rake -p`, +or `rake --pull-gems`. NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. @@ -111,21 +111,21 @@ contains every gem found in the `mrbgems` directory. The maximal GEM structure looks like this: ``` -+- GEM_NAME <- Name of GEM - | - +- README.md <- Readme for GEM - | - +- mrbgem.rake <- GEM Specification - | - +- include/ <- Header for Ruby extension (will exported) - | - +- mrblib/ <- Source for Ruby extension - | - +- src/ <- Source for C extension - | - +- tools/ <- Source for Executable (in C) - | - +- test/ <- Test code (Ruby) ++- GEM_NAME <- Name of GEM + | + +- README.md <- Readme for GEM + | + +- mrbgem.rake <- GEM Specification + | + +- include/ <- Header for Ruby extension (will exported) + | + +- mrblib/ <- Source for Ruby extension + | + +- src/ <- Source for C extension + | + +- tools/ <- Source for Executable (in C) + | + +- test/ <- Test code (Ruby) ``` The folder `mrblib` contains pure Ruby files to extend mruby. The folder `src` @@ -200,8 +200,8 @@ Version requirement supports following operators: * '>=': is equal or greater * '<=': is equal or lesser * '~>': is equal or greater and is lesser than the next major version - * example 1: '~> 2.2.2' means '>= 2.2.2' and '< 2.3.0' - * example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' + * example 1: '~> 2.2.2' means '>= 2.2.2' and '< 2.3.0' + * example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' When more than one version requirements is passed, the dependency must satisfy all of it. @@ -215,7 +215,7 @@ use `MRuby::Build#gem` in the build configuration to override default gem. If you have conflicting GEMs use the following method: * `spec.add_conflict(gem, *requirements)` - * The `requirements` argument is same as in `add_dependency` method. + * The `requirements` argument is same as in `add_dependency` method. like following code: @@ -273,7 +273,7 @@ mrbgems expects that you have implemented a C method called by the name of your GEM. If you call your GEM `c_extension_example`, your initialisation method could look like this: -```C +```c void mrb_c_extension_example_gem_init(mrb_state* mrb) { struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); @@ -288,7 +288,7 @@ mrbgems expects that you have implemented a C method called by the name of your GEM. If you call your GEM `c_extension_example`, your finalizer method could look like this: -```C +```c void mrb_c_extension_example_gem_final(mrb_state* mrb) { free(someone); @@ -297,19 +297,21 @@ mrb_c_extension_example_gem_final(mrb_state* mrb) { ### Example - +- c_extension_example/ - | - +- README.md (Optional) - | - +- src/ - | | - | +- example.c <- C extension source - | - +- test/ - | | - | +- example.rb <- Test code for C extension - | - +- mrbgem.rake <- GEM specification +``` ++- c_extension_example/ + | + +- README.md (Optional) + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C extension + | + +- mrbgem.rake <- GEM specification +``` ## Ruby Extension @@ -323,19 +325,21 @@ none ### Example - +- ruby_extension_example/ - | - +- README.md (Optional) - | - +- mrblib/ - | | - | +- example.rb <- Ruby extension source - | - +- test/ - | | - | +- example.rb <- Test code for Ruby extension - | - +- mrbgem.rake <- GEM specification +``` ++- ruby_extension_example/ + | + +- README.md (Optional) + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- test/ + | | + | +- example.rb <- Test code for Ruby extension + | + +- mrbgem.rake <- GEM specification +``` ## C and Ruby Extension @@ -353,23 +357,25 @@ See C and Ruby example. ### Example - +- c_and_ruby_extension_example/ - | - +- README.md (Optional) - | - +- mrblib/ - | | - | +- example.rb <- Ruby extension source - | - +- src/ - | | - | +- example.c <- C extension source - | - +- test/ - | | - | +- example.rb <- Test code for C and Ruby extension - | - +- mrbgem.rake <- GEM specification +``` ++- c_and_ruby_extension_example/ + | + +- README.md (Optional) + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C and Ruby extension + | + +- mrbgem.rake <- GEM specification +``` ## Binary gems @@ -389,23 +395,23 @@ binary gems, to separate normal gems and binary gems. ### Example ``` - +- mruby-bin-example/ ++- mruby-bin-example/ | - +- README.md (Optional) + +- README.md (Optional) | +- bintest/ - | | - | +- example.rb <- Test code for binary gem + | | + | +- example.rb <- Test code for binary gem | - +- mrbgem.rake <- Gem specification + +- mrbgem.rake <- Gem specification | - +- mrblib/ <- Source for Ruby extension (Optional) + +- mrblib/ <- Source for Ruby extension (Optional) | - +- src/ <- Source for C extension (Optional) + +- src/ <- Source for C extension (Optional) | +- tools/ - | - +- example/ <- Executable name directory - | - +- example.c <- Source for Executable (includes main) + | + +- example/ <- Executable name directory + | + +- example.c <- Source for Executable (includes main) ``` diff --git a/doc/guides/symbol.md b/doc/guides/symbol.md index e9e72a6d3..8f90ce59f 100644 --- a/doc/guides/symbol.md +++ b/doc/guides/symbol.md @@ -4,7 +4,7 @@ Symbols in `mruby` C source code is represented by `mrb_sym` which is alias of `uint32_t`. Lower 30 bits are used for symbols so that higher 2 bits can be used as flags, e.g. `struct mt_elem` in `class.c`. -```C +```c struct mt_elem { union mt_ptr ptr; size_t func_p:1; @@ -57,13 +57,13 @@ To save RAM, `mruby` can use compile-time allocation of some symbols. You can use following macros to get preallocated symbols by including `mruby/presym.h` header. - * `MRB_SYM(xor)` //=> xor (Word characters) - * `MRB_SYM_B(xor)` //=> xor! (Method with Bang) - * `MRB_SYM_Q(xor)` //=> xor? (Method with Question mark) - * `MRB_SYM_E(xor)` //=> xor= (Method with Equal) - * `MRB_CVSYM(xor)` //=> @@xor (Class Variable) - * `MRB_IVSYM(xor)` //=> @xor (Instance Variable) - * `MRB_OPSYM(xor)` //=> ^ (Operator) +* `MRB_SYM(xor)` //=> xor (Word characters) +* `MRB_SYM_B(xor)` //=> xor! (Method with Bang) +* `MRB_SYM_Q(xor)` //=> xor? (Method with Question mark) +* `MRB_SYM_E(xor)` //=> xor= (Method with Equal) +* `MRB_CVSYM(xor)` //=> @@xor (Class Variable) +* `MRB_IVSYM(xor)` //=> @xor (Instance Variable) +* `MRB_OPSYM(xor)` //=> ^ (Operator) For `MRB_OPSYM()`, specify the names corresponding to operators (see `MRuby::Presym::OPERATORS` in `lib/mruby/presym.rb` for the names that diff --git a/doc/limitations.md b/doc/limitations.md index d903d528c..265e4a2d4 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -13,28 +13,6 @@ This document is collecting these limitations. This document does not contain a complete list of limitations. Please help to improve it by submitting your findings. -## `Array` passed to `puts` - -Passing an Array to `puts` results in different output. - -```ruby -puts [1,2,3] -``` - -#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] - -``` -1 -2 -3 -``` - -#### mruby [3.0.0 (2021-03-05)] - -``` -[1, 2, 3] -``` - ## `Kernel.raise` in rescue clause `Kernel.raise` without arguments does not raise the current exception within @@ -54,7 +32,7 @@ end #### mruby [3.0.0 (2021-03-05)] -No exception is raised. Instead, you have to do: +`RuntimeError` is raised instead of `ZeroDivisionError`. To re-raise the exception, you have to do: ```ruby begin @@ -77,7 +55,7 @@ To reduce memory consumption `Array` does not support instance variables. ```ruby class Liste < Array def initialize(str = nil) - @feld = str + @field = str end end diff --git a/doc/mruby3.md b/doc/mruby3.md index d5218428e..a64e3c73e 100644 --- a/doc/mruby3.md +++ b/doc/mruby3.md @@ -1,5 +1,4 @@ -User visible changes in `mruby3` -=== +# User visible changes in `mruby3` # Build System @@ -77,8 +76,9 @@ to be default `mrb_value` representation. Now the default is Pack `mrb_value` in an `intptr_t` integer. Consumes less memory compared to `MRB_NO_BOXING` especially on 32-bit -platforms. `Fixnum` size is 31 bits, so some integer values -does not fit in `Fixnum` integers. +platforms. Inlined integer size is 31 bits, so some `mrb_int` +values does not fit in `mrb_value`. Those integers are allocated +in the object heap as `struct RInteger`. ## `MRB_NAN_BOXING` @@ -111,14 +111,9 @@ $ bin/mruby -r lib1.rb -r lib2.rb < app.mrb `mruby3` introduces a few new instructions. -Instructions that access pool[i]/syms[i] where i>255. - -* `OP_LOADL16` -* `OP_STRING16` -* `OP_LOADSYM16` - -Instructions that load a 32-bit integer. +Instructions that load a 16/32-bit integer. +* `OP_LOADI16` * `OP_LOADI32` Instruction that unwinds jump table for rescue/ensure. diff --git a/doc/opcode.md b/doc/opcode.md index 3ad09919c..953e9aeae 100644 --- a/doc/opcode.md +++ b/doc/opcode.md @@ -22,114 +22,110 @@ sign) of operands. ## 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] | -| OP_ASET | BBB | R(a)[c] = R(b) | -| OP_APOST | BBB | *R(a),R(a+1)..R(a+c) = R(a)[b..] | -| 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 | -|------------------|--------------|--------------------------------------------------------| +| Instruction Name | Operand type | Semantics | +|------------------|--------------|----------------------------------------------------------| +| `OP_NOP` | `-` | `no operation` | +| `OP_MOVE` | `BB` | `R(a) = R(b)` | +| `OP_LOADL` | `BB` | `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_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=m5:r1:m5:d1:lv4)` | +| `OP_ENTER` | `W` | `arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1)` | +| `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=m5:r1:m5:d1:lv4)` | +| `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` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` | +| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` | +| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` | +| `OP_ASET` | `BBB` | `R(a)[c] = R(b)` | +| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` | +| `OP_INTERN` | `B` | `R(a) = intern(R(a))` | +| `OP_STRING` | `BB` | `R(a) = str_dup(Pool(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` | `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(Irep(b),OP_L_LAMBDA)` | +| `OP_BLOCK` | `BB` | `R(a) = lambda(Irep(b),OP_L_BLOCK)` | +| `OP_METHOD` | `BB` | `R(a) = lambda(Irep(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),Irep[b])` | +| `OP_DEF` | `BB` | `R(a).newmethod(Syms(b),R(a+1)); R(a) = Syms(b)` | +| `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, Pool(a))` | +| `OP_EXT1` | `-` | `make 1st operand 16bit` | +| `OP_EXT2` | `-` | `make 2nd operand 16bit` | +| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` | +| `OP_STOP` | `-` | `stop VM` | +|------------------|--------------|----------------------------------------------------------| |
