diff options
| -rw-r--r-- | .github/workflows/main.yml | 24 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | appveyor.yml | 8 | ||||
| -rw-r--r-- | examples/targets/build_config_dreamcast_shelf.rb | 108 | ||||
| -rw-r--r-- | include/mrbconf.h | 7 | ||||
| -rw-r--r-- | include/mruby.h | 10 | ||||
| -rw-r--r-- | include/mruby/common.h | 10 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/mrblib/array.rb | 31 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/test/array.rb | 13 | ||||
| -rw-r--r-- | mrbgems/mruby-error/src/exception.c | 6 | ||||
| -rw-r--r-- | mrbgems/mruby-io/include/mruby/ext/io.h | 32 | ||||
| -rw-r--r-- | mrbgems/mruby-io/mrblib/file_constants.rb | 16 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/file.c | 22 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/io.c | 174 | ||||
| -rw-r--r-- | mrbgems/mruby-io/test/mruby_io_test.c | 7 | ||||
| -rw-r--r-- | mrbgems/mruby-socket/test/sockettest.c | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-time/src/time.c | 2 | ||||
| -rw-r--r-- | src/backtrace.c | 4 | ||||
| -rw-r--r-- | src/hash.c | 3 | ||||
| -rw-r--r-- | src/string.c | 48 | ||||
| -rw-r--r-- | src/symbol.c | 10 | ||||
| -rw-r--r-- | src/vm.c | 4 | ||||
| -rw-r--r-- | test/t/exception.rb | 4 |
23 files changed, 369 insertions, 180 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..3c1a7e07e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,24 @@ +name: CIFuzz +on: [pull_request] +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'mruby' + dry-run: false + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'mruby' + fuzz-seconds: 600 + dry-run: false + - name: Upload Crash + uses: actions/upload-artifact@v1 + if: failure() + with: + name: artifacts + path: ./out/artifacts + @@ -34,7 +34,7 @@ The URL of the mruby home-page is: https://mruby.org. ## Mailing list -We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby). +We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby/issues). ## How to compile and install (mruby and gems) diff --git a/appveyor.yml b/appveyor.yml index a91834cef..bf4fb3f17 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,10 +14,18 @@ environment: # Visual Studio 2017 64bit - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat + # Visual Studio 2017 32bit + - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat + machine: x86 + # Visual Studio 2015 64bit - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat machine: amd64 + # Visual Studio 2015 32bit + - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat + machine: x86 + # Visual Studio 2013 64bit - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat machine: amd64 diff --git a/examples/targets/build_config_dreamcast_shelf.rb b/examples/targets/build_config_dreamcast_shelf.rb new file mode 100644 index 000000000..fd6915acb --- /dev/null +++ b/examples/targets/build_config_dreamcast_shelf.rb @@ -0,0 +1,108 @@ +MRuby::Build.new do |conf| + # Gets set by the VS command prompts + if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] + toolchain :visualcpp + else + toolchain :gcc + end + + enable_debug + + # Include the default GEMs + conf.gembox 'default' +end + +# Cross Compiling configuration for the Sega Dreamcast +# This configuration requires KallistiOS (KOS) +# https://dreamcast.wiki +# +# Tested on GNU/Linux, MinGW-w64/MSYS2, Cygwin, macOS and MinGW/MSYS (see below) +# +MRuby::CrossBuild.new("dreamcast") do |conf| + toolchain :gcc + + # Support for DreamSDK (based on MinGW/MSYS) + # To compile mruby with DreamSDK, RubyInstaller for Windows should be installed + DREAMSDK_HOME = ENV["DREAMSDK_HOME"] + MSYS_ROOT = !(DREAMSDK_HOME.nil? || DREAMSDK_HOME.empty?) ? "#{DREAMSDK_HOME}/msys/1.0" : "" + + # Setting paths + DREAMCAST_PATH = "#{MSYS_ROOT}/opt/toolchains/dc" + KOS_PATH = "#{DREAMCAST_PATH}/kos" + BIN_PATH = "#{DREAMCAST_PATH}/sh-elf/bin" + + # C compiler + # Flags were extracted from KallistiOS environment files + conf.cc do |cc| + cc.command = "#{BIN_PATH}/sh-elf-gcc" + cc.include_paths << ["#{KOS_PATH}/include", "#{KOS_PATH}/kernel/arch/dreamcast/include", "#{KOS_PATH}/addons/include", "#{KOS_PATH}/../kos-ports/include"] + cc.flags << ["-O2", "-fomit-frame-pointer", "-ml", "-m4-single-only", "-ffunction-sections", "-fdata-sections", "-Wall", "-g", "-fno-builtin", "-ml", "-m4-single-only", "-Wl,-Ttext=0x8c010000", "-Wl,--gc-sections", "-T#{KOS_PATH}/utils/ldscripts/shlelf.xc", "-nodefaultlibs"] + cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" + cc.defines << %w(_arch_dreamcast) + cc.defines << %w(_arch_sub_pristine) + end + + # C++ compiler + conf.cxx do |cxx| + cxx.command = conf.cc.command.dup + cxx.include_paths = conf.cc.include_paths.dup + cxx.flags = conf.cc.flags.dup + cxx.flags << %w(-fno-rtti -fno-exceptions) + cxx.defines = conf.cc.defines.dup + cxx.compile_options = conf.cc.compile_options.dup + end + + # Linker + # There is an issue when making the mruby library with KallistiOS: + # 'newlib_kill.o' and 'newlib_getpid.o' aren't found so they are explicitly + # specified here at least for now. + conf.linker do |linker| + linker.command="#{BIN_PATH}/sh-elf-gcc" + linker.flags << ["#{MSYS_ROOT}/opt/toolchains/dc/kos/kernel/build/newlib_kill.o", "#{MSYS_ROOT}/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o", "-Wl,--start-group -lkallisti -lc -lgcc -Wl,--end-group"] + linker.library_paths << ["#{KOS_PATH}/lib/dreamcast", "#{KOS_PATH}/addons/lib/dreamcast", "#{KOS_PATH}/../kos-ports/lib"] + end + + # Archiver + conf.archiver do |archiver| + archiver.command = "#{BIN_PATH}/sh-elf-ar" + archiver.archive_options = 'rcs %{outfile} %{objs}' + end + + # No executables + conf.bins = [] + + # Do not build executable test + conf.build_mrbtest_lib_only + + # Disable C++ exception + 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" + conf.gem :core => "mruby-compar-ext" + 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-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-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-toplevel-ext" + conf.gem :core => "mruby-kernel-ext" + conf.gem :core => "mruby-class-ext" + conf.gem :core => "mruby-compiler" +end diff --git a/include/mrbconf.h b/include/mrbconf.h index 3a574c7d2..35762a8f0 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -38,7 +38,12 @@ /* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */ /* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */ -//#define MRB_METHOD_T_STRUCT +#ifndef MRB_METHOD_T_STRUCT + // can't use highest 2 bits of function pointers on 32bit Windows. +# if defined(_WIN32) && !defined(_WIN64) +# define MRB_METHOD_T_STRUCT +# endif +#endif /* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64; Default for 32-bit CPU mode. */ diff --git a/include/mruby.h b/include/mruby.h index 671053ff9..7419618fd 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -70,6 +70,11 @@ #include "mrbconf.h" +#include <mruby/common.h> +#include <mruby/value.h> +#include <mruby/gc.h> +#include <mruby/version.h> + #ifndef MRB_WITHOUT_FLOAT #ifndef FLT_EPSILON #define FLT_EPSILON (1.19209290e-07f) @@ -88,11 +93,6 @@ #endif #endif -#include <mruby/common.h> -#include <mruby/value.h> -#include <mruby/gc.h> -#include <mruby/version.h> - /** * MRuby C API entry point */ diff --git a/include/mruby/common.h b/include/mruby/common.h index 5be9a40c6..f704ef8df 100644 --- a/include/mruby/common.h +++ b/include/mruby/common.h @@ -74,6 +74,16 @@ MRB_BEGIN_DECL #endif #endif +/** Declare mingw versions */ +#if defined(__MINGW32__) || defined(__MINGW64__) +# include <_mingw.h> +# if defined(__MINGW64_VERSION_MAJOR) +# define MRB_MINGW64_VERSION (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR) +# elif defined(__MINGW32_MAJOR_VERSION) +# define MRB_MINGW32_VERSION (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION) +# endif +#endif + MRB_END_DECL #endif /* MRUBY_COMMON_H */ diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb index 5492ba2eb..f3246af4f 100644 --- a/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mrbgems/mruby-array-ext/mrblib/array.rb @@ -688,37 +688,6 @@ class Array ## # call-seq: - # ary.delete_if { |item| block } -> ary - # ary.delete_if -> Enumerator - # - # Deletes every element of +self+ for which block evaluates to +true+. - # - # The array is changed instantly every time the block is called, not after - # the iteration is over. - # - # See also Array#reject! - # - # If no block is given, an Enumerator is returned instead. - # - # scores = [ 97, 42, 75 ] - # scores.delete_if {|score| score < 80 } #=> [97] - - def delete_if(&block) - return to_enum :delete_if unless block - - idx = 0 - while idx < self.size do - if block.call(self[idx]) - self.delete_at(idx) - else - idx += 1 - end - end - self - end - - ## - # call-seq: # ary.keep_if { |item| block } -> ary # ary.keep_if -> Enumerator # diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb index 51172f9a8..2955ef391 100644 --- a/mrbgems/mruby-array-ext/test/array.rb +++ b/mrbgems/mruby-array-ext/test/array.rb @@ -299,19 +299,6 @@ end #assert("Array#bsearch_index") do #end -assert("Array#delete_if") do - a = [1, 2, 3, 4, 5] - assert_equal [1, 2, 3, 4, 5], a.delete_if { false } - assert_equal [1, 2, 3, 4, 5], a - - a = [1, 2, 3, 4, 5] - assert_equal [], a.delete_if { true } - assert_equal [], a - - a = [ 1, 2, 3, 4, 5 ] - assert_equal [1, 2, 3], a.delete_if { |val| val > 3 } -end - assert("Array#keep_if") do a = [1, 2, 3, 4, 5] assert_equal [1, 2, 3, 4, 5], a.keep_if { true } diff --git a/mrbgems/mruby-error/src/exception.c b/mrbgems/mruby-error/src/exception.c index ec4870dc0..e0ea28ac8 100644 --- a/mrbgems/mruby-error/src/exception.c +++ b/mrbgems/mruby-error/src/exception.c @@ -8,7 +8,7 @@ mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state) struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result = mrb_nil_value(); - mrb_int ai = mrb_gc_arena_save(mrb); + int ai = mrb_gc_arena_save(mrb); if (state) { *state = FALSE; } @@ -34,7 +34,7 @@ mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; - mrb_int ai = mrb_gc_arena_save(mrb); + int ai = mrb_gc_arena_save(mrb); MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; @@ -71,7 +71,7 @@ mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_fun mrb_value result; mrb_bool error_matched = FALSE; mrb_int i; - mrb_int ai = mrb_gc_arena_save(mrb); + int ai = mrb_gc_arena_save(mrb); MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; diff --git a/mrbgems/mruby-io/include/mruby/ext/io.h b/mrbgems/mruby-io/include/mruby/ext/io.h index 5d1dde354..4bcbbe914 100644 --- a/mrbgems/mruby-io/include/mruby/ext/io.h +++ b/mrbgems/mruby-io/include/mruby/ext/io.h @@ -19,13 +19,31 @@ struct mrb_io { is_socket:1; }; -#define FMODE_READABLE 0x00000001 -#define FMODE_WRITABLE 0x00000002 -#define FMODE_READWRITE (FMODE_READABLE|FMODE_WRITABLE) -#define FMODE_BINMODE 0x00000004 -#define FMODE_APPEND 0x00000040 -#define FMODE_CREATE 0x00000080 -#define FMODE_TRUNC 0x00000800 +#define MRB_O_RDONLY 0x0000 +#define MRB_O_WRONLY 0x0001 +#define MRB_O_RDWR 0x0002 +#define MRB_O_ACCMODE (MRB_O_RDONLY | MRB_O_WRONLY | MRB_O_RDWR) +#define MRB_O_NONBLOCK 0x0004 +#define MRB_O_APPEND 0x0008 +#define MRB_O_SYNC 0x0010 +#define MRB_O_NOFOLLOW 0x0020 +#define MRB_O_CREAT 0x0040 +#define MRB_O_TRUNC 0x0080 +#define MRB_O_EXCL 0x0100 +#define MRB_O_NOCTTY 0x0200 +#define MRB_O_DIRECT 0x0400 +#define MRB_O_BINARY 0x0800 +#define MRB_O_SHARE_DELETE 0x1000 +#define MRB_O_TMPFILE 0x2000 +#define MRB_O_NOATIME 0x4000 +#define MRB_O_DSYNC 0x00008000 /* Ignored with MRB_INT16 and MRB_WITHOUT_FLOAT */ +#define MRB_O_RSYNC 0x00010000 /* Ignored with MRB_INT16 and MRB_WITHOUT_FLOAT */ + +#define MRB_O_RDONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDONLY)) +#define MRB_O_WRONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_WRONLY)) +#define MRB_O_RDWR_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDWR)) +#define MRB_O_READABLE_P(f) ((mrb_bool)((((f) & MRB_O_ACCMODE) | 2) == 2)) +#define MRB_O_WRITABLE_P(f) ((mrb_bool)(((((f) & MRB_O_ACCMODE) + 1) & 2) == 2)) #define E_IO_ERROR (mrb_class_get(mrb, "IOError")) #define E_EOF_ERROR (mrb_class_get(mrb, "EOFError")) diff --git a/mrbgems/mruby-io/mrblib/file_constants.rb b/mrbgems/mruby-io/mrblib/file_constants.rb index a68ee2598..bd77d53fe 100644 --- a/mrbgems/mruby-io/mrblib/file_constants.rb +++ b/mrbgems/mruby-io/mrblib/file_constants.rb @@ -1,21 +1,5 @@ class File module Constants - RDONLY = 0 - WRONLY = 1 - RDWR = 2 - NONBLOCK = 4 - APPEND = 8 - - BINARY = 0 - SYNC = 128 - NOFOLLOW = 256 - CREAT = 512 - TRUNC = 1024 - EXCL = 2048 - - NOCTTY = 131072 - DSYNC = 4194304 - FNM_SYSCASE = 0 FNM_NOESCAPE = 1 FNM_PATHNAME = 2 diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index ba1d770e3..dafcac533 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -407,11 +407,11 @@ mrb_file_size(mrb_state *mrb, mrb_value self) #ifdef MRB_WITHOUT_FLOAT mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_WITHOUT_FLOAT"); #else - return mrb_float_value(mrb, st.st_size); + return mrb_float_value(mrb, (mrb_float)st.st_size); #endif } - return mrb_fixnum_value(st.st_size); + return mrb_fixnum_value((mrb_int)st.st_size); } static int @@ -604,4 +604,22 @@ mrb_init_file(mrb_state *mrb) #endif mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE)); + mrb_define_const(mrb, cnst, "RDONLY", mrb_fixnum_value(MRB_O_RDONLY)); + mrb_define_const(mrb, cnst, "WRONLY", mrb_fixnum_value(MRB_O_WRONLY)); + mrb_define_const(mrb, cnst, "RDWR", mrb_fixnum_value(MRB_O_RDWR)); + mrb_define_const(mrb, cnst, "APPEND", mrb_fixnum_value(MRB_O_APPEND)); + mrb_define_const(mrb, cnst, "CREAT", mrb_fixnum_value(MRB_O_CREAT)); + mrb_define_const(mrb, cnst, "EXCL", mrb_fixnum_value(MRB_O_EXCL)); + mrb_define_const(mrb, cnst, "TRUNC", mrb_fixnum_value(MRB_O_TRUNC)); + mrb_define_const(mrb, cnst, "NONBLOCK", mrb_fixnum_value(MRB_O_NONBLOCK)); + mrb_define_const(mrb, cnst, "NOCTTY", mrb_fixnum_value(MRB_O_NOCTTY)); + mrb_define_const(mrb, cnst, "BINARY", mrb_fixnum_value(MRB_O_BINARY)); + mrb_define_const(mrb, cnst, "SHARE_DELETE", mrb_fixnum_value(MRB_O_SHARE_DELETE)); + mrb_define_const(mrb, cnst, "SYNC", mrb_fixnum_value(MRB_O_SYNC)); + mrb_define_const(mrb, cnst, "DSYNC", mrb_fixnum_value(MRB_O_DSYNC)); + mrb_define_const(mrb, cnst, "RSYNC", mrb_fixnum_value(MRB_O_RSYNC)); + mrb_define_const(mrb, cnst, "NOFOLLOW", mrb_fixnum_value(MRB_O_NOFOLLOW)); + mrb_define_const(mrb, cnst, "NOATIME", mrb_fixnum_value(MRB_O_NOATIME)); + mrb_define_const(mrb, cnst, "DIRECT", mrb_fixnum_value(MRB_O_DIRECT)); + mrb_define_const(mrb, cnst, "TMPFILE", mrb_fixnum_value(MRB_O_TMPFILE)); } diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index a5fe22e46..e28946597 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -32,8 +32,13 @@ typedef long fsuseconds_t; typedef int fmode_t; + #ifndef O_TMPFILE + #define O_TMPFILE O_TEMPORARY + #endif + #else #include <sys/wait.h> + #include <sys/time.h> #include <unistd.h> typedef size_t fsize_t; typedef time_t ftime_t; @@ -51,6 +56,12 @@ typedef mrb_int pid_t; #include <stdio.h> #include <string.h> +#define OPEN_ACCESS_MODE_FLAGS (O_RDONLY | O_WRONLY | O_RDWR) +#define OPEN_RDONLY_P(f) ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_RDONLY)) +#define OPEN_WRONLY_P(f) ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_WRONLY)) +#define OPEN_RDWR_P(f) ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_RDWR)) +#define OPEN_READABLE_P(f) ((mrb_bool)(OPEN_RDONLY_P(f) || OPEN_RDWR_P(f))) +#define OPEN_WRITABLE_P(f) ((mrb_bool)(OPEN_WRONLY_P(f) || OPEN_RDWR_P(f))) static void mrb_io_free(mrb_state *mrb, void *ptr); struct mrb_data_type mrb_io_type = { "IO", mrb_io_free }; @@ -58,7 +69,7 @@ struct mrb_data_type mrb_io_type = { "IO", mrb_io_free }; static struct mrb_io *io_get_open_fptr(mrb_state *mrb, mrb_value self); static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr); -static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags); +static int mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode); static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet); static struct mrb_io * @@ -100,30 +111,33 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status) static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) { - int flags = 0; + int flags; const char *m = mode; switch (*m++) { case 'r': - flags |= FMODE_READABLE; + flags = O_RDONLY; break; case 'w': - flags |= FMODE_WRITABLE | FMODE_CREATE | FMODE_TRUNC; + flags = O_WRONLY | O_CREAT | O_TRUNC; break; case 'a': - flags |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE; + flags = O_WRONLY | O_CREAT | O_APPEND; break; default: mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode); + flags = 0; /* not reached */ } while (*m) { switch (*m++) { case 'b': - flags |= FMODE_BINMODE; +#ifdef O_BINARY + flags |= O_BINARY; +#endif break; case '+': - flags |= FMODE_READWRITE; + flags = (flags & ~OPEN_ACCESS_MODE_FLAGS) | O_RDWR; break; case ':': /* XXX: PASSTHROUGH*/ @@ -136,38 +150,72 @@ mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) } static int -mrb_io_flags_to_modenum(mrb_state *mrb, int flags) +mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode) { - int modenum = 0; - - switch(flags & (FMODE_READABLE|FMODE_WRITABLE|FMODE_READWRITE)) { - case FMODE_READABLE: - modenum = O_RDONLY; - break; - case FMODE_WRITABLE: - modenum = O_WRONLY; - break; - case FMODE_READWRITE: - modenum = O_RDWR; - break; - } - - if (flags & FMODE_APPEND) { - modenum |= O_APPEND; - } - if (flags & FMODE_TRUNC) { - modenum |= O_TRUNC; + if (mrb_nil_p(mode)) { + return mrb_io_modestr_to_flags(mrb, "r"); } - if (flags & FMODE_CREATE) { - modenum |= O_CREAT; + else if (mrb_string_p(mode)) { + return mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); } + else { + int flags = 0; + mrb_int flags0 = mrb_int(mrb, mode); + + switch (flags0 & MRB_O_ACCMODE) { + case MRB_O_RDONLY: + flags |= O_RDONLY; + break; + case MRB_O_WRONLY: + flags |= O_WRONLY; + break; + case MRB_O_RDWR: + flags |= O_RDWR; + break; + default: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %v", mode); + } + + if (flags0 & MRB_O_APPEND) flags |= O_APPEND; + if (flags0 & MRB_O_CREAT) flags |= O_CREAT; + if (flags0 & MRB_O_EXCL) flags |= O_EXCL; + if (flags0 & MRB_O_TRUNC) flags |= O_TRUNC; +#ifdef O_NONBLOCK + if (flags0 & MRB_O_NONBLOCK) flags |= O_NONBLOCK; +#endif +#ifdef O_NOCTTY + if (flags0 & MRB_O_NOCTTY) flags |= O_NOCTTY; +#endif #ifdef O_BINARY - if (flags & FMODE_BINMODE) { - modenum |= O_BINARY; - } + if (flags0 & MRB_O_BINARY) flags |= O_BINARY; +#endif +#ifdef O_SHARE_DELETE + if (flags0 & MRB_O_SHARE_DELETE) flags |= O_SHARE_DELETE; +#endif +#ifdef O_SYNC + if (flags0 & MRB_O_SYNC) flags |= O_SYNC; +#endif +#ifdef O_DSYNC + if (flags0 & MRB_O_DSYNC) flags |= O_DSYNC; +#endif +#ifdef O_RSYNC + if (flags0 & MRB_O_RSYNC) flags |= O_RSYNC; +#endif +#ifdef O_NOFOLLOW + if (flags0 & MRB_O_NOFOLLOW) flags |= O_NOFOLLOW; +#endif +#ifdef O_NOATIME + if (flags0 & MRB_O_NOATIME) flags |= O_NOATIME; +#endif +#ifdef O_DIRECT + if (flags0 & MRB_O_DIRECT) flags |= O_DIRECT; +#endif +#ifdef O_TMPFILE + if (flags0 & MRB_O_TMPFILE) flags |= O_TMPFILE; #endif - return modenum; + return flags; + } } static void @@ -317,11 +365,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) ofd[0] = INVALID_HANDLE_VALUE; ofd[1] = INVALID_HANDLE_VALUE; - mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); + mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt); io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); pname = RSTRING_CSTR(mrb, cmd); - flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); + flags = mrb_io_mode_to_flags(mrb, mode); doexec = (strcmp("-", pname) != 0); opt_in = option_to_fd(mrb, opt, "in"); @@ -332,14 +380,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; - if (flags & FMODE_READABLE) { + if (OPEN_READABLE_P(flags)) { if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) || !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) { mrb_sys_fail(mrb, "pipe"); } } - if (flags & FMODE_WRITABLE) { + if (OPEN_WRITABLE_P(flags)) { if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) { mrb_sys_fail(mrb, "pipe"); @@ -353,11 +401,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) si.dwFlags |= STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.dwFlags |= STARTF_USESTDHANDLES; - if (flags & FMODE_READABLE) { + if (OPEN_READABLE_P(flags)) { si.hStdOutput = ofd[1]; si.hStdError = ofd[1]; } - if (flags & FMODE_WRITABLE) { + if (OPEN_WRITABLE_P(flags)) { si.hStdInput = ifd[0]; } if (!CreateProcess( @@ -381,8 +429,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0); fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0); fptr->pid = pid; - fptr->readable = ((flags & FMODE_READABLE) != 0); - fptr->writable = ((flags & FMODE_WRITABLE) != 0); + fptr->readable = OPEN_READABLE_P(flags); + fptr->writable = OPEN_WRITABLE_P(flags); fptr->sync = 0; DATA_TYPE(io) = &mrb_io_type; @@ -413,18 +461,18 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) int saved_errno; int opt_in, opt_out, opt_err; - mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); + mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt); io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); pname = RSTRING_CSTR(mrb, cmd); - flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); + flags = mrb_io_mode_to_flags(mrb, mode); doexec = (strcmp("-", pname) != 0); opt_in = option_to_fd(mrb, opt, "in"); opt_out = option_to_fd(mrb, opt, "out"); opt_err = option_to_fd(mrb, opt, "err"); - if (flags & FMODE_READABLE) { + if (OPEN_READABLE_P(flags)) { if (pipe(pr) == -1) { mrb_sys_fail(mrb, "pipe"); } @@ -432,7 +480,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) mrb_fd_cloexec(mrb, pr[1]); } - if (flags & FMODE_WRITABLE) { + if (OPEN_WRITABLE_P(flags)) { if (pipe(pw) == -1) { if (pr[0] != -1) close(pr[0]); if (pr[1] != -1) close(pr[1]); @@ -461,14 +509,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) if (opt_err != -1) { dup2(opt_err, 2); } - if (flags & FMODE_READABLE) { + if (OPEN_READABLE_P(flags)) { close(pr[0]); if (pr[1] != 1) { dup2(pr[1], 1); close(pr[1]); } } - if (flags & FMODE_WRITABLE) { + if (OPEN_WRITABLE_P(flags)) { close(pw[1]); if (pw[0] != 0) { dup2(pw[0], 0); @@ -487,12 +535,12 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) break; default: /* parent */ - if ((flags & FMODE_READABLE) && (flags & FMODE_WRITABLE)) { + if (OPEN_RDWR_P(flags)) { close(pr[1]); fd = pr[0]; close(pw[0]); write_fd = pw[1]; - } else if (flags & FMODE_READABLE) { + } else if (OPEN_RDONLY_P(flags)) { close(pr[1]); fd = pr[0]; } else { @@ -506,8 +554,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) fptr->fd = fd; fptr->fd2 = write_fd; fptr->pid = pid; - fptr->readable = ((flags & FMODE_READABLE) != 0); - fptr->writable = ((flags & FMODE_WRITABLE) != 0); + fptr->readable = OPEN_READABLE_P(flags); + fptr->writable = OPEN_WRITABLE_P(flags); fptr->sync = 0; DATA_TYPE(io) = &mrb_io_type; @@ -517,11 +565,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) case -1: /* error */ saved_errno = errno; - if (flags & FMODE_READABLE) { + if (OPEN_READABLE_P(flags)) { close(pr[0]); close(pr[1]); } - if (flags & FMODE_WRITABLE) { + if (OPEN_WRITABLE_P(flags)) { close(pw[0]); close(pw[1]); } @@ -606,7 +654,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) mode = opt = mrb_nil_value(); - mrb_get_args(mrb, "i|So", &fd, &mode, &opt); + mrb_get_args(mrb, "i|oo", &fd, &mode, &opt); if (mrb_nil_p(mode)) { mode = mrb_str_new_cstr(mrb, "r"); } @@ -614,7 +662,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) opt = mrb_hash_new(mrb); } - flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); + flags = mrb_io_mode_to_flags(mrb, mode); mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); @@ -629,8 +677,8 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) DATA_PTR(io) = fptr; fptr->fd = (int)fd; - fptr->readable = ((flags & FMODE_READABLE) != 0); - fptr->writable = ((flags & FMODE_WRITABLE) != 0); + fptr->readable = OPEN_READABLE_P(flags); + fptr->writable = OPEN_WRITABLE_P(flags); fptr->sync = 0; return io; } @@ -785,20 +833,16 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) mrb_value mode = mrb_nil_value(); mrb_int fd, perm = -1; const char *pat; - int flags, modenum; + int flags; - mrb_get_args(mrb, "S|Si", &path, &mode, &perm); - if (mrb_nil_p(mode)) { - mode = mrb_str_new_cstr(mrb, "r"); - } + mrb_get_args(mrb, "S|oi", &path, &mode, &perm); if (perm < 0) { perm = 0666; } pat = RSTRING_CSTR(mrb, path); - flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); - modenum = mrb_io_flags_to_modenum(mrb, flags); - fd = mrb_cloexec_open(mrb, pat, modenum, perm); + flags = mrb_io_mode_to_flags(mrb, mode); + fd = mrb_cloexec_open(mrb, pat, flags, perm); return mrb_fixnum_value(fd); } diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c index 3cf1c6111..7e272d45a 100644 --- a/mrbgems/mruby-io/test/mruby_io_test.c +++ b/mrbgems/mruby-io/test/mruby_io_test.c @@ -1,3 +1,4 @@ +#include <mruby/common.h> #include <sys/types.h> #include <errno.h> @@ -18,12 +19,6 @@ typedef int mode_t; #define open _open #define close _close -#if defined(__MINGW64_VERSION_MAJOR) -# define MRB_MINGW64_VERSION (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR) -#elif defined(__MINGW32_MAJOR_VERSION) -# define MRB_MINGW32_VERSION (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION) -#endif - #if defined(_MSC_VER) || \ (defined(MRB_MINGW32_VERSION) && MRB_MINGW32_VERSION < 3021) || \ (defined(MRB_MINGW64_VERSION) && MRB_MINGW64_VERSION < 4000) diff --git a/mrbgems/mruby-socket/test/sockettest.c b/mrbgems/mruby-socket/test/sockettest.c index 3017c7cc1..e9247d030 100644 --- a/mrbgems/mruby-socket/test/sockettest.c +++ b/mrbgems/mruby-socket/test/sockettest.c @@ -8,7 +8,9 @@ #include <io.h> -#ifdef _MSC_VER +#if defined(_MSC_VER) || \ + (defined(MRB_MINGW32_VERSION) && MRB_MINGW32_VERSION < 3021) || \ + (defined(MRB_MINGW64_VERSION) && MRB_MINGW64_VERSION < 4000) #include <fcntl.h> #include <sys/stat.h> diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 7197b634c..5ce43e465 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -238,7 +238,7 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) mrb_float f = mrb_float(obj); mrb_check_num_exact(mrb, f); - if (f > (mrb_float)MRB_TIME_MAX || (mrb_float)MRB_TIME_MIN > f) { + if (f >= ((mrb_float)MRB_TIME_MAX-1.0) || f < ((mrb_float)MRB_TIME_MIN+1.0)) { goto out_of_range; } diff --git a/src/backtrace.c b/src/backtrace.c index 186009523..591f4ea4b 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -79,7 +79,7 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr static void print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) { - int i; + mrb_int i; mrb_int n = RARRAY_LEN(backtrace); mrb_value *loc, mesg; FILE *stream = stderr; @@ -89,7 +89,7 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) { if (mrb_string_p(*loc)) { fprintf(stream, "\t[%d] %.*s\n", - i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); + (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); } } if (mrb_string_p(*loc)) { diff --git a/src/hash.c b/src/hash.c index 70f437358..8e7f97147 100644 --- a/src/hash.c +++ b/src/hash.c @@ -222,9 +222,8 @@ static void ht_compact(mrb_state *mrb, htable *t) { segment *seg; - mrb_int i; + uint16_t i, i2; segment *seg2 = NULL; - mrb_int i2; mrb_int size = 0; if (t == NULL) return; diff --git a/src/string.c b/src/string.c index c7b9db17a..9ea19d107 100644 --- a/src/string.c +++ b/src/string.c @@ -504,25 +504,45 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos) #endif +#ifndef MRB_QS_SHORT_STRING_LENGTH +#define MRB_QS_SHORT_STRING_LENGTH 2048 +#endif + static inline mrb_int mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) { - const unsigned char *x = xs, *xe = xs + m; - const unsigned char *y = ys; - int i; - ptrdiff_t qstable[256]; + if (n + m < MRB_QS_SHORT_STRING_LENGTH) { + const unsigned char *y = ys; + const unsigned char *ye = ys+n-m+1; - /* Preprocessing */ - for (i = 0; i < 256; ++i) - qstable[i] = m + 1; - for (; x < xe; ++x) - qstable[*x] = xe - x; - /* Searching */ - for (; y + m <= ys + n; y += *(qstable + y[m])) { - if (*xs == *y && memcmp(xs, y, m) == 0) - return (mrb_int)(y - ys); + for (;;) { + y = (const unsigned char*)memchr(y, xs[0], (size_t)(ye-y)); + if (y == NULL) return -1; + if (memcmp(xs, y, m) == 0) { + return (mrb_int)(y - ys); + } + y++; + } + return -1; + } + else { + const unsigned char *x = xs, *xe = xs + m; + const unsigned char *y = ys; + int i; + ptrdiff_t qstable[256]; + + /* Preprocessing */ + for (i = 0; i < 256; ++i) + qstable[i] = m + 1; + for (; x < xe; ++x) + qstable[*x] = xe - x; + /* Searching */ + for (; y + m <= ys + n; y += *(qstable + y[m])) { + if (*xs == *y && memcmp(xs, y, m) == 0) + return (mrb_int)(y - ys); + } + return -1; } - return -1; } static mrb_int diff --git a/src/symbol.c b/src/symbol.c index b8d0ea1e7..ad186dce3 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -48,14 +48,14 @@ sym_validate_len(mrb_state *mrb, size_t len) static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; static mrb_sym -sym_inline_pack(const char *name, uint16_t len) +sym_inline_pack(const char *name, size_t len) { - const int lower_length_max = (MRB_SYMBOL_BIT - 2) / 5; - const int mix_length_max = (MRB_SYMBOL_BIT - 2) / 6; + const size_t lower_length_max = (MRB_SYMBOL_BIT - 2) / 5; + const size_t mix_length_max = (MRB_SYMBOL_BIT - 2) / 6; char c; const char *p; - int i; + size_t i; mrb_sym sym = 0; mrb_bool lower = TRUE; @@ -124,7 +124,7 @@ symhash(const char *key, size_t len) } static mrb_sym -find_symbol(mrb_state *mrb, const char *name, uint16_t len, uint8_t *hashp) +find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) { mrb_sym i; symbol_name *sname; @@ -1497,11 +1497,9 @@ RETRY_TRY_BLOCK: ci->target_class = MRB_PROC_TARGET_CLASS(m); ci->proc = m; if (MRB_PROC_ENV_P(m)) { - mrb_sym mid; struct REnv *e = MRB_PROC_ENV(m); - mid = e->mid; - if (mid) ci->mid = mid; + ci->mid = e->mid; if (!e->stack) { e->stack = mrb->c->stack; } diff --git a/test/t/exception.rb b/test/t/exception.rb index a6f69eef6..c9afeb61a 100644 --- a/test/t/exception.rb +++ b/test/t/exception.rb @@ -400,7 +400,7 @@ assert('GC in rescue') do end rescue => exception GC.start - assert_equal("#{__FILE__}:#{line}:in call", + assert_equal("#{__FILE__}:#{line}", exception.backtrace.first) end end @@ -418,7 +418,7 @@ assert('Method call in rescue') do rescue => exception [3].each do end - assert_equal("#{__FILE__}:#{line}:in call", + assert_equal("#{__FILE__}:#{line}", exception.backtrace.first) end end |
