summaryrefslogtreecommitdiffhomepage
path: root/doc
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-07-17 10:35:41 +0900
committerGitHub <[email protected]>2019-07-17 10:35:41 +0900
commitd605b72c1d6fa4564a0a5e88535504b6850463b5 (patch)
tree774fc0de56002abb3bb2b1c3387ff08f91876d17 /doc
parent2af92d0ebcbeca6d3d85a27c8193273080a63090 (diff)
parent9af3b7c6258de327218dd04e69d76ae68caf17b1 (diff)
downloadmruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.tar.gz
mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.zip
Merge branch 'master' into i110/inspect-recursion
Diffstat (limited to 'doc')
-rw-r--r--doc/guides/debugger.md2
-rw-r--r--doc/guides/mrbconf.md56
-rw-r--r--doc/guides/mrbgems.md4
-rw-r--r--doc/limitations.md76
-rw-r--r--doc/opcode.md127
5 files changed, 249 insertions, 16 deletions
diff --git a/doc/guides/debugger.md b/doc/guides/debugger.md
index 1cc7a9a39..81c0e9d63 100644
--- a/doc/guides/debugger.md
+++ b/doc/guides/debugger.md
@@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option:
```bash
$ mrdb --version
-mruby 1.4.1 (2018-4-27)
+mruby 2.0.1 (2019-4-4)
```
## 2.2 Basic Operation
diff --git a/doc/guides/mrbconf.md b/doc/guides/mrbconf.md
index f957f8ce2..3c20b3388 100644
--- a/doc/guides/mrbconf.md
+++ b/doc/guides/mrbconf.md
@@ -50,15 +50,21 @@ You can use mrbconfs with following ways:
* When defined single precision floating point type(C type `float`) is used as `mrb_float`.
* Else double precision floating point type(C type `double`) is used as `mrb_float`.
+`MRB_WITHOUT_FLOAT`
+* When defined removes floating point numbers from mruby.
+* It makes mruby easier to handle in "Microcontroller without FPU" and "Kernel Space".
+
`MRB_INT16`
* When defined `int16_t` will be defined as `mrb_int`.
-* Conflicts with `MRB_INT64`.
+* Conflicts with `MRB_INT32` and `MRB_INT64`.
+
+`MRB_INT32`
+* When defined, or both `MRB_INT16` and `MRB_INT64` are not defined on 32-bit CPU mode, `int32_t` will be defined as `mrb_int`.
+* Conflicts with `MRB_INT16` and `MRB_INT64`.
`MRB_INT64`
-* When defined `int64_t` will be defined as `mrb_int`.
-* Conflicts with `MRB_INT16`.
-* When `MRB_INT16` or `MRB_INT64` isn't defined `int`(most of the times 32-bit integer)
-will be defined as `mrb_int`.
+* When defined, or both `MRB_INT16` and `MRB_INT32` are not defined on 64-bit CPU mode, `int64_t` will be defined as `mrb_int`.
+* Conflicts with `MRB_INT16` and `MRB_INT32`.
## Garbage collector configuration.
@@ -115,7 +121,7 @@ largest value of required alignment.
`MRB_NAN_BOXING`
* If defined represent `mrb_value` in boxed `double`.
-* Conflicts with `MRB_USE_FLOAT`.
+* Conflicts with `MRB_USE_FLOAT` and `MRB_WITHOUT_FLOAT`.
`MRB_WORD_BOXING`
* If defined represent `mrb_value` as a word.
@@ -126,6 +132,27 @@ largest value of required alignment.
* Default value is `4`.
* Specifies size of each segment in segment list.
+## Reduce heap memory configuration.
+
+`MRB_USE_ETEXT_EDATA`
+* 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 `_etext` and `__init_array_start`.
+* It must be `_etext < data_addr < &__init_array_start`.
+
+`MRB_NO_INIT_ARRAY_START`
+* Ignored if `MRB_USE_ETEXT_EDATA` is not defined.
+* Please try if `__init_array_start` is not available.
+* Uses `_etext` and `_edata`.
+* It must be `_etext < data_addr < _edata`.
+
+`MRB_USE_CUSTOM_RO_DATA_P`
+* Takes precedence over `MRB_USE_ETEXT_EDATA`.
+* Please try if both `MRB_USE_ETEXT_EDATA` and `MRB_NO_INIT_ARRAY_START` are 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)`.
+* Return `TRUE` if `ptr` is in read-only section, otherwise return `FALSE`.
+
## Other configuration.
`MRB_UTF8_STRING`
* Adds UTF-8 encoding support to character-oriented String instance methods.
@@ -144,3 +171,20 @@ largest value of required alignment.
`MRB_STR_BUF_MIN_SIZE`
* Default value is `128`.
* Specifies initial capacity of `RString` created by `mrb_str_buf_new` function..
+
+`MRB_METHOD_CACHE`
+* Improve performance for method dispatch.
+
+`MRB_METHOD_CACHE_SIZE`
+* Default value is `128`.
+* Ignored if `MRB_METHOD_CACHE` is not defined.
+* Need to be the power of 2.
+
+`MRB_METHOD_TABLE_INLINE`
+* Reduce the size of method table.
+* Requires LSB of function pointers to be zero.
+* For example, you might need to specify `--falign-functions=n` (where `n > 1`) for GCC.
+
+`MRB_ENABLE_ALL_SYMBOLS`
+* Make it available `Symbols.all_symbols` in `mrbgems/mruby-symbol-ext`
+* Increase heap memory usage.
diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md
index 8dac0dc86..0fcc936ed 100644
--- a/doc/guides/mrbgems.md
+++ b/doc/guides/mrbgems.md
@@ -179,11 +179,11 @@ Version requirement supports following operators:
When more than one version requirements is passed, the dependency must satisfy all of it.
-You can have default gem to use as depedency when it's not defined in *build_config.rb*.
+You can have default gem to use as dependency when it's not defined in *build_config.rb*.
When the last argument of `add_dependency` call is `Hash`, it will be treated as default gem information.
Its format is same as argument of method `MRuby::Build#gem`, expect that it can't be treated as path gem location.
-When a special version of depedency is required,
+When a special version of dependency is required,
use `MRuby::Build#gem` in *build_config.rb* to override default gem.
If you have conflicting GEMs use the following method:
diff --git a/doc/limitations.md b/doc/limitations.md
index 9d8924cff..9b4ed9c6f 100644
--- a/doc/limitations.md
+++ b/doc/limitations.md
@@ -38,7 +38,7 @@ puts [1,2,3]
3
```
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
```
[1, 2, 3]
@@ -61,7 +61,7 @@ end
```ZeroDivisionError``` is raised.
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
No exception is raised.
@@ -89,7 +89,7 @@ p Liste.new "foobar"
``` [] ```
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
```ArgumentError``` is raised.
@@ -119,7 +119,7 @@ false
true
```
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
```
true
@@ -142,7 +142,7 @@ defined?(Foo)
nil
```
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
```NameError``` is raised.
@@ -159,7 +159,7 @@ alias $a $__a__
``` nil ```
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
Syntax error
@@ -181,7 +181,69 @@ end
```ArgumentError``` is raised.
The re-defined ```+``` operator does not accept any arguments.
-#### mruby [1.4.1 (2018-4-27)]
+#### mruby [2.0.1 (2019-4-4)]
``` 'ab' ```
Behavior of the operator wasn't changed.
+
+## Kernel#binding is not supported
+
+`Kernel#binding` method is not supported.
+
+#### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)]
+
+```
+$ ruby -e 'puts Proc.new {}.binding'
+#<Binding:0x00000e9deabb9950>
+```
+
+#### mruby [2.0.1 (2019-4-4)]
+
+```
+$ ./bin/mruby -e 'puts Proc.new {}.binding'
+trace (most recent call last):
+ [0] -e:1
+-e:1: undefined method 'binding' (NoMethodError)
+```
+
+## Keyword arguments
+
+mruby keyword arguments behave slightly different from CRuby 2.5
+to make the behavior simpler and less confusing. Maybe in the
+future, the simpler behavior will be adopted to CRuby as well.
+
+#### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)]
+
+```
+$ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
+[[{"a"=>1}], {:b=>2}]
+```
+
+#### mruby [mruby 2.0.1]
+
+```
+$ ./bin/mruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
+trace (most recent call last):
+ [0] -e:1
+-e:1: keyword argument hash with non symbol keys (ArgumentError)
+```
+
+## Argument Destructuring
+
+```ruby
+def m(a,(b,c),d); p [a,b,c,d]; end
+m(1,[2,3],4) # => [1,2,3,4]
+```
+Destructured arguments (`b` and `c` in above example) cannot be accessed
+from the default expression of optional arguments and keyword arguments,
+since actual assignment is done after the evaluation of those default
+expressions. Thus:
+
+```ruby
+def f(a,(b,c),d=b)
+ p [a,b,c,d]
+end
+f(1,[2,3])
+```
+
+CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`.
diff --git a/doc/opcode.md b/doc/opcode.md
new file mode 100644
index 000000000..eab82a26f
--- /dev/null
+++ b/doc/opcode.md
@@ -0,0 +1,127 @@
+# The new bytecode
+
+We will reimplement 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
+* sB: signed 8bit
+* S: 16bit
+* sS: signed 16bit
+* W: 24bit
+
+First two byte operands may be extended to 16bit. When those byte
+operands are bigger than 256, the instruction will be prefixed by
+`OP_EXT1` (means 1st operand is 16bit) or `OP_EXT2` (means 2nd operand
+is 16bit) or `OP_EXT3` (means 1st and 2nd operands are 16bit).
+
+For instructions marked by `'`, `OP_EXT1` can be prefixed. For those
+with `"`, either `OP_EXT1` or `OP_EXT2` or `OP_EXT2` can be prefixed.
+
+## table.1 Instruction Table
+
+|Instruction Name |Operand type |Semantics
+|-----------------|-------------|-----------------
+|OP_NOP | - |
+|OP_MOVE" |BB |R(a) = R(b)
+|OP_LOADL" |BB |R(a) = Pool(b)
+|OP_LOADI" |BsB |R(a) = mrb_int(b)
+|OP_LOADI_0' |B |R(a) = 0
+|OP_LOADI_1' |B |R(a) = 1
+|OP_LOADI_2' |B |R(a) = 2
+|OP_LOADI_3' |B |R(a) = 3
+|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[b]
+|OP_SETSV" |BB |Special[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' |SB |if R(b) pc+=a
+|OP_JMPNOT' |SB |if !R(b) pc+=a
+|OP_ONERR |sS |rescue_push(pc+a)
+|OP_EXCEPT' |B |R(a) = exc
+|OP_RESCUE" |BB |R(b) = R(a).isa?(R(b))
+|OP_POPERR |B |a.times{rescue_pop()}
+|OP_RAISE' |B |raise(R(a))
+|OP_EPUSH' |B |ensure_push(SEQ[a])
+|OP_EPOP |B |A.times{ensure_pop().call}
+|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(Bx),R(a+1),...,R(a+c),&R(a+c+1))
+|OP_CALL' |B |R(a) = 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_KARG" |BB |R(a) = kdict[Syms(Bx)] # todo
+|OP_KARG2" |BB |R(a) = kdict[Syms(Bx)]; kdict.rm(Syms(b)) # todo
+|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" |BB |R(a) = R(a)+R(a+1)
+|OP_ADDI" |BBB |R(a) = R(a)+mrb_int(c)
+|OP_SUB" |BB |R(a) = R(a)-R(a+1)
+|OP_SUBI" |BB |R(a) = R(a)-C
+|OP_MUL" |BB |R(a) = R(a)*R(a+1)
+|OP_DIV" |BB |R(a) = R(a)/R(a+1)
+|OP_EQ" |BB |R(a) = R(a)==R(a+1)
+|OP_LT" |BB |R(a) = R(a)<R(a+1)
+|OP_LE" |BB |R(a) = R(a)<=R(a+1)
+|OP_GT" |BB |R(a) = R(a)>R(a+1)
+|OP_GE" |BB |R(a) = R(a)>=R(a+1)
+|OP_ARRAY' |BB |R(a) = ary_new(R(a),R(a+1)..R(a+b))
+|OP_ARRAY2" |BB |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_AREF' |BB |R(a) = R(a)[b]
+|OP_ASET' |BB |R(a)[b] = R(a+1)
+|OP_APOST' |BB |*R(a),R(A+1)..R(A+C) = R(a)[B..]
+|OP_STRING" |BB |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))
+|OP_HASHADD' |BB |R(a) = hash_push(R(a),R(a+1)..R(a+b))
+|OP_LAMBDA" |BB |R(a) = lambda(SEQ[b],OP_L_LAMBDA)
+|OP_BLOCK" |BB |R(a) = lambda(SEQ[b],OP_L_BLOCK)
+|OP_METHOD" |BB |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_DEF" |BB |R(a).newmethod(Syms(b),R(a+1))
+|OP_ALIAS' |B |alias_method(R(a),R(a+1),R(a+2))
+|OP_UNDEF" |BB |undef_method(R(a),Syms(b))
+|OP_SCLASS' |B |R(a) = R(a).singleton_class
+|OP_TCLASS' |B |R(a) = target_class
+|OP_ERR' |B |raise(RuntimeError, Lit(Bx))
+|OP_EXT1 |- |make 1st operand 16bit
+|OP_EXT2 |- |make 2nd operand 16bit
+|OP_EXT3 |- |make 1st and 2nd operands 16bit
+|OP_STOP |- |stop VM