From d8c19c3e6e86eeeafe7b438dae8e872759bd48a6 Mon Sep 17 00:00:00 2001 From: usa Date: Tue, 6 Feb 2018 18:59:18 +0000 Subject: [PATCH] mjit mswin support (WIP) * win32/Makefile.sub (LIBRUBYARG_SHARED): define for MJIT because it is used in common.mk. * mjit.c (make_pch): skip temporary for mswin. * mjit.c (compile_c_to_so, init_header_filename, mjit_init): mswin support. * mjig_compile.c (mjit_compile): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62267 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- mjit.c | 71 ++++++++++++++++++++++++++++++++++++++++------ mjit_compile.c | 3 ++ win32/Makefile.sub | 1 + 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/mjit.c b/mjit.c index 7541be6213..763b31b9a8 100644 --- a/mjit.c +++ b/mjit.c @@ -574,6 +574,17 @@ static const char *CLANG_COMMON_ARGS[] = {"clang", "-O2", "-fPIC", "-shared", "- #endif /* #if __MACH__ */ +#ifdef _MSC_VER +static const char *VC_COMMON_ARGS_DEBUG[] = {"cl.exe", "-nologo", "-O0", "-Zi", "-MD", "-LD", NULL}; +static const char *VC_COMMON_ARGS[] = {"cl.exe", "-nologo", +# if _MSC_VER < 1400 + "-O2b2xg-", +# else + "-O2sy-", +# endif + "-MD", "-LD", NULL}; +#endif + static const char *CLANG_USE_PCH_ARGS[] = {"-include-pch", NULL, "-Wl,-undefined", "-Wl,dynamic_lookup", NULL}; static const char *CLANG_EMIT_PCH_ARGS[] = {"-emit-pch", NULL}; @@ -586,6 +597,10 @@ static void make_pch(void) { int exit_code; +#ifdef _MSC_VER + /* XXX TODO */ + exit_code = 0; +#else static const char *input[] = {NULL, NULL}; static const char *output[] = {"-o", NULL, NULL}; char **args; @@ -610,6 +625,7 @@ make_pch(void) exit_code = exec_process(cc_path, args); xfree(args); +#endif CRITICAL_SECTION_START(3, "in make_pch"); if (exit_code == 0) { @@ -624,29 +640,50 @@ make_pch(void) CRITICAL_SECTION_FINISH(3, "in make_pch"); } +#define append_str2(p, str, len) ((char *)memcpy((p), str, (len))+(len)) +#define append_str(p, str) append_str2(p, str, sizeof(str)-1) + /* Compile C file to so. It returns 1 if it succeeds. */ static int compile_c_to_so(const char *c_file, const char *so_file) { int exit_code; static const char *input[] = {NULL, NULL}; - static const char *output[] = {"-o", NULL, NULL}; + static const char *output[] = {"-o", NULL, NULL}; const char *libs[] = { -#ifdef _WIN32 +#ifdef _MSC_VER + LIBRUBYARG_SHARED, + "-link", + libruby_installed, + libruby_build, +#else +# ifdef _WIN32 /* Look for ruby.dll.a in build and install directories. */ libruby_installed, libruby_build, /* Link to ruby.dll.a, because Windows DLLs don't allow unresolved symbols. */ LIBRUBYARG_SHARED, "-lmsvcrt", -# ifdef __GNUC__ +# ifdef __GNUC__ "-lgcc", +# endif # endif #endif NULL}; char **args; input[0] = c_file; +#ifdef _MSC_VER + { + char *p = (char *)output[0] = xmalloc(3 + strlen(so_file) + 1); + p = append_str(p, "-Fe"); + p = append_str(p, so_file); + *p = '\0'; + } + args = form_args(4, (mjit_opts.debug ? VC_COMMON_ARGS_DEBUG : VC_COMMON_ARGS), + output, input, libs); + xfree(output[0]); +#else output[1] = so_file; if (mjit_opts.cc == MJIT_CC_CLANG) { CLANG_USE_PCH_ARGS[1] = pch_file; @@ -657,6 +694,7 @@ compile_c_to_so(const char *c_file, const char *so_file) args = form_args(5, (mjit_opts.debug ? GCC_COMMON_ARGS_DEBUG : GCC_COMMON_ARGS), GCC_USE_PCH_ARGS, input, output, libs); } +#endif if (args == NULL) return FALSE; @@ -1057,9 +1095,9 @@ mjit_get_iseq_func(const struct rb_iseq_constant_body *body) ones to prevent changing C compiler for security reasons. */ #define GCC_PATH "gcc" #define CLANG_PATH "clang" - -#define append_str2(p, str, len) ((char *)memcpy((p), str, (len))+(len)) -#define append_str(p, str) append_str2(p, str, sizeof(str)-1) +#ifdef _MSC_VER +# define VC_PATH "cl.exe" +#endif static void init_header_filename(void) @@ -1090,11 +1128,20 @@ init_header_filename(void) fclose(f); #ifdef _WIN32 +# ifdef _MSC_VER + p = libruby_build = xmalloc(9 + baselen + 1); + p = append_str(p, "-LIBPATH:"); +#else p = libruby_build = xmalloc(2 + baselen + 1); p = append_str(p, "-L"); +#endif p = append_str2(p, basedir, baselen); *p = '\0'; +# ifdef _MSC_VER + libruby_installed = xmalloc(9 + baselen + 4 + 1); +#else libruby_installed = xmalloc(2 + baselen + 4 + 1); +#endif p = append_str2(libruby_installed, libruby_build, p - libruby_build); p = append_str(p, "/lib"); *p = '\0'; @@ -1150,22 +1197,30 @@ mjit_init(struct mjit_options *opts) mjit_opts.max_cache_size = MIN_CACHE_SIZE; if (mjit_opts.cc == MJIT_CC_DEFAULT) { -#if defined(__clang__) +#if _MSC_VER + verbose(2, "MJIT: CC defaults to cl"); +#else +# if defined(__clang__) mjit_opts.cc = MJIT_CC_CLANG; verbose(2, "MJIT: CC defaults to clang"); -#else +# else mjit_opts.cc = MJIT_CC_GCC; verbose(2, "MJIT: CC defaults to gcc"); +# endif #endif } /* Initialize variables for compilation */ pch_status = PCH_NOT_READY; +#ifdef _MSC_VER + cc_path = VC_PATH; +#else if (mjit_opts.cc == MJIT_CC_CLANG) { cc_path = CLANG_PATH; } else { cc_path = GCC_PATH; } +#endif if (getenv("TMP") != NULL) { /* For MinGW */ tmp_dir = get_string(getenv("TMP")); diff --git a/mjit_compile.c b/mjit_compile.c index 3155ef2c84..69fc8947d8 100644 --- a/mjit_compile.c +++ b/mjit_compile.c @@ -137,6 +137,9 @@ mjit_compile(FILE *f, const struct rb_iseq_constant_body *body, const char *func status.success = TRUE; status.compiled_for_pos = ZALLOC_N(int, body->iseq_size); +#ifdef _WIN32 + fprintf(f, "__declspec(dllexport)\n"); +#endif fprintf(f, "VALUE\n%s(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)\n{\n", funcname); fprintf(f, " VALUE *stack = reg_cfp->sp;\n"); diff --git a/win32/Makefile.sub b/win32/Makefile.sub index 7153612519..4e143af419 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -354,6 +354,7 @@ LIBRUBY_SO = $(RUBY_SO_NAME).dll LIBRUBY_SONAME= $(RUBY_SO_NAME).dll LIBRUBY = $(RUBY_SO_NAME).lib LIBRUBYARG = $(LIBRUBY) +LIBRUBYARG_SHARED = $(LIBRUBY) LIBRUBY_RELATIVE = yes THREAD_MODEL = win32