summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml24
-rw-r--r--README.md2
-rw-r--r--appveyor.yml8
-rw-r--r--examples/targets/build_config_dreamcast_shelf.rb108
-rw-r--r--include/mrbconf.h7
-rw-r--r--include/mruby.h10
-rw-r--r--include/mruby/common.h10
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb31
-rw-r--r--mrbgems/mruby-array-ext/test/array.rb13
-rw-r--r--mrbgems/mruby-error/src/exception.c6
-rw-r--r--mrbgems/mruby-io/include/mruby/ext/io.h32
-rw-r--r--mrbgems/mruby-io/mrblib/file_constants.rb16
-rw-r--r--mrbgems/mruby-io/src/file.c22
-rw-r--r--mrbgems/mruby-io/src/io.c174
-rw-r--r--mrbgems/mruby-io/test/mruby_io_test.c7
-rw-r--r--mrbgems/mruby-socket/test/sockettest.c4
-rw-r--r--mrbgems/mruby-time/src/time.c2
-rw-r--r--src/backtrace.c4
-rw-r--r--src/hash.c3
-rw-r--r--src/string.c48
-rw-r--r--src/symbol.c10
-rw-r--r--src/vm.c4
-rw-r--r--test/t/exception.rb4
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
+
diff --git a/README.md b/README.md
index ab518734b..b11e9412d 100644
--- a/README.md
+++ b/README.md
@@ -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;
diff --git a/src/vm.c b/src/vm.c
index 2ccc03e30..214907a19 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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