From 657d06958262a8f9f1c0c4c4754adc7f328a7c04 Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Tue, 6 Oct 2015 14:26:48 -0300 Subject: Move guides location --- .gitignore | 2 +- .yardopts | 4 +- doc/api/gc-arena-howto.md | 171 --------------- doc/guides/compile.md | 481 +++++++++++++++++++++++++++++++++++++++++++ doc/guides/debugger.md | 370 +++++++++++++++++++++++++++++++++ doc/guides/gc-arena-howto.md | 171 +++++++++++++++ doc/guides/mrbconf.md | 160 ++++++++++++++ doc/guides/mrbgems.md | 337 ++++++++++++++++++++++++++++++ guides/compile.md | 481 ------------------------------------------- guides/debugger.md | 370 --------------------------------- guides/mrbconf.md | 160 -------------- guides/mrbgems.md | 337 ------------------------------ 12 files changed, 1523 insertions(+), 1521 deletions(-) delete mode 100644 doc/api/gc-arena-howto.md create mode 100644 doc/guides/compile.md create mode 100644 doc/guides/debugger.md create mode 100644 doc/guides/gc-arena-howto.md create mode 100644 doc/guides/mrbconf.md create mode 100644 doc/guides/mrbgems.md delete mode 100644 guides/compile.md delete mode 100755 guides/debugger.md delete mode 100644 guides/mrbconf.md delete mode 100644 guides/mrbgems.md diff --git a/.gitignore b/.gitignore index ba4da68f4..800680821 100644 --- a/.gitignore +++ b/.gitignore @@ -21,5 +21,5 @@ cscope.out /bin /build /mruby-source-*.gem -doc +doc/api .yardoc diff --git a/.yardopts b/.yardopts index af8937b55..017b7ce70 100644 --- a/.yardopts +++ b/.yardopts @@ -1,6 +1,8 @@ +--plugin mruby --plugin coderay +--output-dir doc/api - AUTHORS MITL CONTRIBUTING.md -guides/*.md +doc/guides/*.md diff --git a/doc/api/gc-arena-howto.md b/doc/api/gc-arena-howto.md deleted file mode 100644 index f2a0448bd..000000000 --- a/doc/api/gc-arena-howto.md +++ /dev/null @@ -1,171 +0,0 @@ -# How to use `mrb_gc_arena_save()`/`mrb_gc_arena_restore()` - -This is basically English translation of [Matz's blog post](http://www.rubyist.net/~matz/20130731.html) written in Japanese. -Some parts are updated to reflect recent changes. - -When you are extending mruby using C language, you may encounter -mysterious "arena overflow error" or memory leak or very slow -execution speed. This is an error indicating overflow of "GC arena" -implementing "conservative GC". - -GC (garbage collector) must ensure that object is "alive", in other -words, that it is referenced by somewhere from program. This can be -determined by checking that that object can be directly or indirectly -referenced by root. The local variables, global variables and -constants etc are root. - -If program execution is performed inside mruby VM, there is nothing to -worry about because GC can access all roots owned by VM. - -The problem arises when executing C functions. The object referenced -by C variable is also "alive", but mruby GC cannot aware of this, so -it might mistakenly recognize the objects referenced by only C -variables as dead. - -It is a fatal bug for GC to collect live objects. - -In CRuby, we scan C stack area, and use C variable as root to check -whether object is alive or not. Of course, because we are accessing C -stack just as memory region, we never know it is an integer or a -pointer. We workaround this by assuming that if it looks like a -pointer, then assume it as a pointer. We call it "conservative". - -By the way, CRuby's "conservative GC" has some problems. - -Its biggest problem is we have no way to access to the stack area in -portable way. Therefore, we cannot use this method if we'd like to -implement highly portable runtime, like mruby. - -So we came up an another plan to implement "conservative GC" in mruby. - -Again, the problem is that there is an object which was created in C -function, and is not referenced by Ruby world, and cannot be treated -as garbage. - -In mruby, we recognize all objects created in C function are alive. -Then we have no problem such as recognizing live object as dead. - -This means that because we cannot collect truly dead object, we may -get a little bit less efficiency, but GC itself is highly portable. -We can say goodbye to the problem that GC deletes live objects due to -optimization which sometimes occurs in CRuby. - -According to this idea, we have a table, called "GC arena", which -remembers objects created in C function. The arena is stack -structure, when C function execution is returned to mruby VM, all -objects registered in the arena are popped. - -This works very well, but GC arena causes another problem. "arena -overflow error" or memory leak. - -As of this writing, mruby automatically extend arena to remember -objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in -doc/mrbconf/README.md). If you keep creating objects in C functions, -it increases memory usage, since GC never kick in. This memory usage -may look like memory leak, and also makes execution slower. - -With the build time configuration, you can limit the maximum size of -arena (e.g., 100). Then if you create many objects, arena overflows, -thus you will get "arena overflow error". - -To workaround these problems, we have `mrb_gc_arena_save()` and -`mrb_gc_arena_restore()` functions. - -`int mrb_gc_arena_save(mrb)` returns the current position of the stack -top of GC arena, and `void mrb_gc_arena_restore(mrb, idx)` sets the -stack top position to back to given idx. We uses them like so: - -```c -int arena_idx = mrb_gc_arena_save(mrb); - -...create objects... -mrb_gc_arena_restore(mrb, arena_idx); - -``` - -In mruby, C function call are surrounded by this save/restore, but we -can further optimize memory usage by surrounding save/restore, and can -avoid arena overflow. - -Let's take a real example. Here is the source code of `Array#inspect`: - -```c -static mrb_value -inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) -{ - mrb_int i; - mrb_value s, arystr; - char head[] = { '[' }; - char sep[] = { ',', ' ' }; - char tail[] = { ']' }; - - /* check recursive */ - for(i=0; i 0) { - mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); - } - if (mrb_array_p(RARRAY_PTR(ary)[i])) { - s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); - } - else { - s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); - } - mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); - mrb_gc_arena_restore(mrb, ai); - } - - mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail)); - mrb_ary_pop(mrb, list); - - return arystr; -} -``` - -This is a real example, so a little bit complicated, so bear with me. -The essence of `Array#inspect` is that after stringifying each element -of array using `inspect` method, we join them together so that we can -get `inspect` representation of entire array. - -After the `inspect` representation of entire array is created, we no -longer require the individual string representation. That means that -we don't have to register these temporal objects into GC arena. - -Therefore, in `ary_inspect()` function, we do: - -* save the position of the stack top using `mrb_gc_arena_save()`. -* get `inspect` representation of each element. -* append it to the constructing entire `inspect` representation of array. -* restore stack top position using `mrb_gc_arena_restore()`. - -to keep the arena size small. - -Please note that the final `inspect` representation of entire array -was created before the call of `mrb_gc_arena_restore()`. Otherwise, -required temporal object may be deleted by GC. - -We may have a usecase that after creating many temporal objects, we'd -like to keep some of them. In this case, we cannot use the same idea -in `ary_inspect()` like appending objects to existing one. Instead, -after `mrb_gc_arena_restore()`, we register back the objects we'd like -to keep to the arena using `mrb_gc_protect(mrb, obj)`. Use -`mrb_gc_protect()` with caution because its usage could lead to arena -overflow error. - -We also have to mention that when `mrb_funcall` is called in top -level, its return value is also registered to GC arena, so calling -them repeatedly eventually lead to arena overflow error. Use -`mrb_gc_arena_save()` and `mrb_gc_arena_restore()` or possible use of -`mrb_gc_protect()` to workaround this. diff --git a/doc/guides/compile.md b/doc/guides/compile.md new file mode 100644 index 000000000..8e91e7546 --- /dev/null +++ b/doc/guides/compile.md @@ -0,0 +1,481 @@ +# Compile + +mruby uses Rake to compile and cross-compile all libraries and +binaries. + +## Prerequisites + +To compile mruby out of the source code you need the following tools: +* C Compiler (i.e. ```gcc```) +* Linker (i.e. ```gcc```) +* Archive utility (i.e. ```ar```) +* Parser generator (i.e. ```bison```) +* Ruby 1.8 or 1.9 (i.e. ```ruby``` or ```jruby```) + +Optional: +* GIT (to update mruby source and integrate mrbgems easier) +* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc) +* Assembler (to use GEMs which include \*.asm) + +## Usage + +Inside of the root directory of the mruby source a file exists +called *build_config.rb*. This file contains the build configuration +of mruby and looks like this for example: +```ruby +MRuby::Build.new do |conf| + toolchain :gcc +end +``` + +All tools necessary to compile mruby can be set or modified here. In case +you want to maintain an additional *build_config.rb* you can define a +customized path using the *$MRUBY_CONFIG* environment variable. + +To compile just call ```./minirake``` inside of the mruby source root. To +generate and execute the test tools call ```./minirake test```. To clean +all build files call ```./minirake clean```. To see full command line on +build, call ```./minirake -v```. + +## Build Configuration + +Inside of the *build_config.rb* the following options can be configured +based on your environment. + +### Toolchains + +The mruby build system already contains a set of toolchain templates which +configure the build environment for specific compiler infrastructures. + +#### GCC + +Toolchain configuration for the GNU C Compiler. +```ruby +toolchain :gcc +``` + +#### clang + +Toolchain configuration for the LLVM C Compiler clang. Mainly equal to the +GCC toolchain. +```ruby +toolchain :clang +``` + +#### Visual Studio 2010, 2012 and 2013 + +Toolchain configuration for Visual Studio on Windows. If you use the +[Visual Studio Command Prompt](http://msdn.microsoft.com/en-us/library/ms229859\(v=vs.110\).aspx), +you normally do not have to specify this manually, since it gets automatically detected by our build process. +``` +toolchain :visualcpp +``` + +#### Android + +Toolchain configuration for Android. +```ruby +toolchain :androideabi +``` + +Requires the custom standalone Android NDK and the toolchain path +in ```ANDROID_STANDALONE_TOOLCHAIN```. + +### Binaries + +It is possible to select which tools should be compiled during the compilation +process. The following tools can be selected: +* mruby (mruby interpreter) +* mirb (mruby interactive shell) + +To select them declare conf.gem as follows: +```ruby +conf.gem "#{root}/mrbgems/mruby-bin-mruby" +conf.gem "#{root}/mrbgems/mruby-bin-mirb" +``` + +### File Separator + +Some environments require a different file separator character. It is possible to +set the character via ```conf.file_separator```. +```ruby +conf.file_separator = '/' +``` + +### C Compiler + +Configuration of the C compiler binary, flags and include paths. +```ruby +conf.cc do |cc| + cc.command = ... + cc.flags = ... + cc.include_paths = ... + cc.defines = ... + cc.option_include_path = ... + cc.option_define = ... + cc.compile_options = ... +end +``` + +C Compiler has header searcher to detect installed library. + +If you need a include path of header file use ```search_header_path```: +```ruby +# Searches ```iconv.h```. +# If found it will return include path of the header file. +# 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```. +# If found it will return full path of the header file. +# Otherwise it will return nil . +iconv_h = conf.cc.search_header 'iconv.h' +print "iconv.h found: #{iconv_h}\n" +``` + +Header searcher uses compiler's ```include_paths``` by default. +When you are using GCC toolchain (including clang toolchain since its base is gcc toolchain) +it will use compiler specific include paths too. (For example ```/usr/local/include```, ```/usr/include```) + +If you need a special header search paths define a singleton method ```header_search_paths``` to C compiler: +```ruby +def conf.cc.header_search_paths + ['/opt/local/include'] + include_paths +end +``` + +### Linker + +Configuration of the Linker binary, flags and library paths. +```ruby +conf.linker do |linker| + linker.command = ... + linker.flags = ... + linker.flags_before_libraries = ... + linker.libraries = ... + linker.flags_after_libraries = ... + linker.library_paths = .... + linker.option_library = ... + linker.option_library_path = ... + linker.link_options = ... +end +``` + +### Archiver + +Configuration of the Archiver binary and flags. +```ruby +conf.archiver do |archiver| + archiver.command = ... + archiver.archive_options = ... +end +``` + +### Parser Generator + +Configuration of the Parser Generator binary and flags. +```ruby +conf.yacc do |yacc| + yacc.command = ... + yacc.compile_options = ... +end +``` + +### GPerf + +Configuration of the GPerf binary and flags. +```ruby +conf.gperf do |gperf| + gperf.command = ... + gperf.compile_options = ... +end +``` + +### File Extensions +```ruby +conf.exts do |exts| + exts.object = ... + exts.executable = ... + exts.library = ... +end +``` + +### Mrbgems + +Integrate GEMs in the build process. +```ruby +# Integrate GEM with additional configuration +conf.gem 'path/to/gem' do |g| + g.cc.flags << ... +end + +# Integrate GEM without additional configuration +conf.gem 'path/to/another/gem' +``` + +See doc/mrbgems/README.md for more option about mrbgems. + +### Mrbtest + +Configuration Mrbtest build process. + +If you want mrbtest.a only, You should set ```conf.build_mrbtest_lib_only``` +```ruby +conf.build_mrbtest_lib_only +``` + +### Bintest + +Tests for mrbgem tools using CRuby. +To have bintests place \*.rb scripts to ```bintest/``` directory of mrbgems. +See ```mruby-bin-*/bintest/*.rb``` if you need examples. +If you want a temporary files use `tempfile` module of CRuby instead of ```/tmp/```. + +You can enable it with following: +```ruby +conf.enable_bintest +``` + +### C++ ABI + +mruby can use C++ exception to raise exception internally. +It is called C++ ABI mode. +By using C++ exception it can release C++ stack object correctly. +Whenever you mix C++ code C++ ABI mode would be enabled automatically. +If you need to enable C++ ABI mode explicitly add the following: +```ruby +conf.enable_cxx_abi +``` + +#### C++ exception disabling. + +If you need to force C++ exception disable +(For example using a compiler option to disable C++ exception) +add following: +```ruby +conf.disable_cxx_exception +``` + +Note that it must be called before ```enable_cxx_abi``` or ```gem``` method. + +### Debugging mode + +To enable debugging mode add the following: +```ruby +conf.enable_debug +``` + +When debugging mode is enabled +* Macro ```MRB_DEBUG``` would be defined. + * 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. + * You can have better backtrace of mruby scripts with this. + +## Cross-Compilation + +mruby can also be cross-compiled from one platform to another. To +achieve this the *build_config.rb* needs to contain an instance of +```MRuby::CrossBuild```. This instance defines the compilation +tools and flags for the target platform. An example could look +like this: +```ruby +MRuby::CrossBuild.new('32bit') do |conf| + toolchain :gcc + + conf.cc.flags << "-m32" + conf.linker.flags << "-m32" +end +``` + +All configuration options of ```MRuby::Build``` can also be used +in ```MRuby::CrossBuild```. + +### Mrbtest in Cross-Compilation + +In cross compilation, you can run ```mrbtest``` on emulator if +you have it by changing configuration of test runner. +```ruby +conf.test_runner do |t| + t.command = ... # set emulator. this value must be non nil or false + t.flags = ... # set flags of emulator + + def t.run(bin) # override `run` if you need to change the behavior of it + ... # `bin` is the full path of mrbtest + end +end +``` + +## Build process + +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 + | + +- bin <- Binaries (mirb, mrbc and mruby) + | + +- lib <- Libraries (libmruby.a and libmruby_core.a) + | + +- mrblib + | + +- src + | + +- test <- mrbtest tool + | + +- tools + | + +- mirb + | + +- mrbc + | + +- mruby + +The compilation workflow will look like this: +* compile all files under *src* (object files will be stored +in *build/host/src*) +* generate parser grammar out of *src/parse.y* (generated +result will be stored in *build/host/src/y.tab.c*) +* compile *build/host/src/y.tab.c* to *build/host/src/y.tab.o* +* create *build/host/lib/libmruby_core.a* out of all object files (C only) +* create ```build/host/bin/mrbc``` by compiling *tools/mrbc/mrbc.c* and +linking with *build/host/lib/libmruby_core.a* +* create *build/host/mrblib/mrblib.c* by compiling all \*.rb files +under *mrblib* with ```build/host/bin/mrbc``` +* compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* +* create *build/host/lib/libmruby.a* out of all object files (C and Ruby) +* create ```build/host/bin/mruby``` by compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and +linking with *build/host/lib/libmruby.a* +* create ```build/host/bin/mirb``` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and +linking with *build/host/lib/libmruby.a* + +``` + _____ _____ ______ ____ ____ _____ _____ ____ +| CC |->|GEN |->|AR |->|CC |->|CC |->|AR |->|CC |->|CC | +| *.c | |y.tab| |core.a| |mrbc| |*.rb| |lib.a| |mruby| |mirb| + ----- ----- ------ ---- ---- ----- ----- ---- +``` + +### Cross-Compilation + +In case of a cross-compilation to *i386* the *build* directory structure looks +like this: + + +- build + | + +- host + | | + | +- bin <- Native Binaries + | | + | +- lib <- Native Libraries + | | + | +- mrblib + | | + | +- src + | | + | +- test <- Native mrbtest tool + | | + | +- tools + | | + | +- mirb + | | + | +- mrbc + | | + | +- mruby + +- i386 + | + +- bin <- Cross-compiled Binaries + | + +- lib <- Cross-compiled Libraries + | + +- mrblib + | + +- src + | + +- test <- Cross-compiled mrbtest tool + | + +- tools + | + +- mirb + | + +- mrbc + | + +- mruby + +An extra directory is created for the target platform. In case you +compile for *i386* a directory called *i386* is created under the +build directory. + +The cross compilation workflow starts in the same way as the normal +compilation by compiling all *native* libraries and binaries. +Afterwards the cross compilation process proceeds like this: +* cross-compile all files under *src* (object files will be stored +in *build/i386/src*) +* generate parser grammar out of *src/parse.y* (generated +result will be stored in *build/i386/src/y.tab.c*) +* cross-compile *build/i386/src/y.tab.c* to *build/i386/src/y.tab.o* +* create *build/i386/mrblib/mrblib.c* by compiling all \*.rb files +under *mrblib* with the native ```build/host/bin/mrbc``` +* cross-compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* +* create *build/i386/lib/libmruby.a* out of all object files (C and Ruby) +* create ```build/i386/bin/mruby``` by cross-compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and +linking with *build/i386/lib/libmruby.a* +* create ```build/i386/bin/mirb``` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and +linking with *build/i386/lib/libmruby.a* +* create *build/i386/lib/libmruby_core.a* out of all object files (C only) +* create ```build/i386/bin/mrbc``` by cross-compiling *tools/mrbc/mrbc.c* and +linking with *build/i386/lib/libmruby_core.a* + +``` + _______________________________________________________________ +| Native Compilation for Host System | +| _____ ______ _____ ____ ____ _____ | +| | CC | -> |AR | -> |GEN | -> |CC | -> |CC | -> |AR | | +| | *.c | |core.a| |y.tab| |mrbc| |*.rb| |lib.a| | +| ----- ------ ----- ---- ---- ----- | + --------------------------------------------------------------- + || + \||/ + \/ + ________________________________________________________________ +| Cross Compilation for Target System | +| _____ _____ _____ ____ ______ _____ | +| | CC | -> |AR | -> |CC | -> |CC | -> |AR | -> |CC | | +| | *.c | |lib.a| |mruby| |mirb| |core.a| |mrbc | | +| ----- ----- ----- ---- ------ ----- | + ---------------------------------------------------------------- +``` + +## Build Configuration Examples + +### Minimal Library + +To build a minimal mruby library you need to use the Cross Compiling +feature due to the reason that there are functions (i.e. stdio) which +can't be disabled for the main build. + +```ruby +MRuby::CrossBuild.new('Minimal') do |conf| + toolchain :gcc + + conf.cc.defines = %w(DISABLE_STDIO) + conf.bins = [] +end +``` + +This configuration defines a cross compile build called 'Minimal' which +is using the GCC and compiles for the host machine. It also disables +all usages of stdio and doesn't compile any binaries (i.e. mrbc). + +## Test Environment + +mruby's build process includes a test environment. In case you start the testing +of mruby, a native binary called ```mrbtest``` will be generated and executed. +This binary contains all test cases which are defined under *test/t*. In case +of a cross-compilation an additional cross-compiled *mrbtest* binary is +generated. You can copy this binary and run on your target system. diff --git a/doc/guides/debugger.md b/doc/guides/debugger.md new file mode 100644 index 000000000..a13e91cec --- /dev/null +++ b/doc/guides/debugger.md @@ -0,0 +1,370 @@ +# How to Use the mruby Debugger + +copyright (c) 2014 Specified Non-Profit Corporation mruby Forum + +## 1. Summary + +This file documents the mruby debugger ('mrdb') methods. + +## 2 Debugging with mrdb + +## 2.1 Building mrdb + +The trunk of the mruby source tree, with the most recent mrdb, can be checked out with the following command: + +```bash +$ git clone https://github.com/mruby/mruby.git +``` + +To run the `make` command: + +```bash +$ cd mruby +$ make +``` + +By default, the `make` command will install the debugger files into mruby/bin. + +You can add the path for mrdb on your host environment with the following command: + +```bash +$ echo "export PATH=\$PATH:MRUBY_ROOT/bin" >> ~/.bashrc +$ source ~/.bashrc +``` + +`*MRUBY_ROOT` is the directory in which mruby source code will be installed. + +To confirm mrdb was installed properly, run mrdb with the `--version` option: + +```bash +$ mrdb --version +mruby 1.1.0 (2014-11-19) +``` + +## 2.2 Basic Operation + +### 2.2.1 Debugging mruby Script Files (rb file) with mrdb + +To invoke the mruby debugger, just type `mrdb`. + +To specify the script file: + +```bash +$ mrdb [option] file name +``` + +For example: Debugging sample.rb + +```bash +$ mrdb sample.rb +``` + +You can execute the shell commands listed below: + +|command|description| +|:-:|:--| +|run|execute programs| +|step|execute stepping| +|continue|execute continuing program| +|break|configure the breaking point| +|delete|deleting the breaking points| +|disable|disabling the breaking points| +|enable|enabling the breaking points| +|info breakpoints|showing list of the breaking points| +|print|evaluating and printing the values of the mruby expressions in the script| +|list|displaying the source cords| +|help|showing help| +|quit|terminating the mruby debugger| + +### 2.2.2 Debugging mruby Binary Files (mrb file) with mrdb + +You can debug the mruby binary files. + +#### 2.2.2.1 Debugging the binary files + +* notice +To debug mruby binary files, you need to compile mruby files with option `-g`. + +```bash +$ mrbc -g sample.rb +``` + +You can debug the mruby binary files with following command and the option `-b`. + +```bash +$ mrdb -b sample.mrb +``` + +Then you can execute all debugger shell commands. + +#### Break Command + +You can use any breakpoint to stop the program by specifying the line number and method name. +The breakpoint list will be displayed after you have set the breakpoint successfully. + +Usage: + +``` +break [file:]linenum +b [file:]linenum +break [class:]method +b [class:]method +``` + +The breakpoint will be ordered in serial from 1. +The number, which was given to the deleted breakpoint, will never be given to another breakpoint again. + +You can give multiple breakpoints to specified the line number and method. +Be ware that breakpoint command will not check the validity of the class name and method name. + +You can get the current breakpoint information by the following options. + +breakpoint breakpoint number : file name. line number + +breakpoint breakpoint number : [class name,] method name + +#### Continue Command + +Usage: + +``` +continue [N] +c [N] +``` + +N: the next breakpoint number + +When resuming the program, it will stop at breakpoint N (N-1 breakpoint will be ignored). + +When you run the `continue` command without specifying N, the program will be stopped at the next breakpoint. + +Example: + +``` +(foo.rb:1) continue 3 +``` + +This will resume the program and stop it at the third breakpoint. + +#### Delete Command + +This will delete the specified breakpoint. + +Usage: + +``` +delete [breakpoint-no] +d [breakpoint-no] +``` + +breakpoint-no: breakpoint number + +Example: + +``` +(foo.rb:1) delete +``` + +This will delete all of the breakpoints. + +``` +(foo.rb:1) delete 1 3 +``` + +This will delete the breakpoint at 1 and 3. + +#### Disable Command + +This will disable the specified breakpoint. + +Usage: + +``` +disable [breakpoint-no] +dis [breakpoint-no] +``` + +reappointing: breakpoint number + +Example: + +``` +(foo.rb:1) disable +``` + +Use `disable` if you would like to disable all of the breakpoints. + +``` +(foo.rb:1) disable 1 3 +``` + +This will disable the breakpoints at 1 and 3. + +#### Enable Command + +This will enable the specified breakpoints. + +Usage: + +``` +enable [breakpoint-no] +e [breakpoint-no] +``` + +breakpoint-no: breakpoint number + +Example: + +``` +(foo.rb:1) enable +``` + +Enabling all breakpoints +``` +(foo.rb:1) enable 1 3 +``` + +Enabling the breakpoint 1 and 3 + +#### eval command + +Evaluating the string as source code and printing the value. + +Same as print command, please see print command. + +#### help command + +Displaying the help message. + +Usage: + +``` +help [command] +h [command] +``` + +Typing `help` without any options will display the command list. + +#### Info Breakpoints Command + +Displaying the specified breakpoint information. + +Usage: + +``` +info breakpoints [breakpoint-no] +i b [breakpoint-no] +``` + +breakpoint-no: breakpoint number + +Typing "info breakpoints" without ant option will display all breakpoint information. +Example: + +``` +(sample.rb:1) info breakpoints +Num Type Enb What +1 breakpoint y at sample.rb:3 -> file name,line number +2 breakpoint n in Sample_class:sample_class_method -> [class:]method name +3 breakpoint y in sample_global_method +``` + +Displaying the specified breakpoint number: + +``` +(foo.rb:1) info breakpoints 1 3 +Num Type Enb What +1 breakpoint y at sample.rb:3 +3 breakpoint y in sample_global_method +``` + +#### List Command + +To display the code of the source file. + +Usage: + +``` +list [filename:]first[,last] +l [filename]:first[,last] +``` + +first: the opening row number +last : the closing row number + +When you specify the `first`, but not the `last` option, you will receive 10 rows. +When you do not specify both the `first` and `last` options, you will receive the next 10 rows. + +Example: + +``` +Specifying file name and first row number +sample.rb:1) list sample2.rb:5 +``` + +Specifying the file name and the first and last row number: + +``` +(sample.rb:1) list sample2.rb:6,7 +``` + +#### Print Command + +Evaluating the string as source code and printing the value. + +Usage: + +``` +print [expr] +p [expr] +``` + +expr: expression + +The expression is mandatory. +The displayed expressions will be serially ordered from 1. +If an exception occurs, the exception information will be displayed and the debugging will be continued. + +Example: + +``` +(sample.rb:1) print 1+2 +$1 = 3 +(sample.rb:1) print self +$2 = main +``` + +Below is the case of the exception: + +``` +(sample.rb:1) print (1+2 +$1 = SyntaxError: line 1: syntax error, unexpected $end, expecting ')' +``` + +#### Quit Command + +Quitting the debugger. + +Usage: + +``` +quit +q +``` + +#### Run Command + +Running the program and stopping at the first breakpoint. + +Usage: + +``` +run +r +``` + +#### Step Command + +This will run the program step by step. +When the method and the block are invoked, the program will be stop at the first row. +The program, which is developed in C, will be ignored. diff --git a/doc/guides/gc-arena-howto.md b/doc/guides/gc-arena-howto.md new file mode 100644 index 000000000..f2a0448bd --- /dev/null +++ b/doc/guides/gc-arena-howto.md @@ -0,0 +1,171 @@ +# How to use `mrb_gc_arena_save()`/`mrb_gc_arena_restore()` + +This is basically English translation of [Matz's blog post](http://www.rubyist.net/~matz/20130731.html) written in Japanese. +Some parts are updated to reflect recent changes. + +When you are extending mruby using C language, you may encounter +mysterious "arena overflow error" or memory leak or very slow +execution speed. This is an error indicating overflow of "GC arena" +implementing "conservative GC". + +GC (garbage collector) must ensure that object is "alive", in other +words, that it is referenced by somewhere from program. This can be +determined by checking that that object can be directly or indirectly +referenced by root. The local variables, global variables and +constants etc are root. + +If program execution is performed inside mruby VM, there is nothing to +worry about because GC can access all roots owned by VM. + +The problem arises when executing C functions. The object referenced +by C variable is also "alive", but mruby GC cannot aware of this, so +it might mistakenly recognize the objects referenced by only C +variables as dead. + +It is a fatal bug for GC to collect live objects. + +In CRuby, we scan C stack area, and use C variable as root to check +whether object is alive or not. Of course, because we are accessing C +stack just as memory region, we never know it is an integer or a +pointer. We workaround this by assuming that if it looks like a +pointer, then assume it as a pointer. We call it "conservative". + +By the way, CRuby's "conservative GC" has some problems. + +Its biggest problem is we have no way to access to the stack area in +portable way. Therefore, we cannot use this method if we'd like to +implement highly portable runtime, like mruby. + +So we came up an another plan to implement "conservative GC" in mruby. + +Again, the problem is that there is an object which was created in C +function, and is not referenced by Ruby world, and cannot be treated +as garbage. + +In mruby, we recognize all objects created in C function are alive. +Then we have no problem such as recognizing live object as dead. + +This means that because we cannot collect truly dead object, we may +get a little bit less efficiency, but GC itself is highly portable. +We can say goodbye to the problem that GC deletes live objects due to +optimization which sometimes occurs in CRuby. + +According to this idea, we have a table, called "GC arena", which +remembers objects created in C function. The arena is stack +structure, when C function execution is returned to mruby VM, all +objects registered in the arena are popped. + +This works very well, but GC arena causes another problem. "arena +overflow error" or memory leak. + +As of this writing, mruby automatically extend arena to remember +objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in +doc/mrbconf/README.md). If you keep creating objects in C functions, +it increases memory usage, since GC never kick in. This memory usage +may look like memory leak, and also makes execution slower. + +With the build time configuration, you can limit the maximum size of +arena (e.g., 100). Then if you create many objects, arena overflows, +thus you will get "arena overflow error". + +To workaround these problems, we have `mrb_gc_arena_save()` and +`mrb_gc_arena_restore()` functions. + +`int mrb_gc_arena_save(mrb)` returns the current position of the stack +top of GC arena, and `void mrb_gc_arena_restore(mrb, idx)` sets the +stack top position to back to given idx. We uses them like so: + +```c +int arena_idx = mrb_gc_arena_save(mrb); + +...create objects... +mrb_gc_arena_restore(mrb, arena_idx); + +``` + +In mruby, C function call are surrounded by this save/restore, but we +can further optimize memory usage by surrounding save/restore, and can +avoid arena overflow. + +Let's take a real example. Here is the source code of `Array#inspect`: + +```c +static mrb_value +inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) +{ + mrb_int i; + mrb_value s, arystr; + char head[] = { '[' }; + char sep[] = { ',', ' ' }; + char tail[] = { ']' }; + + /* check recursive */ + for(i=0; i 0) { + mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); + } + if (mrb_array_p(RARRAY_PTR(ary)[i])) { + s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); + } + else { + s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); + } + mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); + mrb_gc_arena_restore(mrb, ai); + } + + mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail)); + mrb_ary_pop(mrb, list); + + return arystr; +} +``` + +This is a real example, so a little bit complicated, so bear with me. +The essence of `Array#inspect` is that after stringifying each element +of array using `inspect` method, we join them together so that we can +get `inspect` representation of entire array. + +After the `inspect` representation of entire array is created, we no +longer require the individual string representation. That means that +we don't have to register these temporal objects into GC arena. + +Therefore, in `ary_inspect()` function, we do: + +* save the position of the stack top using `mrb_gc_arena_save()`. +* get `inspect` representation of each element. +* append it to the constructing entire `inspect` representation of array. +* restore stack top position using `mrb_gc_arena_restore()`. + +to keep the arena size small. + +Please note that the final `inspect` representation of entire array +was created before the call of `mrb_gc_arena_restore()`. Otherwise, +required temporal object may be deleted by GC. + +We may have a usecase that after creating many temporal objects, we'd +like to keep some of them. In this case, we cannot use the same idea +in `ary_inspect()` like appending objects to existing one. Instead, +after `mrb_gc_arena_restore()`, we register back the objects we'd like +to keep to the arena using `mrb_gc_protect(mrb, obj)`. Use +`mrb_gc_protect()` with caution because its usage could lead to arena +overflow error. + +We also have to mention that when `mrb_funcall` is called in top +level, its return value is also registered to GC arena, so calling +them repeatedly eventually lead to arena overflow error. Use +`mrb_gc_arena_save()` and `mrb_gc_arena_restore()` or possible use of +`mrb_gc_protect()` to workaround this. diff --git a/doc/guides/mrbconf.md b/doc/guides/mrbconf.md new file mode 100644 index 000000000..dfff41898 --- /dev/null +++ b/doc/guides/mrbconf.md @@ -0,0 +1,160 @@ +# mruby configuration macros. + +## How to use these macros. +You can use mrbconfs with following ways: +* Write them in `mrbconf.h`. + * Using compiler flags is preferred when building a cross binaries or multiple mruby binaries + since it's easier to use different mrbconf per each `MRuby::Build`. + * Most flags can be enabled by just commenting in. +* Pass them as compiler flags. + * Make sure you pass the same flags to all compilers since some mrbconf(e.g., `MRB_GC_FIXED_ARENA`) + changes `struct` layout and cause memory access error when C and other language(e.g., C++) is mixed. + +## stdio setting. +`ENABLE_STDIO` +* Will be defined automatically if `DISABLE_STDIO` isn't defined. +* Uses `` functions. + +`DISABLE_STDIO` +* When defined `` functions won't be used. +* Some features will be disabled when this is enabled: + * `mrb_irep` load/dump from/to file. + * Compiling mruby script from file. + * Printing features in **src/print.c**. + +## Debug macros. +`ENABLE_DEBUG` +* When defined code fetch hook and debug OP hook will be enabled. +* When using any of the hook set function pointer `code_fetch_hook` and/or `debug_op_hook` of `mrb_state`. +* Fetch hook will be called before any OP. +* Debug OP hook will be called when dispatching `OP_DEBUG`. + +`DISABLE_DEBUG` +* Will be define automatically if `ENABLE_DEBUG` isn't defined. + +`MRB_DEBUG` +* When defined `mrb_assert*` macro will be defined with macros from ``. +* Could be enabled via `enable_debug` method of `MRuby::Build`. + +## Stack configuration + +`MRB_STACK_EXTEND_DOUBLING` +* If defined doubles the stack size when extending it. +* Else extends stack with `MRB_STACK_GROWTH`. + +`MRB_STACK_GROWTH` +* Default value is `128`. +* Used in stack extending. +* Ignored when `MRB_STACK_EXTEND_DOUBLING` is defined. + +`MRB_STACK_MAX` +* Default value is `0x40000 - MRB_STACK_GROWTH`. +* Raises `RuntimeError` when stack size exceeds this value. + +## Primitive type configuration. + +`MRB_USE_FLOAT` +* 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_INT16` +* When defined `int16_t` will be defined as `mrb_int`. +* Conflicts with `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`. + +## Garbage collector configuration. + +`MRB_GC_STRESS` +* When defined full GC is emitted per each `RBasic` allocation. +* Mainly used in memory manager debugging. + +`MRB_GC_TURN_OFF_GENERATIONAL` +* When defined turns generational GC by default. + +`MRB_GC_FIXED_ARENA` +* When defined used fixed size GC arena. +* Raises `RuntimeError` when this is defined and GC arena size exceeds `MRB_GC_ARENA_SIZE`. +* Useful tracking unnecessary mruby object allocation. + +`MRB_GC_ARENA_SIZE` +* Default value is `100`. +* Ignored when `MRB_GC_FIXED_ARENA` isn't defined. +* Defines fixed GC arena size. + +`MRB_HEAP_PAGE_SIZE` +* Defines value is `1024`. +* Specifies number of `RBasic` per each heap page. + +## Memory pool configuration. + +`POOL_ALIGNMENT` +* Default value is `4`. +* If you're allocating data types that requires alignment more than default value define the +largest value of required alignment. + +`POOL_PAGE_SIZE` +* Default value is `16000`. +* Specifies page size of pool page. +* Smaller the value is increases memory overhead. + +## State atexit configuration. + +`MRB_FIXED_STATE_ATEXIT_STACK` +* If defined enables fixed size `mrb_state` atexit stack. +* Raises `RuntimeError` when `mrb_state_atexit` call count to same `mrb_state` exceeds +`MRB_FIXED_STATE_ATEXIT_STACK_SIZE`'s value. + +`MRB_FIXED_STATE_ATEXIT_STACK_SIZE` +* Default value is `5`. +* If `MRB_FIXED_STATE_ATEXIT_STACK` isn't defined this macro is ignored. + +## `mrb_value` configuration. + +`MRB_ENDIAN_BIG` +* If defined compiles mruby for big endian machines. +* Used in `MRB_NAN_BOXING`. +* Some mrbgem use this mrbconf. + +`MRB_NAN_BOXING` +* If defined represent `mrb_value` in boxed `double`. +* Conflicts with `MRB_USE_FLOAT`. + +`MRB_WORD_BOXING` +* If defined represent `mrb_value` as a word. +* If defined `Float` will be a mruby object with `RBasic`. + +## Instance variable configuration. +`MRB_USE_IV_SEGLIST` +* If defined enable segmented list in instance variable table instead of khash. +* Segmented list is a linked list of key and value segments. +* It will linear search instead of hash search. + +`MRB_SEGMENT_SIZE` +* Default value is `4`. +* Specifies size of each segment in segment list. +* Ignored when `MRB_USE_IV_SEGLIST` isn't defined. + +`MRB_IVHASH_INIT_SIZE` +* Default value is `8`. +* Specifies initial size for instance variable table. +* Ignored when `MRB_USE_IV_SEGLIST` is defined. + +## Other configuration. +`MRB_FUNCALL_ARGC_MAX` +* Default value is `16`. +* Specifies 4th argument(`argc`) max value of `mrb_funcall`. +* Raises `ArgumentError` when the `argc` argument is bigger then this value `mrb_funcall`. + +`KHASH_DEFAULT_SIZE` +* Default value is `32`. +* Specifies default size of khash table bucket. +* Used in `kh_init_ ## name` function. + +`MRB_STR_BUF_MIN_SIZE` +* Default value is `128`. +* Specifies initial capacity of `RString` created by `mrb_str_buf_new` function.. diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md new file mode 100644 index 000000000..f75231f71 --- /dev/null +++ b/doc/guides/mrbgems.md @@ -0,0 +1,337 @@ +# mrbgems + +mrbgems is a library manager to integrate C and Ruby extension in an easy and +standardised way into mruby. + +## Usage + +By default mrbgems is currently deactivated. As soon as you add a GEM to your +build configuration (i.e. *build_config.rb*), mrbgems will be activated and the +extension integrated. + +To add a GEM into the *build_config.rb* add the following line for example: +```ruby +conf.gem '/path/to/your/gem/dir' +``` + +You can also use a relative path which would be relative from the mruby root: +```ruby +conf.gem 'examples/mrbgems/ruby_extension_example' +``` + +A remote GIT repository location for a GEM is also supported: +```ruby +conf.gem :git => 'https://github.com/masuidrive/mrbgems-example.git', :branch => 'master' +conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master' +conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' +``` + +To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option: +```ruby +conf.gem :mgem => 'mruby-yaml' +conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted +``` + +If there is missing dependencies, mrbgem dependencies solver will reference +mrbgem from core or mgem-list. + +To pull all gems from remote GIT repository on build, call ```./minirake -p```, +or ```./minirake --pull-gems```. + +NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. + +## GemBox + +There are instances when you wish to add a collection of mrbgems into mruby at +once, or be able to substitute mrbgems based on configuration, without having to +add each gem to the *build_config.rb* file. A packaged collection of mrbgems +is called a GemBox. A GemBox is a file that contains a list of mrbgems to load +into mruby, in the same format as if you were adding them to *build_config.rb* +via `config.gem`, but wrapped in an `MRuby::GemBox` object. GemBoxes are +loaded into mruby via `config.gembox 'boxname'`. + +Below we have created a GemBox containing *mruby-time* and *mrbgems-example*: +```ruby +MRuby::GemBox.new do |conf| + conf.gem "#{root}/mrbgems/mruby-time" + conf.gem :github => 'masuidrive/mrbgems-example' +end +``` + +As mentioned, the GemBox uses the same conventions as `MRuby::Build`. The GemBox +must be saved with a *.gembox* extension inside the *mrbgems* directory to to be +picked up by mruby. + +To use this example GemBox, we save it as `custom.gembox` inside the *mrbgems* +directory in mruby, and add the following to our *build_config.rb* file inside +the build block: +```ruby +conf.gembox 'custom' +``` +This will cause the *custom* GemBox to be read in during the build process, +adding *mruby-time* and *mrbgems-example* to the build. + +If you want, you can put GemBox outside of mruby directory. In that case you must +specify an absolute path like below. +```ruby +conf.gembox "#{ENV["HOME"]}/mygemboxes/custom" +``` + +There are two GemBoxes that ship with mruby: [default](../../mrbgems/default.gembox) +and [full-core](../../mrbgems/full-core.gembox). The [default](../../mrbgems/default.gembox) GemBox +contains several core components of mruby, and [full-core](../../mrbgems/full-core.gembox) +contains every gem found in the *mrbgems* directory. + +## GEM Structure + +The maximal GEM structure looks like this: + + +- GEM_NAME <- Name of GEM + | + +- include/ <- Header for Ruby extension (will exported) + | + +- mrblib/ <- Source for Ruby extension + | + +- src/ <- Source for C extension + | + +- test/ <- Test code (Ruby) + | + +- mrbgem.rake <- GEM Specification + | + +- README.md <- Readme for GEM + +The folder *mrblib* contains pure Ruby files to extend mruby. The folder *src* +contains C/C++ files to extend mruby. The folder *include* contains C/C++ header +files. The folder *test* contains C/C++ and pure Ruby files for testing purposes +which will be used by `mrbtest`. *mrbgem.rake* contains the specification +to compile C and Ruby files. *README.md* is a short description of your GEM. + +## Build process + +mrbgems expects a specification file called *mrbgem.rake* inside of your +GEM directory. A typical GEM specification could look like this for example: +```ruby +MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Example mrbgem using C and ruby' +end +``` + +The mrbgems build process will use this specification to compile Object and Ruby +files. The compilation results will be added to *lib/libmruby.a*. This file exposes +the GEM functionality to tools like `mruby` and `mirb`. + +The following properties can be set inside of your `MRuby::Gem::Specification` for +information purpose: + +* `spec.license` or `spec.licenses` (A single license or a list of them under which this GEM is licensed) +* `spec.author` or `spec.authors` (Developer name or a list of them) +* `spec.version` (Current version) +* `spec.description` (Detailed description) +* `spec.summary` + * One line short description of mrbgem. + * Printed in build summary of rake when set. +* `spec.homepage` (Homepage) +* `spec.requirements` (External requirements as information for user) + +The `license` and `author` properties are required in every GEM! + +In case your GEM is depending on other GEMs please use +`spec.add_dependency(gem, *requirements[, default_get_info])` like: +```ruby +MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + + # Add GEM dependency mruby-parser. + # The version must be between 1.0.0 and 1.5.2 . + spec.add_dependency('mruby-parser', '>= 1.0.0', '<= 1.5.2') + + # Use any version of mruby-uv from github. + spec.add_dependency('mruby-uv', '>= 0.0.0', :github => 'mattn/mruby-uv') + + # Use latest mruby-onig-regexp from github. (version requirements can be omitted) + spec.add_dependency('mruby-onig-regexp', :github => 'mattn/mruby-onig-regexp') +end +``` + +The version requirements and default gem information are optional. + +Version requirement supports following operators: +* '=': is equal +* '!=': is not equal +* '>': is greater +* '<': is lesser +* '>=': 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' + +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*. +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, +use `MRuby::Build#gem` in *build_config.rb* 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. + +like following code: +```ruby +MRuby::Gem::Specification.new 'some-regexp-binding' do |spec| + spec.license = 'BSD' + spec.author = 'John Doe' + + spec.add_conflict 'mruby-onig-regexp', '> 0.0.0' + spec.add_conflict 'mruby-hs-regexp' + spec.add_conflict 'mruby-pcre-regexp' + spec.add_conflict 'mruby-regexp-pcre' +end +``` + +In case your GEM has more complex build requirements you can use +the following options additionally inside of your GEM specification: + +* `spec.cc.flags` (C compiler flags) +* `spec.cc.defines` (C compiler defines) +* `spec.cc.include_paths` (C compiler include paths) +* `spec.linker.flags` (Linker flags) +* `spec.linker.libraries` (Linker libraries) +* `spec.linker.library_paths` (Linker additional library path) +* `spec.bins` (Generate binary file) +* `spec.rbfiles` (Ruby files to compile) +* `spec.objs` (Object files to compile) +* `spec.test_rbfiles` (Ruby test files for integration into mrbtest) +* `spec.test_objs` (Object test files for integration into mrbtest) +* `spec.test_preload` (Initialization files for mrbtest) + +You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for compiler and linker. + +### include_paths and dependency + +Your GEM can export include paths to another GEMs that depends on your GEM. +By default, `/...absolute path.../{GEM_NAME}/include` will be exported. +So it is recommended not to put GEM's local header files on include/. + +These exports are retroactive. +For example: when B depends to C and A depends to B, A will get include paths exported by C. + +Exported include_paths are automatically appended to GEM local include_paths by Minirake. +You can use `spec.export_include_paths` accessor if you want more complex build. + + +## C Extension + +mruby can be extended with C. This is possible by using the C API to +integrate C libraries into mruby. + +### Preconditions + +mrbgems expects that you have implemented a C method called +`mrb_YOURGEMNAME_gem_init(mrb_state)`. `YOURGEMNAME` will be replaced +by the name of your GEM. If you call your GEM *c_extension_example*, your +initialisation method could look like this: +```C +void +mrb_c_extension_example_gem_init(mrb_state* mrb) { + struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); + mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE()); +} +``` + +### Finalize + +mrbgems expects that you have implemented a C method called +`mrb_YOURGEMNAME_gem_final(mrb_state)`. `YOURGEMNAME` will be replaced +by the name of your GEM. If you call your GEM *c_extension_example*, your +finalizer method could look like this: + +```C +void +mrb_c_extension_example_gem_final(mrb_state* mrb) { + free(someone); +} +``` + +### Example + + +- c_extension_example/ + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C extension + | + +- mrbgem.rake <- GEM specification + | + +- README.md + +## Ruby Extension + +mruby can be extended with pure Ruby. It is possible to override existing +classes or add new ones in this way. Put all Ruby files into the *mrblib* +folder. + + +### Pre-Conditions + +none + +### Example + + +- ruby_extension_example/ + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- test/ + | | + | +- example.rb <- Test code for Ruby extension + | + +- mrbgem.rake <- GEM specification + | + +- README.md + +## C and Ruby Extension + +mruby can be extended with C and Ruby at the same time. It is possible to +override existing classes or add new ones in this way. Put all Ruby files +into the *mrblib* folder and all C files into the *src* folder. + +mruby codes under *mrblib* directory would be executed after gem init C +function is called. Make sure *mruby script* depends on *C code* and +*C code* doesn't depend on *mruby script*. + +### Pre-Conditions + +See C and Ruby example. + +### Example + + +- c_and_ruby_extension_example/ + | + +- 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 + | + +- README.md diff --git a/guides/compile.md b/guides/compile.md deleted file mode 100644 index 8e91e7546..000000000 --- a/guides/compile.md +++ /dev/null @@ -1,481 +0,0 @@ -# Compile - -mruby uses Rake to compile and cross-compile all libraries and -binaries. - -## Prerequisites - -To compile mruby out of the source code you need the following tools: -* C Compiler (i.e. ```gcc```) -* Linker (i.e. ```gcc```) -* Archive utility (i.e. ```ar```) -* Parser generator (i.e. ```bison```) -* Ruby 1.8 or 1.9 (i.e. ```ruby``` or ```jruby```) - -Optional: -* GIT (to update mruby source and integrate mrbgems easier) -* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc) -* Assembler (to use GEMs which include \*.asm) - -## Usage - -Inside of the root directory of the mruby source a file exists -called *build_config.rb*. This file contains the build configuration -of mruby and looks like this for example: -```ruby -MRuby::Build.new do |conf| - toolchain :gcc -end -``` - -All tools necessary to compile mruby can be set or modified here. In case -you want to maintain an additional *build_config.rb* you can define a -customized path using the *$MRUBY_CONFIG* environment variable. - -To compile just call ```./minirake``` inside of the mruby source root. To -generate and execute the test tools call ```./minirake test```. To clean -all build files call ```./minirake clean```. To see full command line on -build, call ```./minirake -v```. - -## Build Configuration - -Inside of the *build_config.rb* the following options can be configured -based on your environment. - -### Toolchains - -The mruby build system already contains a set of toolchain templates which -configure the build environment for specific compiler infrastructures. - -#### GCC - -Toolchain configuration for the GNU C Compiler. -```ruby -toolchain :gcc -``` - -#### clang - -Toolchain configuration for the LLVM C Compiler clang. Mainly equal to the -GCC toolchain. -```ruby -toolchain :clang -``` - -#### Visual Studio 2010, 2012 and 2013 - -Toolchain configuration for Visual Studio on Windows. If you use the -[Visual Studio Command Prompt](http://msdn.microsoft.com/en-us/library/ms229859\(v=vs.110\).aspx), -you normally do not have to specify this manually, since it gets automatically detected by our build process. -``` -toolchain :visualcpp -``` - -#### Android - -Toolchain configuration for Android. -```ruby -toolchain :androideabi -``` - -Requires the custom standalone Android NDK and the toolchain path -in ```ANDROID_STANDALONE_TOOLCHAIN```. - -### Binaries - -It is possible to select which tools should be compiled during the compilation -process. The following tools can be selected: -* mruby (mruby interpreter) -* mirb (mruby interactive shell) - -To select them declare conf.gem as follows: -```ruby -conf.gem "#{root}/mrbgems/mruby-bin-mruby" -conf.gem "#{root}/mrbgems/mruby-bin-mirb" -``` - -### File Separator - -Some environments require a different file separator character. It is possible to -set the character via ```conf.file_separator```. -```ruby -conf.file_separator = '/' -``` - -### C Compiler - -Configuration of the C compiler binary, flags and include paths. -```ruby -conf.cc do |cc| - cc.command = ... - cc.flags = ... - cc.include_paths = ... - cc.defines = ... - cc.option_include_path = ... - cc.option_define = ... - cc.compile_options = ... -end -``` - -C Compiler has header searcher to detect installed library. - -If you need a include path of header file use ```search_header_path```: -```ruby -# Searches ```iconv.h```. -# If found it will return include path of the header file. -# 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```. -# If found it will return full path of the header file. -# Otherwise it will return nil . -iconv_h = conf.cc.search_header 'iconv.h' -print "iconv.h found: #{iconv_h}\n" -``` - -Header searcher uses compiler's ```include_paths``` by default. -When you are using GCC toolchain (including clang toolchain since its base is gcc toolchain) -it will use compiler specific include paths too. (For example ```/usr/local/include```, ```/usr/include```) - -If you need a special header search paths define a singleton method ```header_search_paths``` to C compiler: -```ruby -def conf.cc.header_search_paths - ['/opt/local/include'] + include_paths -end -``` - -### Linker - -Configuration of the Linker binary, flags and library paths. -```ruby -conf.linker do |linker| - linker.command = ... - linker.flags = ... - linker.flags_before_libraries = ... - linker.libraries = ... - linker.flags_after_libraries = ... - linker.library_paths = .... - linker.option_library = ... - linker.option_library_path = ... - linker.link_options = ... -end -``` - -### Archiver - -Configuration of the Archiver binary and flags. -```ruby -conf.archiver do |archiver| - archiver.command = ... - archiver.archive_options = ... -end -``` - -### Parser Generator - -Configuration of the Parser Generator binary and flags. -```ruby -conf.yacc do |yacc| - yacc.command = ... - yacc.compile_options = ... -end -``` - -### GPerf - -Configuration of the GPerf binary and flags. -```ruby -conf.gperf do |gperf| - gperf.command = ... - gperf.compile_options = ... -end -``` - -### File Extensions -```ruby -conf.exts do |exts| - exts.object = ... - exts.executable = ... - exts.library = ... -end -``` - -### Mrbgems - -Integrate GEMs in the build process. -```ruby -# Integrate GEM with additional configuration -conf.gem 'path/to/gem' do |g| - g.cc.flags << ... -end - -# Integrate GEM without additional configuration -conf.gem 'path/to/another/gem' -``` - -See doc/mrbgems/README.md for more option about mrbgems. - -### Mrbtest - -Configuration Mrbtest build process. - -If you want mrbtest.a only, You should set ```conf.build_mrbtest_lib_only``` -```ruby -conf.build_mrbtest_lib_only -``` - -### Bintest - -Tests for mrbgem tools using CRuby. -To have bintests place \*.rb scripts to ```bintest/``` directory of mrbgems. -See ```mruby-bin-*/bintest/*.rb``` if you need examples. -If you want a temporary files use `tempfile` module of CRuby instead of ```/tmp/```. - -You can enable it with following: -```ruby -conf.enable_bintest -``` - -### C++ ABI - -mruby can use C++ exception to raise exception internally. -It is called C++ ABI mode. -By using C++ exception it can release C++ stack object correctly. -Whenever you mix C++ code C++ ABI mode would be enabled automatically. -If you need to enable C++ ABI mode explicitly add the following: -```ruby -conf.enable_cxx_abi -``` - -#### C++ exception disabling. - -If you need to force C++ exception disable -(For example using a compiler option to disable C++ exception) -add following: -```ruby -conf.disable_cxx_exception -``` - -Note that it must be called before ```enable_cxx_abi``` or ```gem``` method. - -### Debugging mode - -To enable debugging mode add the following: -```ruby -conf.enable_debug -``` - -When debugging mode is enabled -* Macro ```MRB_DEBUG``` would be defined. - * 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. - * You can have better backtrace of mruby scripts with this. - -## Cross-Compilation - -mruby can also be cross-compiled from one platform to another. To -achieve this the *build_config.rb* needs to contain an instance of -```MRuby::CrossBuild```. This instance defines the compilation -tools and flags for the target platform. An example could look -like this: -```ruby -MRuby::CrossBuild.new('32bit') do |conf| - toolchain :gcc - - conf.cc.flags << "-m32" - conf.linker.flags << "-m32" -end -``` - -All configuration options of ```MRuby::Build``` can also be used -in ```MRuby::CrossBuild```. - -### Mrbtest in Cross-Compilation - -In cross compilation, you can run ```mrbtest``` on emulator if -you have it by changing configuration of test runner. -```ruby -conf.test_runner do |t| - t.command = ... # set emulator. this value must be non nil or false - t.flags = ... # set flags of emulator - - def t.run(bin) # override `run` if you need to change the behavior of it - ... # `bin` is the full path of mrbtest - end -end -``` - -## Build process - -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 - | - +- bin <- Binaries (mirb, mrbc and mruby) - | - +- lib <- Libraries (libmruby.a and libmruby_core.a) - | - +- mrblib - | - +- src - | - +- test <- mrbtest tool - | - +- tools - | - +- mirb - | - +- mrbc - | - +- mruby - -The compilation workflow will look like this: -* compile all files under *src* (object files will be stored -in *build/host/src*) -* generate parser grammar out of *src/parse.y* (generated -result will be stored in *build/host/src/y.tab.c*) -* compile *build/host/src/y.tab.c* to *build/host/src/y.tab.o* -* create *build/host/lib/libmruby_core.a* out of all object files (C only) -* create ```build/host/bin/mrbc``` by compiling *tools/mrbc/mrbc.c* and -linking with *build/host/lib/libmruby_core.a* -* create *build/host/mrblib/mrblib.c* by compiling all \*.rb files -under *mrblib* with ```build/host/bin/mrbc``` -* compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* -* create *build/host/lib/libmruby.a* out of all object files (C and Ruby) -* create ```build/host/bin/mruby``` by compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and -linking with *build/host/lib/libmruby.a* -* create ```build/host/bin/mirb``` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and -linking with *build/host/lib/libmruby.a* - -``` - _____ _____ ______ ____ ____ _____ _____ ____ -| CC |->|GEN |->|AR |->|CC |->|CC |->|AR |->|CC |->|CC | -| *.c | |y.tab| |core.a| |mrbc| |*.rb| |lib.a| |mruby| |mirb| - ----- ----- ------ ---- ---- ----- ----- ---- -``` - -### Cross-Compilation - -In case of a cross-compilation to *i386* the *build* directory structure looks -like this: - - +- build - | - +- host - | | - | +- bin <- Native Binaries - | | - | +- lib <- Native Libraries - | | - | +- mrblib - | | - | +- src - | | - | +- test <- Native mrbtest tool - | | - | +- tools - | | - | +- mirb - | | - | +- mrbc - | | - | +- mruby - +- i386 - | - +- bin <- Cross-compiled Binaries - | - +- lib <- Cross-compiled Libraries - | - +- mrblib - | - +- src - | - +- test <- Cross-compiled mrbtest tool - | - +- tools - | - +- mirb - | - +- mrbc - | - +- mruby - -An extra directory is created for the target platform. In case you -compile for *i386* a directory called *i386* is created under the -build directory. - -The cross compilation workflow starts in the same way as the normal -compilation by compiling all *native* libraries and binaries. -Afterwards the cross compilation process proceeds like this: -* cross-compile all files under *src* (object files will be stored -in *build/i386/src*) -* generate parser grammar out of *src/parse.y* (generated -result will be stored in *build/i386/src/y.tab.c*) -* cross-compile *build/i386/src/y.tab.c* to *build/i386/src/y.tab.o* -* create *build/i386/mrblib/mrblib.c* by compiling all \*.rb files -under *mrblib* with the native ```build/host/bin/mrbc``` -* cross-compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* -* create *build/i386/lib/libmruby.a* out of all object files (C and Ruby) -* create ```build/i386/bin/mruby``` by cross-compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and -linking with *build/i386/lib/libmruby.a* -* create ```build/i386/bin/mirb``` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and -linking with *build/i386/lib/libmruby.a* -* create *build/i386/lib/libmruby_core.a* out of all object files (C only) -* create ```build/i386/bin/mrbc``` by cross-compiling *tools/mrbc/mrbc.c* and -linking with *build/i386/lib/libmruby_core.a* - -``` - _______________________________________________________________ -| Native Compilation for Host System | -| _____ ______ _____ ____ ____ _____ | -| | CC | -> |AR | -> |GEN | -> |CC | -> |CC | -> |AR | | -| | *.c | |core.a| |y.tab| |mrbc| |*.rb| |lib.a| | -| ----- ------ ----- ---- ---- ----- | - --------------------------------------------------------------- - || - \||/ - \/ - ________________________________________________________________ -| Cross Compilation for Target System | -| _____ _____ _____ ____ ______ _____ | -| | CC | -> |AR | -> |CC | -> |CC | -> |AR | -> |CC | | -| | *.c | |lib.a| |mruby| |mirb| |core.a| |mrbc | | -| ----- ----- ----- ---- ------ ----- | - ---------------------------------------------------------------- -``` - -## Build Configuration Examples - -### Minimal Library - -To build a minimal mruby library you need to use the Cross Compiling -feature due to the reason that there are functions (i.e. stdio) which -can't be disabled for the main build. - -```ruby -MRuby::CrossBuild.new('Minimal') do |conf| - toolchain :gcc - - conf.cc.defines = %w(DISABLE_STDIO) - conf.bins = [] -end -``` - -This configuration defines a cross compile build called 'Minimal' which -is using the GCC and compiles for the host machine. It also disables -all usages of stdio and doesn't compile any binaries (i.e. mrbc). - -## Test Environment - -mruby's build process includes a test environment. In case you start the testing -of mruby, a native binary called ```mrbtest``` will be generated and executed. -This binary contains all test cases which are defined under *test/t*. In case -of a cross-compilation an additional cross-compiled *mrbtest* binary is -generated. You can copy this binary and run on your target system. diff --git a/guides/debugger.md b/guides/debugger.md deleted file mode 100755 index a13e91cec..000000000 --- a/guides/debugger.md +++ /dev/null @@ -1,370 +0,0 @@ -# How to Use the mruby Debugger - -copyright (c) 2014 Specified Non-Profit Corporation mruby Forum - -## 1. Summary - -This file documents the mruby debugger ('mrdb') methods. - -## 2 Debugging with mrdb - -## 2.1 Building mrdb - -The trunk of the mruby source tree, with the most recent mrdb, can be checked out with the following command: - -```bash -$ git clone https://github.com/mruby/mruby.git -``` - -To run the `make` command: - -```bash -$ cd mruby -$ make -``` - -By default, the `make` command will install the debugger files into mruby/bin. - -You can add the path for mrdb on your host environment with the following command: - -```bash -$ echo "export PATH=\$PATH:MRUBY_ROOT/bin" >> ~/.bashrc -$ source ~/.bashrc -``` - -`*MRUBY_ROOT` is the directory in which mruby source code will be installed. - -To confirm mrdb was installed properly, run mrdb with the `--version` option: - -```bash -$ mrdb --version -mruby 1.1.0 (2014-11-19) -``` - -## 2.2 Basic Operation - -### 2.2.1 Debugging mruby Script Files (rb file) with mrdb - -To invoke the mruby debugger, just type `mrdb`. - -To specify the script file: - -```bash -$ mrdb [option] file name -``` - -For example: Debugging sample.rb - -```bash -$ mrdb sample.rb -``` - -You can execute the shell commands listed below: - -|command|description| -|:-:|:--| -|run|execute programs| -|step|execute stepping| -|continue|execute continuing program| -|break|configure the breaking point| -|delete|deleting the breaking points| -|disable|disabling the breaking points| -|enable|enabling the breaking points| -|info breakpoints|showing list of the breaking points| -|print|evaluating and printing the values of the mruby expressions in the script| -|list|displaying the source cords| -|help|showing help| -|quit|terminating the mruby debugger| - -### 2.2.2 Debugging mruby Binary Files (mrb file) with mrdb - -You can debug the mruby binary files. - -#### 2.2.2.1 Debugging the binary files - -* notice -To debug mruby binary files, you need to compile mruby files with option `-g`. - -```bash -$ mrbc -g sample.rb -``` - -You can debug the mruby binary files with following command and the option `-b`. - -```bash -$ mrdb -b sample.mrb -``` - -Then you can execute all debugger shell commands. - -#### Break Command - -You can use any breakpoint to stop the program by specifying the line number and method name. -The breakpoint list will be displayed after you have set the breakpoint successfully. - -Usage: - -``` -break [file:]linenum -b [file:]linenum -break [class:]method -b [class:]method -``` - -The breakpoint will be ordered in serial from 1. -The number, which was given to the deleted breakpoint, will never be given to another breakpoint again. - -You can give multiple breakpoints to specified the line number and method. -Be ware that breakpoint command will not check the validity of the class name and method name. - -You can get the current breakpoint information by the following options. - -breakpoint breakpoint number : file name. line number - -breakpoint breakpoint number : [class name,] method name - -#### Continue Command - -Usage: - -``` -continue [N] -c [N] -``` - -N: the next breakpoint number - -When resuming the program, it will stop at breakpoint N (N-1 breakpoint will be ignored). - -When you run the `continue` command without specifying N, the program will be stopped at the next breakpoint. - -Example: - -``` -(foo.rb:1) continue 3 -``` - -This will resume the program and stop it at the third breakpoint. - -#### Delete Command - -This will delete the specified breakpoint. - -Usage: - -``` -delete [breakpoint-no] -d [breakpoint-no] -``` - -breakpoint-no: breakpoint number - -Example: - -``` -(foo.rb:1) delete -``` - -This will delete all of the breakpoints. - -``` -(foo.rb:1) delete 1 3 -``` - -This will delete the breakpoint at 1 and 3. - -#### Disable Command - -This will disable the specified breakpoint. - -Usage: - -``` -disable [breakpoint-no] -dis [breakpoint-no] -``` - -reappointing: breakpoint number - -Example: - -``` -(foo.rb:1) disable -``` - -Use `disable` if you would like to disable all of the breakpoints. - -``` -(foo.rb:1) disable 1 3 -``` - -This will disable the breakpoints at 1 and 3. - -#### Enable Command - -This will enable the specified breakpoints. - -Usage: - -``` -enable [breakpoint-no] -e [breakpoint-no] -``` - -breakpoint-no: breakpoint number - -Example: - -``` -(foo.rb:1) enable -``` - -Enabling all breakpoints -``` -(foo.rb:1) enable 1 3 -``` - -Enabling the breakpoint 1 and 3 - -#### eval command - -Evaluating the string as source code and printing the value. - -Same as print command, please see print command. - -#### help command - -Displaying the help message. - -Usage: - -``` -help [command] -h [command] -``` - -Typing `help` without any options will display the command list. - -#### Info Breakpoints Command - -Displaying the specified breakpoint information. - -Usage: - -``` -info breakpoints [breakpoint-no] -i b [breakpoint-no] -``` - -breakpoint-no: breakpoint number - -Typing "info breakpoints" without ant option will display all breakpoint information. -Example: - -``` -(sample.rb:1) info breakpoints -Num Type Enb What -1 breakpoint y at sample.rb:3 -> file name,line number -2 breakpoint n in Sample_class:sample_class_method -> [class:]method name -3 breakpoint y in sample_global_method -``` - -Displaying the specified breakpoint number: - -``` -(foo.rb:1) info breakpoints 1 3 -Num Type Enb What -1 breakpoint y at sample.rb:3 -3 breakpoint y in sample_global_method -``` - -#### List Command - -To display the code of the source file. - -Usage: - -``` -list [filename:]first[,last] -l [filename]:first[,last] -``` - -first: the opening row number -last : the closing row number - -When you specify the `first`, but not the `last` option, you will receive 10 rows. -When you do not specify both the `first` and `last` options, you will receive the next 10 rows. - -Example: - -``` -Specifying file name and first row number -sample.rb:1) list sample2.rb:5 -``` - -Specifying the file name and the first and last row number: - -``` -(sample.rb:1) list sample2.rb:6,7 -``` - -#### Print Command - -Evaluating the string as source code and printing the value. - -Usage: - -``` -print [expr] -p [expr] -``` - -expr: expression - -The expression is mandatory. -The displayed expressions will be serially ordered from 1. -If an exception occurs, the exception information will be displayed and the debugging will be continued. - -Example: - -``` -(sample.rb:1) print 1+2 -$1 = 3 -(sample.rb:1) print self -$2 = main -``` - -Below is the case of the exception: - -``` -(sample.rb:1) print (1+2 -$1 = SyntaxError: line 1: syntax error, unexpected $end, expecting ')' -``` - -#### Quit Command - -Quitting the debugger. - -Usage: - -``` -quit -q -``` - -#### Run Command - -Running the program and stopping at the first breakpoint. - -Usage: - -``` -run -r -``` - -#### Step Command - -This will run the program step by step. -When the method and the block are invoked, the program will be stop at the first row. -The program, which is developed in C, will be ignored. diff --git a/guides/mrbconf.md b/guides/mrbconf.md deleted file mode 100644 index dfff41898..000000000 --- a/guides/mrbconf.md +++ /dev/null @@ -1,160 +0,0 @@ -# mruby configuration macros. - -## How to use these macros. -You can use mrbconfs with following ways: -* Write them in `mrbconf.h`. - * Using compiler flags is preferred when building a cross binaries or multiple mruby binaries - since it's easier to use different mrbconf per each `MRuby::Build`. - * Most flags can be enabled by just commenting in. -* Pass them as compiler flags. - * Make sure you pass the same flags to all compilers since some mrbconf(e.g., `MRB_GC_FIXED_ARENA`) - changes `struct` layout and cause memory access error when C and other language(e.g., C++) is mixed. - -## stdio setting. -`ENABLE_STDIO` -* Will be defined automatically if `DISABLE_STDIO` isn't defined. -* Uses `` functions. - -`DISABLE_STDIO` -* When defined `` functions won't be used. -* Some features will be disabled when this is enabled: - * `mrb_irep` load/dump from/to file. - * Compiling mruby script from file. - * Printing features in **src/print.c**. - -## Debug macros. -`ENABLE_DEBUG` -* When defined code fetch hook and debug OP hook will be enabled. -* When using any of the hook set function pointer `code_fetch_hook` and/or `debug_op_hook` of `mrb_state`. -* Fetch hook will be called before any OP. -* Debug OP hook will be called when dispatching `OP_DEBUG`. - -`DISABLE_DEBUG` -* Will be define automatically if `ENABLE_DEBUG` isn't defined. - -`MRB_DEBUG` -* When defined `mrb_assert*` macro will be defined with macros from ``. -* Could be enabled via `enable_debug` method of `MRuby::Build`. - -## Stack configuration - -`MRB_STACK_EXTEND_DOUBLING` -* If defined doubles the stack size when extending it. -* Else extends stack with `MRB_STACK_GROWTH`. - -`MRB_STACK_GROWTH` -* Default value is `128`. -* Used in stack extending. -* Ignored when `MRB_STACK_EXTEND_DOUBLING` is defined. - -`MRB_STACK_MAX` -* Default value is `0x40000 - MRB_STACK_GROWTH`. -* Raises `RuntimeError` when stack size exceeds this value. - -## Primitive type configuration. - -`MRB_USE_FLOAT` -* 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_INT16` -* When defined `int16_t` will be defined as `mrb_int`. -* Conflicts with `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`. - -## Garbage collector configuration. - -`MRB_GC_STRESS` -* When defined full GC is emitted per each `RBasic` allocation. -* Mainly used in memory manager debugging. - -`MRB_GC_TURN_OFF_GENERATIONAL` -* When defined turns generational GC by default. - -`MRB_GC_FIXED_ARENA` -* When defined used fixed size GC arena. -* Raises `RuntimeError` when this is defined and GC arena size exceeds `MRB_GC_ARENA_SIZE`. -* Useful tracking unnecessary mruby object allocation. - -`MRB_GC_ARENA_SIZE` -* Default value is `100`. -* Ignored when `MRB_GC_FIXED_ARENA` isn't defined. -* Defines fixed GC arena size. - -`MRB_HEAP_PAGE_SIZE` -* Defines value is `1024`. -* Specifies number of `RBasic` per each heap page. - -## Memory pool configuration. - -`POOL_ALIGNMENT` -* Default value is `4`. -* If you're allocating data types that requires alignment more than default value define the -largest value of required alignment. - -`POOL_PAGE_SIZE` -* Default value is `16000`. -* Specifies page size of pool page. -* Smaller the value is increases memory overhead. - -## State atexit configuration. - -`MRB_FIXED_STATE_ATEXIT_STACK` -* If defined enables fixed size `mrb_state` atexit stack. -* Raises `RuntimeError` when `mrb_state_atexit` call count to same `mrb_state` exceeds -`MRB_FIXED_STATE_ATEXIT_STACK_SIZE`'s value. - -`MRB_FIXED_STATE_ATEXIT_STACK_SIZE` -* Default value is `5`. -* If `MRB_FIXED_STATE_ATEXIT_STACK` isn't defined this macro is ignored. - -## `mrb_value` configuration. - -`MRB_ENDIAN_BIG` -* If defined compiles mruby for big endian machines. -* Used in `MRB_NAN_BOXING`. -* Some mrbgem use this mrbconf. - -`MRB_NAN_BOXING` -* If defined represent `mrb_value` in boxed `double`. -* Conflicts with `MRB_USE_FLOAT`. - -`MRB_WORD_BOXING` -* If defined represent `mrb_value` as a word. -* If defined `Float` will be a mruby object with `RBasic`. - -## Instance variable configuration. -`MRB_USE_IV_SEGLIST` -* If defined enable segmented list in instance variable table instead of khash. -* Segmented list is a linked list of key and value segments. -* It will linear search instead of hash search. - -`MRB_SEGMENT_SIZE` -* Default value is `4`. -* Specifies size of each segment in segment list. -* Ignored when `MRB_USE_IV_SEGLIST` isn't defined. - -`MRB_IVHASH_INIT_SIZE` -* Default value is `8`. -* Specifies initial size for instance variable table. -* Ignored when `MRB_USE_IV_SEGLIST` is defined. - -## Other configuration. -`MRB_FUNCALL_ARGC_MAX` -* Default value is `16`. -* Specifies 4th argument(`argc`) max value of `mrb_funcall`. -* Raises `ArgumentError` when the `argc` argument is bigger then this value `mrb_funcall`. - -`KHASH_DEFAULT_SIZE` -* Default value is `32`. -* Specifies default size of khash table bucket. -* Used in `kh_init_ ## name` function. - -`MRB_STR_BUF_MIN_SIZE` -* Default value is `128`. -* Specifies initial capacity of `RString` created by `mrb_str_buf_new` function.. diff --git a/guides/mrbgems.md b/guides/mrbgems.md deleted file mode 100644 index f75231f71..000000000 --- a/guides/mrbgems.md +++ /dev/null @@ -1,337 +0,0 @@ -# mrbgems - -mrbgems is a library manager to integrate C and Ruby extension in an easy and -standardised way into mruby. - -## Usage - -By default mrbgems is currently deactivated. As soon as you add a GEM to your -build configuration (i.e. *build_config.rb*), mrbgems will be activated and the -extension integrated. - -To add a GEM into the *build_config.rb* add the following line for example: -```ruby -conf.gem '/path/to/your/gem/dir' -``` - -You can also use a relative path which would be relative from the mruby root: -```ruby -conf.gem 'examples/mrbgems/ruby_extension_example' -``` - -A remote GIT repository location for a GEM is also supported: -```ruby -conf.gem :git => 'https://github.com/masuidrive/mrbgems-example.git', :branch => 'master' -conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master' -conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' -``` - -To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option: -```ruby -conf.gem :mgem => 'mruby-yaml' -conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted -``` - -If there is missing dependencies, mrbgem dependencies solver will reference -mrbgem from core or mgem-list. - -To pull all gems from remote GIT repository on build, call ```./minirake -p```, -or ```./minirake --pull-gems```. - -NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. - -## GemBox - -There are instances when you wish to add a collection of mrbgems into mruby at -once, or be able to substitute mrbgems based on configuration, without having to -add each gem to the *build_config.rb* file. A packaged collection of mrbgems -is called a GemBox. A GemBox is a file that contains a list of mrbgems to load -into mruby, in the same format as if you were adding them to *build_config.rb* -via `config.gem`, but wrapped in an `MRuby::GemBox` object. GemBoxes are -loaded into mruby via `config.gembox 'boxname'`. - -Below we have created a GemBox containing *mruby-time* and *mrbgems-example*: -```ruby -MRuby::GemBox.new do |conf| - conf.gem "#{root}/mrbgems/mruby-time" - conf.gem :github => 'masuidrive/mrbgems-example' -end -``` - -As mentioned, the GemBox uses the same conventions as `MRuby::Build`. The GemBox -must be saved with a *.gembox* extension inside the *mrbgems* directory to to be -picked up by mruby. - -To use this example GemBox, we save it as `custom.gembox` inside the *mrbgems* -directory in mruby, and add the following to our *build_config.rb* file inside -the build block: -```ruby -conf.gembox 'custom' -``` -This will cause the *custom* GemBox to be read in during the build process, -adding *mruby-time* and *mrbgems-example* to the build. - -If you want, you can put GemBox outside of mruby directory. In that case you must -specify an absolute path like below. -```ruby -conf.gembox "#{ENV["HOME"]}/mygemboxes/custom" -``` - -There are two GemBoxes that ship with mruby: [default](../../mrbgems/default.gembox) -and [full-core](../../mrbgems/full-core.gembox). The [default](../../mrbgems/default.gembox) GemBox -contains several core components of mruby, and [full-core](../../mrbgems/full-core.gembox) -contains every gem found in the *mrbgems* directory. - -## GEM Structure - -The maximal GEM structure looks like this: - - +- GEM_NAME <- Name of GEM - | - +- include/ <- Header for Ruby extension (will exported) - | - +- mrblib/ <- Source for Ruby extension - | - +- src/ <- Source for C extension - | - +- test/ <- Test code (Ruby) - | - +- mrbgem.rake <- GEM Specification - | - +- README.md <- Readme for GEM - -The folder *mrblib* contains pure Ruby files to extend mruby. The folder *src* -contains C/C++ files to extend mruby. The folder *include* contains C/C++ header -files. The folder *test* contains C/C++ and pure Ruby files for testing purposes -which will be used by `mrbtest`. *mrbgem.rake* contains the specification -to compile C and Ruby files. *README.md* is a short description of your GEM. - -## Build process - -mrbgems expects a specification file called *mrbgem.rake* inside of your -GEM directory. A typical GEM specification could look like this for example: -```ruby -MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| - spec.license = 'MIT' - spec.author = 'mruby developers' - spec.summary = 'Example mrbgem using C and ruby' -end -``` - -The mrbgems build process will use this specification to compile Object and Ruby -files. The compilation results will be added to *lib/libmruby.a*. This file exposes -the GEM functionality to tools like `mruby` and `mirb`. - -The following properties can be set inside of your `MRuby::Gem::Specification` for -information purpose: - -* `spec.license` or `spec.licenses` (A single license or a list of them under which this GEM is licensed) -* `spec.author` or `spec.authors` (Developer name or a list of them) -* `spec.version` (Current version) -* `spec.description` (Detailed description) -* `spec.summary` - * One line short description of mrbgem. - * Printed in build summary of rake when set. -* `spec.homepage` (Homepage) -* `spec.requirements` (External requirements as information for user) - -The `license` and `author` properties are required in every GEM! - -In case your GEM is depending on other GEMs please use -`spec.add_dependency(gem, *requirements[, default_get_info])` like: -```ruby -MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| - spec.license = 'MIT' - spec.author = 'mruby developers' - - # Add GEM dependency mruby-parser. - # The version must be between 1.0.0 and 1.5.2 . - spec.add_dependency('mruby-parser', '>= 1.0.0', '<= 1.5.2') - - # Use any version of mruby-uv from github. - spec.add_dependency('mruby-uv', '>= 0.0.0', :github => 'mattn/mruby-uv') - - # Use latest mruby-onig-regexp from github. (version requirements can be omitted) - spec.add_dependency('mruby-onig-regexp', :github => 'mattn/mruby-onig-regexp') -end -``` - -The version requirements and default gem information are optional. - -Version requirement supports following operators: -* '=': is equal -* '!=': is not equal -* '>': is greater -* '<': is lesser -* '>=': 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' - -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*. -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, -use `MRuby::Build#gem` in *build_config.rb* 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. - -like following code: -```ruby -MRuby::Gem::Specification.new 'some-regexp-binding' do |spec| - spec.license = 'BSD' - spec.author = 'John Doe' - - spec.add_conflict 'mruby-onig-regexp', '> 0.0.0' - spec.add_conflict 'mruby-hs-regexp' - spec.add_conflict 'mruby-pcre-regexp' - spec.add_conflict 'mruby-regexp-pcre' -end -``` - -In case your GEM has more complex build requirements you can use -the following options additionally inside of your GEM specification: - -* `spec.cc.flags` (C compiler flags) -* `spec.cc.defines` (C compiler defines) -* `spec.cc.include_paths` (C compiler include paths) -* `spec.linker.flags` (Linker flags) -* `spec.linker.libraries` (Linker libraries) -* `spec.linker.library_paths` (Linker additional library path) -* `spec.bins` (Generate binary file) -* `spec.rbfiles` (Ruby files to compile) -* `spec.objs` (Object files to compile) -* `spec.test_rbfiles` (Ruby test files for integration into mrbtest) -* `spec.test_objs` (Object test files for integration into mrbtest) -* `spec.test_preload` (Initialization files for mrbtest) - -You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for compiler and linker. - -### include_paths and dependency - -Your GEM can export include paths to another GEMs that depends on your GEM. -By default, `/...absolute path.../{GEM_NAME}/include` will be exported. -So it is recommended not to put GEM's local header files on include/. - -These exports are retroactive. -For example: when B depends to C and A depends to B, A will get include paths exported by C. - -Exported include_paths are automatically appended to GEM local include_paths by Minirake. -You can use `spec.export_include_paths` accessor if you want more complex build. - - -## C Extension - -mruby can be extended with C. This is possible by using the C API to -integrate C libraries into mruby. - -### Preconditions - -mrbgems expects that you have implemented a C method called -`mrb_YOURGEMNAME_gem_init(mrb_state)`. `YOURGEMNAME` will be replaced -by the name of your GEM. If you call your GEM *c_extension_example*, your -initialisation method could look like this: -```C -void -mrb_c_extension_example_gem_init(mrb_state* mrb) { - struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); - mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE()); -} -``` - -### Finalize - -mrbgems expects that you have implemented a C method called -`mrb_YOURGEMNAME_gem_final(mrb_state)`. `YOURGEMNAME` will be replaced -by the name of your GEM. If you call your GEM *c_extension_example*, your -finalizer method could look like this: - -```C -void -mrb_c_extension_example_gem_final(mrb_state* mrb) { - free(someone); -} -``` - -### Example - - +- c_extension_example/ - | - +- src/ - | | - | +- example.c <- C extension source - | - +- test/ - | | - | +- example.rb <- Test code for C extension - | - +- mrbgem.rake <- GEM specification - | - +- README.md - -## Ruby Extension - -mruby can be extended with pure Ruby. It is possible to override existing -classes or add new ones in this way. Put all Ruby files into the *mrblib* -folder. - - -### Pre-Conditions - -none - -### Example - - +- ruby_extension_example/ - | - +- mrblib/ - | | - | +- example.rb <- Ruby extension source - | - +- test/ - | | - | +- example.rb <- Test code for Ruby extension - | - +- mrbgem.rake <- GEM specification - | - +- README.md - -## C and Ruby Extension - -mruby can be extended with C and Ruby at the same time. It is possible to -override existing classes or add new ones in this way. Put all Ruby files -into the *mrblib* folder and all C files into the *src* folder. - -mruby codes under *mrblib* directory would be executed after gem init C -function is called. Make sure *mruby script* depends on *C code* and -*C code* doesn't depend on *mruby script*. - -### Pre-Conditions - -See C and Ruby example. - -### Example - - +- c_and_ruby_extension_example/ - | - +- 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 - | - +- README.md -- cgit v1.2.3