summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-22 02:28:10 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-22 02:28:10 +0000
commit85ddcb935791939d107cf11db7b3839f82b95cb0 (patch)
treecee3fc46b268f02e2b737427986ffae8b0e241d3
parent9852802c887b1457dbff4f83e341b768fbfe6a5d (diff)
merge revision(s) 54737,54740,55792: [Backport #14623]
Support MSVC14 and 15 [Bug #11118] Search _pioinfo which is not exported after MSVC14. [Bug #12014] [GH-884] win32.c: suppress warnings * win32/win32.c (set_pioinfo_extra): remove "/*" within comment. * win32/win32.c (set_pioinfo_extra): use more reliable way to search the position of pioinfo of VC14, and also support debug library of it. patched by davispuh AT gmail.com [ruby-core:76644] [Bug #12644] this fixes also [Bug #12631] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@62884 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog21
-rw-r--r--test/-ext-/symbol/noninterned_name.rb15
-rw-r--r--test/-ext-/symbol/test_inadvertent_creation.rb23
-rw-r--r--version.h6
-rwxr-xr-xwin32/mkexports.rb1
-rw-r--r--win32/win32.c90
6 files changed, 134 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 7f7a9e7af6..10675ff13f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Thu Mar 22 11:24:43 2018 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (set_pioinfo_extra): use more reliable way to search
+ the position of pioinfo of VC14, and also support debug library of it.
+ patched by davispuh AT gmail.com
+ [ruby-core:76644] [Bug #12644]
+ this fixes also [Bug #12631]
+
+Thu Mar 22 11:24:43 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ win32.c: suppress warnings
+
+ * win32/win32.c (set_pioinfo_extra): remove "/*" within comment.
+
+Thu Mar 22 11:24:43 2018 NARUSE, Yui <naruse@ruby-lang.org>
+
+ Support MSVC14 and 15 [Bug #11118]
+
+ Search _pioinfo which is not exported after MSVC14.
+ [Bug #12014] [GH-884]
+
Mon Mar 19 00:34:38 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
win32.c: unknown reparse tags
diff --git a/test/-ext-/symbol/noninterned_name.rb b/test/-ext-/symbol/noninterned_name.rb
new file mode 100644
index 0000000000..7c9097ae25
--- /dev/null
+++ b/test/-ext-/symbol/noninterned_name.rb
@@ -0,0 +1,15 @@
+require "-test-/symbol"
+
+module Test_Symbol
+ module NonInterned
+ module_function
+
+ def noninterned_name(prefix = "")
+ prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}"
+ begin
+ name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}"
+ end while Bug::Symbol.find(name)
+ name
+ end
+ end
+end
diff --git a/test/-ext-/symbol/test_inadvertent_creation.rb b/test/-ext-/symbol/test_inadvertent_creation.rb
index 5d3906a40b..a923340828 100644
--- a/test/-ext-/symbol/test_inadvertent_creation.rb
+++ b/test/-ext-/symbol/test_inadvertent_creation.rb
@@ -1,16 +1,10 @@
# frozen_string_literal: false
require 'test/unit'
-require "-test-/symbol"
+require_relative 'noninterned_name'
module Test_Symbol
class TestInadvertent < Test::Unit::TestCase
- def noninterned_name(prefix = "")
- prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}"
- begin
- name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}"
- end while Bug::Symbol.find(name)
- name
- end
+ include NonInterned
def setup
@obj = Object.new
@@ -362,15 +356,9 @@ module Test_Symbol
end
def test_gc_attrset
- assert_separately(['-r-test-/symbol', '-', '[ruby-core:62226] [Bug #9787]'], <<-'end;') # begin
- bug = ARGV.shift
- def noninterned_name(prefix = "")
- prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}"
- begin
- name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}"
- end while Bug::Symbol.find(name) or Bug::Symbol.find(name + "=")
- name
- end
+ assert_separately(['-r-test-/symbol', '-r-ext-/symbol/noninterned_name', '-'], "#{<<-'begin;'}\n#{<<-"end;"}")
+ bug = '[ruby-core:62226] [Bug #9787]'
+ include Test_Symbol::NonInterned
names = Array.new(1000) {noninterned_name("gc")}
names.each {|n| n.to_sym}
GC.start(immediate_sweep: false)
@@ -378,6 +366,7 @@ module Test_Symbol
eval(":#{n}=")
assert_nothing_raised(TypeError, bug) {eval("proc{self.#{n} = nil}")}
end
+ begin;
end;
end
diff --git a/version.h b/version.h
index c5de3e68d8..1947c9ce32 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "2.3.7"
-#define RUBY_RELEASE_DATE "2018-03-20"
-#define RUBY_PATCHLEVEL 430
+#define RUBY_RELEASE_DATE "2018-03-22"
+#define RUBY_PATCHLEVEL 431
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 20
+#define RUBY_RELEASE_DAY 22
#include "ruby/version.h"
diff --git a/win32/mkexports.rb b/win32/mkexports.rb
index c3514f13ab..d26acbb107 100755
--- a/win32/mkexports.rb
+++ b/win32/mkexports.rb
@@ -114,6 +114,7 @@ class Exports::Mswin < Exports
when /OBJECT/, /LIBRARY/
next if /^[[:xdigit:]]+ 0+ UNDEF / =~ l
next unless /External/ =~ l
+ next if /(?:_local_stdio_printf_options|v(f|sn?)printf_l)\Z/ =~ l
next unless l.sub!(/.*?\s(\(\)\s+)?External\s+\|\s+/, '')
is_data = !$1
if noprefix or /^[@_]/ =~ l
diff --git a/win32/win32.c b/win32/win32.c
index 3f189b3a6c..9c25c939f1 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -2320,6 +2320,24 @@ typedef struct {
#endif
/* License: Ruby's */
+#if RUBY_MSVCRT_VERSION >= 140
+typedef char lowio_text_mode;
+typedef char lowio_pipe_lookahead[3];
+
+typedef struct {
+ CRITICAL_SECTION lock;
+ intptr_t osfhnd; // underlying OS file HANDLE
+ __int64 startpos; // File position that matches buffer start
+ unsigned char osfile; // Attributes of file (e.g., open in text mode?)
+ lowio_text_mode textmode;
+ lowio_pipe_lookahead _pipe_lookahead;
+
+ uint8_t unicode : 1; // Was the file opened as unicode?
+ uint8_t utf8translations : 1; // Buffer contains translations other than CRLF
+ uint8_t dbcsBufferUsed : 1; // Is the dbcsBuffer in use?
+ char dbcsBuffer; // Buffer for the lead byte of DBCS when converting from DBCS to Unicode
+} ioinfo;
+#else
typedef struct {
intptr_t osfhnd; /* underlying OS file HANDLE */
char osfile; /* attributes of file (e.g., open in text mode?) */
@@ -2331,20 +2349,25 @@ typedef struct {
char pipech2[2];
#endif
} ioinfo;
+#endif
#if !defined _CRTIMP || defined __MINGW32__
#undef _CRTIMP
#define _CRTIMP __declspec(dllimport)
#endif
+#if RUBY_MSVCRT_VERSION >= 140
+static ioinfo ** __pioinfo = NULL;
+#define IOINFO_L2E 6
+#else
EXTERN_C _CRTIMP ioinfo * __pioinfo[];
+#define IOINFO_L2E 5
+#endif
static inline ioinfo* _pioinfo(int);
-#define IOINFO_L2E 5
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
#define _osfhnd(i) (_pioinfo(i)->osfhnd)
#define _osfile(i) (_pioinfo(i)->osfile)
-#define _pipech(i) (_pioinfo(i)->pipech)
#define rb_acrt_lowio_lock_fh(i) EnterCriticalSection(&_pioinfo(i)->lock)
#define rb_acrt_lowio_unlock_fh(i) LeaveCriticalSection(&_pioinfo(i)->lock)
@@ -2355,6 +2378,68 @@ static size_t pioinfo_extra = 0; /* workaround for VC++8 SP1 */
static void
set_pioinfo_extra(void)
{
+#if RUBY_MSVCRT_VERSION >= 140
+# define FUNCTION_RET 0xc3 /* ret */
+# ifdef _DEBUG
+# define UCRTBASE "ucrtbased.dll"
+# else
+# define UCRTBASE "ucrtbase.dll"
+# endif
+ /* get __pioinfo addr with _isatty */
+ char *p = (char*)get_proc_address(UCRTBASE, "_isatty", NULL);
+ char *pend = p;
+ /* _osfile(fh) & FDEV */
+
+# if _WIN64
+ int32_t rel;
+ char *rip;
+ /* add rsp, _ */
+# define FUNCTION_BEFORE_RET_MARK "\x48\x83\xc4"
+# define FUNCTION_SKIP_BYTES 1
+# ifdef _DEBUG
+ /* lea rcx,[__pioinfo's addr in RIP-relative 32bit addr] */
+# define PIOINFO_MARK "\x48\x8d\x0d"
+# else
+ /* lea rdx,[__pioinfo's addr in RIP-relative 32bit addr] */
+# define PIOINFO_MARK "\x48\x8d\x15"
+# endif
+
+# else /* x86 */
+ /* pop ebp */
+# define FUNCTION_BEFORE_RET_MARK "\x5d"
+# define FUNCTION_SKIP_BYTES 0
+ /* mov eax,dword ptr [eax*4+100EB430h] */
+# define PIOINFO_MARK "\x8B\x04\x85"
+# endif
+ if (p) {
+ for (pend += 10; pend < p + 300; pend++) {
+ // find end of function
+ if (memcmp(pend, FUNCTION_BEFORE_RET_MARK, sizeof(FUNCTION_BEFORE_RET_MARK) - 1) == 0 &&
+ *(pend + (sizeof(FUNCTION_BEFORE_RET_MARK) - 1) + FUNCTION_SKIP_BYTES) & FUNCTION_RET == FUNCTION_RET) {
+ // search backwards from end of function
+ for (pend -= (sizeof(PIOINFO_MARK) - 1); pend > p; pend--) {
+ if (memcmp(pend, PIOINFO_MARK, sizeof(PIOINFO_MARK) - 1) == 0) {
+ p = pend;
+ goto found;
+ }
+ }
+ break;
+ }
+ }
+ }
+ fprintf(stderr, "unexpected " UCRTBASE "\n");
+ _exit(1);
+
+ found:
+ p += sizeof(PIOINFO_MARK) - 1;
+#if _WIN64
+ rel = *(int32_t*)(p);
+ rip = p + sizeof(int32_t);
+ __pioinfo = (ioinfo**)(rip + rel);
+#else
+ __pioinfo = *(ioinfo***)(p);
+#endif
+#else
int fd;
fd = _open("NUL", O_RDONLY);
@@ -2369,6 +2454,7 @@ set_pioinfo_extra(void)
/* not found, maybe something wrong... */
pioinfo_extra = 0;
}
+#endif
}
#else
#define pioinfo_extra 0