diff options
| -rw-r--r-- | .github/workflows/codeql-analysis.yml | 5 | ||||
| -rw-r--r-- | .github/workflows/oss-fuzz.yml | 2 | ||||
| -rw-r--r-- | build_config/dreamcast_shelf.rb | 73 | ||||
| -rw-r--r-- | doc/guides/compile.md | 2 | ||||
| -rw-r--r-- | doc/guides/link.md | 83 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-config/mruby-config | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-config/mruby-config.bat | 12 | ||||
| -rw-r--r-- | mrbgems/mruby-catch/src/catch.c | 16 | ||||
| -rw-r--r-- | src/class.c | 27 | ||||
| -rw-r--r-- | src/proc.c | 19 | ||||
| -rw-r--r-- | tasks/libmruby.rake | 3 |
11 files changed, 193 insertions, 53 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ea9f9bd8e..75f80a558 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -19,11 +19,6 @@ jobs: # a pull request then we can checkout the head. fetch-depth: 2 - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml index 0fd505624..e693b913d 100644 --- a/.github/workflows/oss-fuzz.yml +++ b/.github/workflows/oss-fuzz.yml @@ -16,7 +16,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/[email protected] + uses: actions/[email protected] if: failure() with: name: artifacts diff --git a/build_config/dreamcast_shelf.rb b/build_config/dreamcast_shelf.rb index 7e7d6a52e..ee9b260a5 100644 --- a/build_config/dreamcast_shelf.rb +++ b/build_config/dreamcast_shelf.rb @@ -1,8 +1,14 @@ # Cross Compiling configuration for the Sega Dreamcast -# This configuration requires KallistiOS (KOS) -# https://dreamcast.wiki +# https://dreamcast.wiki/Using_Ruby_for_Sega_Dreamcast_development # -# Tested on GNU/Linux, MinGW-w64/MSYS2, Cygwin, macOS and MinGW/MSYS (see below) +# Requires KallistiOS (KOS) +# http://gamedev.allusion.net/softprj/kos/ +# +# Tested on GNU/Linux, macOS and Windows (through MinGW-w64/MSYS2, Cygwin and DreamSDK). +# DreamSDK is based on MinGW/MSYS: https://dreamsdk.org/ +# +# Input this command on the directory where mruby is installed: +# make MRUBY_CONFIG=dreamcast_shelf # MRuby::CrossBuild.new("dreamcast") do |conf| toolchain :gcc @@ -64,31 +70,50 @@ MRuby::CrossBuild.new("dreamcast") do |conf| conf.disable_cxx_exception # Gems from core - # removing mruby-io - conf.gem :core => "mruby-metaprog" - conf.gem :core => "mruby-pack" - conf.gem :core => "mruby-sprintf" - conf.gem :core => "mruby-print" - conf.gem :core => "mruby-math" - conf.gem :core => "mruby-time" - conf.gem :core => "mruby-struct" + # Some Gems are incompatible and were disabled. + + conf.gem :core => "mruby-array-ext" + conf.gem :core => "mruby-binding" + conf.gem :core => "mruby-binding-core" + conf.gem :core => "mruby-catch" + conf.gem :core => "mruby-class-ext" + conf.gem :core => "mruby-cmath" conf.gem :core => "mruby-compar-ext" + conf.gem :core => "mruby-compiler" + conf.gem :core => "mruby-complex" + conf.gem :core => "mruby-enum-chain" conf.gem :core => "mruby-enum-ext" - conf.gem :core => "mruby-string-ext" - conf.gem :core => "mruby-numeric-ext" - conf.gem :core => "mruby-array-ext" + conf.gem :core => "mruby-enum-lazy" + conf.gem :core => "mruby-enumerator" + conf.gem :core => "mruby-error" + conf.gem :core => "mruby-eval" + conf.gem :core => "mruby-exit" + conf.gem :core => "mruby-fiber" conf.gem :core => "mruby-hash-ext" - conf.gem :core => "mruby-range-ext" - conf.gem :core => "mruby-proc-ext" - conf.gem :core => "mruby-symbol-ext" - conf.gem :core => "mruby-random" + conf.gem :core => "mruby-inline-struct" +# conf.gem :core => "mruby-io" + conf.gem :core => "mruby-kernel-ext" + conf.gem :core => "mruby-math" + conf.gem :core => "mruby-metaprog" + conf.gem :core => "mruby-method" + conf.gem :core => "mruby-numeric-ext" conf.gem :core => "mruby-object-ext" conf.gem :core => "mruby-objectspace" - conf.gem :core => "mruby-fiber" - conf.gem :core => "mruby-enumerator" - conf.gem :core => "mruby-enum-lazy" + conf.gem :core => "mruby-os-memsize" + conf.gem :core => "mruby-pack" + conf.gem :core => "mruby-print" + conf.gem :core => "mruby-proc-binding" + conf.gem :core => "mruby-proc-ext" + conf.gem :core => "mruby-random" + conf.gem :core => "mruby-range-ext" + conf.gem :core => "mruby-rational" + conf.gem :core => "mruby-sleep" +# conf.gem :core => "mruby-socket" + conf.gem :core => "mruby-sprintf" + conf.gem :core => "mruby-string-ext" + conf.gem :core => "mruby-struct" + conf.gem :core => "mruby-symbol-ext" +# conf.gem :core => "mruby-test" +# conf.gem :core => "mruby-time" conf.gem :core => "mruby-toplevel-ext" - conf.gem :core => "mruby-kernel-ext" - conf.gem :core => "mruby-class-ext" - conf.gem :core => "mruby-compiler" end diff --git a/doc/guides/compile.md b/doc/guides/compile.md index 7a2ff2a44..740663ff8 100644 --- a/doc/guides/compile.md +++ b/doc/guides/compile.md @@ -527,7 +527,9 @@ convenience. `mruby-config` command prints the configuration used for `libmruby. $ mruby-config --help Usage: mruby-config [switches] switches: + --cc print compiler name --cflags print flags passed to compiler + --ld print linker name --ldflags print flags passed to linker --ldflags-before-libs print flags passed to linker before linked libraries --libs print linked libraries diff --git a/doc/guides/link.md b/doc/guides/link.md new file mode 100644 index 000000000..4bef8414c --- /dev/null +++ b/doc/guides/link.md @@ -0,0 +1,83 @@ +# Linking `libmruby` to your application + +You have two ways to link `libmruby` to your application. + +* using executable gem. +* using normal compilation process + +## Executable Gems + +If your application is relatively small, `mrbgem` is easier way to +create the executable. By tradition, the gem name start with +`mruby-bin-`, e.g. `mruby-bin-debugger`. + +### `mrbgem.rake` file + +The executable name is specified in `mrbgem.rake` file at the top of +your `mrbgem` directory. + +```ruby +MRuby::Gem::Specification.new('mruby-bin-example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Example for executable command gem' + spec.bins = %w(mruby-example) # <- this is binary name +end +``` + +### Source tree structure + +The source file for the gem executable should be in +`<gem-name>/tools/<bin-name>`. Currently, we support C or C++ source code +(`.c`, `.cpp`, `.cxx`, `.cc`) for the executable. Ruby source files are not +supported. Put the functionality in the different gem and specify dependency to +it in `mrbgem.rake`. + +## Normal compilation process + +The `libmruby` is a normal library so that you can just link it to your +application. Specify proper compiler options (`-I` etc.) and linker options +(`-Lmruby` etc.) to compile and link your application. Specify those options in +your build script (e.g. `Makefile`). + +### Compiler options + +You need to specify compiler options that are compatible to mruby configuration, +for example: + +* `-I` to specify the place for mruby header files +* `-D` to specify mruby configuration macros + +To retrieve compiler options used to build `mruby`, you can use `mruby-config` +command with following options: + +* `--cc` compiler name +* `--cflags` options passed to compiler + +``` +$ mruby-config --cflags +-std=gnu99 -g -O3 -Wall -DMRB_GC_FIXED_ARENA -I/home/matz/work/mruby/include -I/home/matz/work/mruby/build/host/include +``` + +### Linker options + +Just like compiler options, you need to specify linker options that are +compatible to mruby configuration. + +To retrieve linker options, you can use `mruby-config` with following options: + +* `--ld` linker name +* `--ldflags` options passed to linker +* `--ldflags-before-libs` options passed to linker before linked libraries +* `--libs` linked libraries + +``` +$ mruby-config --ldflags +-L/home/matz/work/mruby/build/host/lib + +$ mruby-config --ldflags-before-libs +# <nothing in this case> + +$ mruby-config --libs +-lmruby -lm +``` diff --git a/mrbgems/mruby-bin-config/mruby-config b/mrbgems/mruby-bin-config/mruby-config index 8bbb4ecc6..3adda9e1a 100644 --- a/mrbgems/mruby-bin-config/mruby-config +++ b/mrbgems/mruby-bin-config/mruby-config @@ -4,7 +4,9 @@ print_help() { echo "Usage: mruby-config [switches]" echo " switches:" + echo " --cc print compiler name" echo " --cflags print flags passed to compiler" + echo " --ld print linker name" echo " --ldflags print flags passed to linker" echo " --ldflags-before-libs print flags passed to linker before linked libraries" echo " --libs print linked libraries" @@ -19,7 +21,9 @@ fi while [ $# -gt 0 ]; do case $1 in + --cc) echo MRUBY_CC;; --cflags) echo MRUBY_CFLAGS;; + --ld) echo MRUBY_LD;; --ldflags) echo MRUBY_LDFLAGS;; --ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;; --libs) echo MRUBY_LIBS;; diff --git a/mrbgems/mruby-bin-config/mruby-config.bat b/mrbgems/mruby-bin-config/mruby-config.bat index a1f7bfdd1..949fea06f 100644 --- a/mrbgems/mruby-bin-config/mruby-config.bat +++ b/mrbgems/mruby-bin-config/mruby-config.bat @@ -3,7 +3,9 @@ :top shift if "%0" equ "" goto :eof +if "%0" equ "--cc" goto cc if "%0" equ "--cflags" goto cflags +if "%0" equ "--ld" goto ld if "%0" equ "--ldflags" goto ldflags if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs if "%0" equ "--libs" goto libs @@ -12,10 +14,18 @@ if "%0" equ "--help" goto showhelp echo Invalid Option goto :eof +:cc +echo MRUBY_CC +goto top + :cflags echo MRUBY_CFLAGS goto top +:ld +echo MRUBY_LD +goto top + :libs echo MRUBY_LIBS goto top @@ -35,7 +45,9 @@ goto top :showhelp echo Usage: mruby-config [switches] echo switches: +echo --cc print compiler name echo --cflags print flags passed to compiler +echo --ld print linker name echo --ldflags print flags passed to linker echo --ldflags-before-libs print flags passed to linker before linked libraries echo --libs print linked libraries diff --git a/mrbgems/mruby-catch/src/catch.c b/mrbgems/mruby-catch/src/catch.c index d910cac7f..148639530 100644 --- a/mrbgems/mruby-catch/src/catch.c +++ b/mrbgems/mruby-catch/src/catch.c @@ -61,21 +61,20 @@ static const mrb_irep catch_irep = { 29,0,3,1,0 }; -#define ID_PRESERVED_CATCH MRB_SYM(__preserved_catch_proc) +static const struct RProc catch_proc = { + NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT, + { &catch_irep }, NULL, { NULL } +}; static const mrb_callinfo * find_catcher(mrb_state *mrb, mrb_value tag) { - mrb_value pval = mrb_obj_iv_get(mrb, (struct RObject *)mrb->kernel_module, ID_PRESERVED_CATCH); - mrb_assert(mrb_proc_p(pval)); - const struct RProc *proc = mrb_proc_ptr(pval); - const mrb_callinfo *ci = mrb->c->ci; size_t n = ci - mrb->c->cibase; ci--; for (; n > 0; n--, ci--) { const mrb_value *arg1 = ci->stack + 1; - if (ci->proc == proc && mrb_obj_eq(mrb, *arg1, tag)) { + if (ci->proc == &catch_proc && mrb_obj_eq(mrb, *arg1, tag)) { return ci; } } @@ -109,15 +108,12 @@ mrb_f_throw(mrb_state *mrb, mrb_value self) void mrb_mruby_catch_gem_init(mrb_state *mrb) { - struct RProc *p; mrb_method_t m; MRB_PRESYM_INIT_SYMBOLS(mrb, catch_syms_3); MRB_PRESYM_INIT_SYMBOLS(mrb, catch_syms_1); - p = mrb_proc_new(mrb, &catch_irep); - MRB_METHOD_FROM_PROC(m, p); + MRB_METHOD_FROM_PROC(m, &catch_proc); mrb_define_method_raw(mrb, mrb->kernel_module, MRB_SYM(catch), m); - mrb_obj_iv_set(mrb, (struct RObject *)mrb->kernel_module, ID_PRESERVED_CATCH, mrb_obj_value(p)); mrb_define_method(mrb, mrb->kernel_module, "throw", mrb_f_throw, MRB_ARGS_ARG(1,1)); } diff --git a/src/class.c b/src/class.c index 09e52d24a..33a65f7d6 100644 --- a/src/class.c +++ b/src/class.c @@ -736,11 +736,17 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ ptr.proc = p; if (p) { - p->flags |= MRB_PROC_SCOPE; - p->c = NULL; - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p); - if (!MRB_PROC_ENV_P(p)) { - MRB_PROC_SET_TARGET_CLASS(p, c); + if (p->color != 7 /* GC_RED */) { + p->flags |= MRB_PROC_SCOPE; + p->c = NULL; + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p); + if (!MRB_PROC_ENV_P(p)) { + MRB_PROC_SET_TARGET_CLASS(p, c); + } + } + else { + mrb_assert(MRB_FROZEN_P(p) && MRB_PROC_SCOPE_P(p)); + mrb_assert(p->c == NULL && p->upper == NULL && p->e.target_class == NULL); } } } @@ -2199,7 +2205,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) if (MRB_PROC_ENV_P(p)) { MRB_PROC_ENV(p)->mid = b; } - else { + else if (p->color != 7 /* GC_RED */) { struct RClass *tc = MRB_PROC_TARGET_CLASS(p); struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL); @@ -2812,15 +2818,18 @@ static const mrb_irep new_irep = { sizeof(new_iseq), 0, 2, 0, 0, }; +static const struct RProc new_proc = { + NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT, + { &new_irep }, NULL, { NULL } +}; + static void init_class_new(mrb_state *mrb, struct RClass *cls) { - struct RProc *p; mrb_method_t m; MRB_PRESYM_INIT_SYMBOLS(mrb, new_syms); - p = mrb_proc_new(mrb, &new_irep); - MRB_METHOD_FROM_PROC(m, p); + MRB_METHOD_FROM_PROC(m, &new_proc); mrb_define_method_raw(mrb, cls, MRB_SYM(new), m); } diff --git a/src/proc.c b/src/proc.c index 4a202525c..5419ac002 100644 --- a/src/proc.c +++ b/src/proc.c @@ -35,6 +35,11 @@ static const mrb_irep call_irep = { 0, /* refcnt */ }; +static const struct RProc call_proc = { + NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT, + { &call_irep }, NULL, { NULL } +}; + struct RProc* mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) { @@ -46,7 +51,15 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) struct RClass *tc = NULL; if (ci->proc) { - tc = MRB_PROC_TARGET_CLASS(ci->proc); + if (ci->proc->color != 7 /* GC_RED */) { + tc = MRB_PROC_TARGET_CLASS(ci->proc); + } + else { + tc = mrb_vm_ci_target_class(ci); + if (tc && tc->tt == MRB_TT_ICLASS) { + tc = tc->c; + } + } } if (tc == NULL) { tc = mrb_vm_ci_target_class(ci); @@ -413,15 +426,13 @@ mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, c void mrb_init_proc(mrb_state *mrb) { - struct RProc *p; mrb_method_t m; mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE()); - p = mrb_proc_new(mrb, &call_irep); - MRB_METHOD_FROM_PROC(m, p); + MRB_METHOD_FROM_PROC(m, &call_proc); mrb_define_method_raw(mrb, mrb->proc_class, MRB_SYM(call), m); mrb_define_method_raw(mrb, mrb->proc_class, MRB_OPSYM(aref), m); diff --git a/tasks/libmruby.rake b/tasks/libmruby.rake index 8cdb4ca2e..9a7a57ff7 100644 --- a/tasks/libmruby.rake +++ b/tasks/libmruby.rake @@ -16,6 +16,9 @@ MRuby.each_target do open(t.name, 'w') do |f| f.puts "MRUBY_CFLAGS = #{cc.all_flags}" + f.puts "MRUBY_CC = #{cc.command}" + f.puts "MRUBY_LD = #{linker.command}" + libgems = gems.reject{|g| g.bin?} gem_flags = libgems.map {|g| g.linker.flags } gem_library_paths = libgems.map {|g| g.linker.library_paths } |
