From e4da6874134c2ec37d29b297d21c54027b99152b Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 17 Jan 2010 03:43:22 +1300 Subject: [PATCH] vm: Tweak Factor VM to compile with Microsoft Visual Studio on Windows, in addition to Mingw. Add an Nmakefile which can be used for this purpose. Rename Makefile to GNUmakefile. --- Makefile => GNUmakefile | 0 Nmakefile | 65 +++++++++++++++++ build-support/cleanup | 3 +- build-support/factor.sh | 4 +- vm/alien.cpp | 8 +-- vm/bitwise_hacks.hpp | 16 ++++- vm/code_blocks.cpp | 2 +- vm/compaction.cpp | 2 +- vm/factor.cpp | 12 +--- vm/factor.hpp | 2 +- vm/free_list.hpp | 2 +- vm/gc.cpp | 12 ++-- vm/instruction_operands.cpp | 2 +- vm/layouts.hpp | 2 +- vm/main-windows-ce.cpp | 129 ++-------------------------------- vm/main-windows-nt.cpp | 34 ++++----- vm/master.hpp | 12 +++- vm/math.cpp | 10 +-- vm/object_start_map.cpp | 2 +- vm/os-unix.cpp | 8 +-- vm/os-unix.hpp | 1 + vm/os-windows-ce.hpp | 1 - vm/os-windows-nt.cpp | 2 +- vm/os-windows-nt.hpp | 17 +++-- vm/os-windows.cpp | 135 +++++++++++++++++++++++++++++++++--- vm/os-windows.hpp | 22 ++++-- vm/platform.hpp | 20 +++--- vm/strings.cpp | 4 +- vm/vm.hpp | 6 +- 29 files changed, 318 insertions(+), 217 deletions(-) rename Makefile => GNUmakefile (100%) create mode 100755 Nmakefile mode change 100644 => 100755 vm/bitwise_hacks.hpp mode change 100644 => 100755 vm/factor.hpp mode change 100644 => 100755 vm/free_list.hpp mode change 100644 => 100755 vm/main-windows-ce.cpp mode change 100644 => 100755 vm/main-windows-nt.cpp mode change 100644 => 100755 vm/os-windows-ce.hpp mode change 100644 => 100755 vm/os-windows.hpp mode change 100644 => 100755 vm/platform.hpp diff --git a/Makefile b/GNUmakefile similarity index 100% rename from Makefile rename to GNUmakefile diff --git a/Nmakefile b/Nmakefile new file mode 100755 index 0000000000..04992e6771 --- /dev/null +++ b/Nmakefile @@ -0,0 +1,65 @@ +LINK_CLFAGS = +CL_FLAGS = /O2 /W3 + +OBJS = vm\main-windows-nt.obj \ + vm\os-windows-nt.obj \ + vm\os-windows.obj \ + vm\aging_collector.obj \ + vm\alien.obj \ + vm\arrays.obj \ + vm\bignum.obj \ + vm\booleans.obj \ + vm\byte_arrays.obj \ + vm\callbacks.obj \ + vm\callstack.obj \ + vm\code_blocks.obj \ + vm\code_heap.obj \ + vm\compaction.obj \ + vm\contexts.obj \ + vm\data_heap.obj \ + vm\data_heap_checker.obj \ + vm\debug.obj \ + vm\dispatch.obj \ + vm\entry_points.obj \ + vm\errors.obj \ + vm\factor.obj \ + vm\free_list.obj \ + vm\full_collector.obj \ + vm\gc.obj \ + vm\image.obj \ + vm\inline_cache.obj \ + vm\instruction_operands.obj \ + vm\io.obj \ + vm\jit.obj \ + vm\math.obj \ + vm\nursery_collector.obj \ + vm\object_start_map.obj \ + vm\objects.obj \ + vm\primitives.obj \ + vm\profiler.obj \ + vm\quotations.obj \ + vm\run.obj \ + vm\strings.obj \ + vm\to_tenured_collector.obj \ + vm\tuples.obj \ + vm\utilities.obj \ + vm\vm.obj \ + vm\words.obj + +.cpp.obj: + cl /nologo /EHsc $(CL_FLAGS) /Fo$@ /c $< + +all: factor.com factor.exe + +factor.com: $(OBJS) + link $(LINK_FLAGS) /nologo /out:factor.com /SUBSYSTEM:console $(OBJS) + +factor.exe: $(OBJS) + link $(LINK_FLAGS) /nologo /out:factor.exe /SUBSYSTEM:windows $(OBJS) + +clean: + del vm\*.obj + del factor.com + del factor.exe + +.PHONY: clean diff --git a/build-support/cleanup b/build-support/cleanup index 2d2aab0bba..2173619acb 100644 --- a/build-support/cleanup +++ b/build-support/cleanup @@ -3,6 +3,7 @@ temp logs .git .gitignore -Makefile +GNUmakefile +Nmakefile unmaintained build-support diff --git a/build-support/factor.sh b/build-support/factor.sh index c2775f435a..a02a2fad7e 100755 --- a/build-support/factor.sh +++ b/build-support/factor.sh @@ -406,9 +406,9 @@ backup_factor() { } check_makefile_exists() { - if [[ ! -e "Makefile" ]] ; then + if [[ ! -e "GNUmakefile" ]] ; then echo "" - echo "***Makefile not found***" + echo "***GNUmakefile not found***" echo "You are likely in the wrong directory." echo "Run this script from your factor directory:" echo " ./build-support/factor.sh" diff --git a/vm/alien.cpp b/vm/alien.cpp index 84d31a69c0..48fda5d752 100755 --- a/vm/alien.cpp +++ b/vm/alien.cpp @@ -109,7 +109,7 @@ void *factor_vm::alien_pointer() PRIMITIVE(set_alien_##name) \ { \ type *ptr = (type *)parent->alien_pointer(); \ - type value = to(parent->ctx->pop(),parent); \ + type value = (type)to(parent->ctx->pop(),parent); \ *ptr = value; \ } @@ -151,7 +151,7 @@ void factor_vm::primitive_dlsym() { dll *d = untag_check(library.value()); - if(d->dll == NULL) + if(d->handle == NULL) ctx->push(false_object); else ctx->push(allot_alien(ffi_dlsym(d,sym))); @@ -164,7 +164,7 @@ void factor_vm::primitive_dlsym() void factor_vm::primitive_dlclose() { dll *d = untag_check(ctx->pop()); - if(d->dll != NULL) + if(d->handle != NULL) ffi_dlclose(d); } @@ -172,7 +172,7 @@ void factor_vm::primitive_dll_validp() { cell library = ctx->pop(); if(to_boolean(library)) - ctx->push(tag_boolean(untag_check(library)->dll != NULL)); + ctx->push(tag_boolean(untag_check(library)->handle != NULL)); else ctx->push(true_object); } diff --git a/vm/bitwise_hacks.hpp b/vm/bitwise_hacks.hpp old mode 100644 new mode 100755 index 6cd2a5b694..1927cd4736 --- a/vm/bitwise_hacks.hpp +++ b/vm/bitwise_hacks.hpp @@ -4,8 +4,18 @@ namespace factor inline cell log2(cell x) { cell n; -#if defined(FACTOR_X86) || defined(FACTOR_AMD64) - asm ("bsr %1, %0;":"=r"(n):"r"(x)); +#if defined(FACTOR_X86) + #if defined(_MSC_VER) + _BitScanReverse(&n,x); + #else + asm ("bsr %1, %0;":"=r"(n):"r"(x)); + #endif +#elif defined(FACTOR_AMD64) + #if defined(_MSC_VER) + _BitScanReverse64(&n,x); + #else + asm ("bsr %1, %0;":"=r"(n):"r"(x)); + #endif #elif defined(FACTOR_PPC) asm ("cntlzw %1, %0;":"=r"(n):"r"(x)); n = (31 - n); @@ -22,7 +32,7 @@ inline cell rightmost_clear_bit(cell x) inline cell rightmost_set_bit(cell x) { - return log2(x & -x); + return log2(x & (~x + 1)); } inline cell popcount(cell x) diff --git a/vm/code_blocks.cpp b/vm/code_blocks.cpp index d72d30cc96..aaa4369a1d 100755 --- a/vm/code_blocks.cpp +++ b/vm/code_blocks.cpp @@ -159,7 +159,7 @@ cell factor_vm::compute_dlsym_address(array *literals, cell index) dll *d = (to_boolean(library) ? untag(library) : NULL); - if(d != NULL && !d->dll) + if(d != NULL && !d->handle) return (cell)factor::undefined_symbol; switch(tagged(symbol).type()) diff --git a/vm/compaction.cpp b/vm/compaction.cpp index 7a062998a7..240a725a08 100644 --- a/vm/compaction.cpp +++ b/vm/compaction.cpp @@ -168,7 +168,7 @@ void factor_vm::update_code_roots_for_compaction() for(; iter < end; iter++) { code_root *root = *iter; - code_block *block = (code_block *)(root->value & -data_alignment); + code_block *block = (code_block *)(root->value & (~data_alignment + 1)); /* Offset of return address within 16-byte allocation line */ cell offset = root->value - (cell)block; diff --git a/vm/factor.cpp b/vm/factor.cpp index 453ec71682..d5a1d2f30e 100755 --- a/vm/factor.cpp +++ b/vm/factor.cpp @@ -3,7 +3,6 @@ namespace factor { -factor_vm *vm; std::map thread_vms; void init_globals() @@ -31,11 +30,7 @@ void factor_vm::default_parameters(vm_parameters *p) #ifdef WINDOWS p->console = false; #else - if (this == vm) - p->console = true; - else - p->console = false; - + p->console = true; #endif p->callback_size = 256; @@ -120,7 +115,7 @@ void factor_vm::init_factor(vm_parameters *p) if(p->image_path == NULL) p->image_path = default_image_path(); - srand(system_micros()); + srand((unsigned int)system_micros()); init_ffi(); init_stacks(p->ds_size,p->rs_size); init_callbacks(p->callback_size); @@ -225,7 +220,7 @@ factor_vm *new_factor_vm() } // arg must be new'ed because we're going to delete it! -void* start_standalone_factor_thread(void *arg) +void *start_standalone_factor_thread(void *arg) { factor_vm *newvm = new_factor_vm(); startargs *args = (startargs*) arg; @@ -238,7 +233,6 @@ void* start_standalone_factor_thread(void *arg) VM_C_API void start_standalone_factor(int argc, vm_char **argv) { factor_vm *newvm = new_factor_vm(); - vm = newvm; return newvm->start_standalone_factor(argc,argv); } diff --git a/vm/factor.hpp b/vm/factor.hpp old mode 100644 new mode 100755 index 5f41c952e1..cec59bcc5c --- a/vm/factor.hpp +++ b/vm/factor.hpp @@ -2,7 +2,7 @@ namespace factor { VM_C_API void init_globals(); - VM_C_API void start_standalone_factor(int argc, vm_char **argv); VM_C_API THREADHANDLE start_standalone_factor_in_new_thread(int argc, vm_char **argv); + } diff --git a/vm/free_list.hpp b/vm/free_list.hpp old mode 100644 new mode 100755 index 0a0a5c7614..3fb06babc9 --- a/vm/free_list.hpp +++ b/vm/free_list.hpp @@ -32,7 +32,7 @@ struct free_heap_block }; struct block_size_compare { - bool operator()(free_heap_block *a, free_heap_block *b) + bool operator()(free_heap_block *a, free_heap_block *b) const { return a->size() < b->size(); } diff --git a/vm/gc.cpp b/vm/gc.cpp index 96eab18c47..a57f338c44 100755 --- a/vm/gc.cpp +++ b/vm/gc.cpp @@ -29,7 +29,7 @@ void gc_event::ended_card_scan(cell cards_scanned_, cell decks_scanned_) { cards_scanned += cards_scanned_; decks_scanned += decks_scanned_; - card_scan_time = (nano_count() - temp_time); + card_scan_time = (cell)(nano_count() - temp_time); } void gc_event::started_code_scan() @@ -40,7 +40,7 @@ void gc_event::started_code_scan() void gc_event::ended_code_scan(cell code_blocks_scanned_) { code_blocks_scanned += code_blocks_scanned_; - code_scan_time = (nano_count() - temp_time); + code_scan_time = (cell)(nano_count() - temp_time); } void gc_event::started_data_sweep() @@ -50,7 +50,7 @@ void gc_event::started_data_sweep() void gc_event::ended_data_sweep() { - data_sweep_time = (nano_count() - temp_time); + data_sweep_time = (cell)(nano_count() - temp_time); } void gc_event::started_code_sweep() @@ -60,7 +60,7 @@ void gc_event::started_code_sweep() void gc_event::ended_code_sweep() { - code_sweep_time = (nano_count() - temp_time); + code_sweep_time = (cell)(nano_count() - temp_time); } void gc_event::started_compaction() @@ -70,14 +70,14 @@ void gc_event::started_compaction() void gc_event::ended_compaction() { - compaction_time = (nano_count() - temp_time); + compaction_time = (cell)(nano_count() - temp_time); } void gc_event::ended_gc(factor_vm *parent) { data_heap_after = parent->data_room(); code_heap_after = parent->code_room(); - total_time = nano_count() - start_time; + total_time = (cell)(nano_count() - start_time); } gc_state::gc_state(gc_op op_, factor_vm *parent) : op(op_), start_time(nano_count()) diff --git a/vm/instruction_operands.cpp b/vm/instruction_operands.cpp index 69b82b1435..e022b093c4 100644 --- a/vm/instruction_operands.cpp +++ b/vm/instruction_operands.cpp @@ -122,7 +122,7 @@ void instruction_operand::store_value(fixnum absolute_value) store_value_masked(relative_value - sizeof(cell),rel_indirect_arm_mask,0); break; case RC_ABSOLUTE_2: - *(u16 *)(pointer - sizeof(u16)) = absolute_value; + *(u16 *)(pointer - sizeof(u16)) = (u16)absolute_value; break; default: critical_error("Bad rel class",rel.rel_class()); diff --git a/vm/layouts.hpp b/vm/layouts.hpp index b03a0d2244..2a3eee9214 100644 --- a/vm/layouts.hpp +++ b/vm/layouts.hpp @@ -298,7 +298,7 @@ struct dll : public object { /* tagged byte array holding a C string */ cell path; /* OS-specific handle */ - void *dll; + void *handle; }; struct stack_frame { diff --git a/vm/main-windows-ce.cpp b/vm/main-windows-ce.cpp old mode 100644 new mode 100755 index 526f3b2c36..e0b1d3b626 --- a/vm/main-windows-ce.cpp +++ b/vm/main-windows-ce.cpp @@ -1,134 +1,17 @@ #include "master.hpp" -/* - Windows CE argument parsing ported to work on - int main(int argc, wchar_t **argv). - - This would not be necessary if Windows CE had CommandLineToArgvW. - - Based on MinGW's public domain char** version. - -*/ - -int __argc; -wchar_t **__argv; - -static int -parse_tokens(wchar_t* string, wchar_t*** tokens, int length) -{ - /* Extract whitespace- and quotes- delimited tokens from the given string - and put them into the tokens array. Returns number of tokens - extracted. Length specifies the current size of tokens[]. - THIS METHOD MODIFIES string. */ - - const wchar_t* whitespace = L" \t\r\n"; - wchar_t* tokenEnd = 0; - const wchar_t* quoteCharacters = L"\"\'"; - wchar_t *end = string + wcslen(string); - - if (string == NULL) - return length; - - while (1) - { - const wchar_t* q; - /* Skip over initial whitespace. */ - string += wcsspn(string, whitespace); - if (*string == '\0') - break; - - for (q = quoteCharacters; *q; ++q) - { - if (*string == *q) - break; - } - if (*q) - { - /* Token is quoted. */ - wchar_t quote = *string++; - tokenEnd = wcschr(string, quote); - /* If there is no endquote, the token is the rest of the string. */ - if (!tokenEnd) - tokenEnd = end; - } - else - { - tokenEnd = string + wcscspn(string, whitespace); - } - - *tokenEnd = '\0'; - - { - wchar_t** new_tokens; - int newlen = length + 1; - new_tokens = realloc (*tokens, sizeof (wchar_t**) * newlen); - if (!new_tokens) - { - /* Out of memory. */ - return -1; - } - - *tokens = new_tokens; - (*tokens)[length] = string; - length = newlen; - } - if (tokenEnd == end) - break; - string = tokenEnd + 1; - } - return length; -} - -static void -parse_args(int *argc, wchar_t ***argv, wchar_t *cmdlinePtrW) -{ - wchar_t cmdnameBufW[MAX_UNICODE_PATH]; - int cmdlineLen = 0; - int modlen; - - /* argv[0] is the path of invoked program - get this from CE. */ - cmdnameBufW[0] = 0; - modlen = GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof (cmdnameBufW[0])); - - if (!cmdlinePtrW) - cmdlineLen = 0; - else - cmdlineLen = wcslen(cmdlinePtrW); - - /* gets realloc()'d later */ - *argv = malloc (sizeof (wchar_t**) * 1); - if (!*argv) - ExitProcess(-1); - - (*argv)[0] = wcsdup(cmdnameBufW); - if(!(*argv[0])) - ExitProcess(-1); - /* Add one to account for argv[0] */ - (*argc)++; - - if (cmdlineLen > 0) - { - wchar_t* argv1 = (*argv)[0] + wcslen((*argv)[0]) + 1; - argv1 = wcsdup(cmdlinePtrW); - if(!argv1) - ExitProcess(-1); - *argc = parse_tokens(argv1, argv, 1); - if (*argc < 0) - ExitProcess(-1); - } - (*argv)[*argc] = 0; - return; -} - -int WINAPI -WinMain( +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { - parse_args(&__argc, &__argv, lpCmdLine); + int __argc; + wchar_t **__argv; + factor::parse_args(&__argc, &__argv, lpCmdLine); + factor::init_globals(); factor::start_standalone_factor(__argc,(LPWSTR*)__argv); + // memory leak from malloc, wcsdup return 0; } diff --git a/vm/main-windows-nt.cpp b/vm/main-windows-nt.cpp old mode 100644 new mode 100755 index df4a1172f1..080a64c276 --- a/vm/main-windows-nt.cpp +++ b/vm/main-windows-nt.cpp @@ -1,30 +1,30 @@ #include "master.hpp" +VM_C_API int wmain(int argc, wchar_t **argv) +{ + factor::init_globals(); +#ifdef FACTOR_MULTITHREADED + factor::THREADHANDLE thread = factor::start_standalone_factor_in_new_thread(argv,argc); + WaitForSingleObject(thread, INFINITE); +#else + factor::start_standalone_factor(argc,argv); +#endif + return 0; +} + int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - LPWSTR *szArglist; - int nArgs; - - szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); - if(NULL == szArglist) - { - puts("CommandLineToArgvW failed"); - return 1; - } + int argc; + wchar_t **argv; - factor::init_globals(); - #ifdef FACTOR_MULTITHREADED - factor::THREADHANDLE thread = factor::start_standalone_factor_in_new_thread(nArgs,szArglist); - WaitForSingleObject(thread, INFINITE); - #else - factor::start_standalone_factor(nArgs,szArglist); - #endif + factor::parse_args(&argc, &argv, (wchar_t *)GetCommandLine()); - LocalFree(szArglist); + wmain(argc,argv); + // memory leak from malloc, wcsdup return 0; } diff --git a/vm/master.hpp b/vm/master.hpp index 9a920efce7..f4c0934478 100755 --- a/vm/master.hpp +++ b/vm/master.hpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -36,7 +35,7 @@ #elif defined(__amd64__) || defined(__x86_64__) #define FACTOR_AMD64 #define FACTOR_64 -#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(WIN32) +#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(WIN32) || defined(_MSC_VER) #define FACTOR_X86 #elif defined(__POWERPC__) || defined(__ppc__) || defined(_ARCH_PPC) #define FACTOR_PPC @@ -44,8 +43,15 @@ #error "Unsupported architecture" #endif -#ifdef WIN32 +#if defined(_MSC_VER) #define WINDOWS + #define WINNT +#elif defined(WIN32) + #define WINDOWS +#endif + +#ifndef _MSC_VER + #include #endif /* Forward-declare this since it comes up in function prototypes */ diff --git a/vm/math.cpp b/vm/math.cpp index f2056ee32e..a2c69c31f2 100755 --- a/vm/math.cpp +++ b/vm/math.cpp @@ -277,7 +277,7 @@ void factor_vm::primitive_str_to_float() void factor_vm::primitive_float_to_str() { byte_array *array = allot_byte_array(33); - snprintf((char *)(array + 1),32,"%.16g",untag_float_check(ctx->pop())); + SNPRINTF((char *)(array + 1),32,"%.16g",untag_float_check(ctx->pop())); ctx->push(tag(array)); } @@ -347,7 +347,7 @@ void factor_vm::primitive_float_greatereq() void factor_vm::primitive_float_bits() { - ctx->push(from_unsigned_4(float_bits(untag_float_check(ctx->pop())))); + ctx->push(from_unsigned_4(float_bits((float)untag_float_check(ctx->pop())))); } void factor_vm::primitive_bits_float() @@ -480,7 +480,7 @@ cell factor_vm::from_signed_8(s64 n) if(n < fixnum_min || n > fixnum_max) return tag(long_long_to_bignum(n)); else - return tag_fixnum(n); + return tag_fixnum((fixnum)n); } VM_C_API cell from_signed_8(s64 n, factor_vm *parent) @@ -513,7 +513,7 @@ cell factor_vm::from_unsigned_8(u64 n) if(n > (u64)fixnum_max) return tag(ulong_long_to_bignum(n)); else - return tag_fixnum(n); + return tag_fixnum((fixnum)n); } VM_C_API cell from_unsigned_8(u64 n, factor_vm *parent) @@ -549,7 +549,7 @@ VM_C_API cell from_float(float flo, factor_vm *parent) /* Cannot allocate */ float factor_vm::to_float(cell value) { - return untag_float_check(value); + return (float)untag_float_check(value); } VM_C_API float to_float(cell value, factor_vm *parent) diff --git a/vm/object_start_map.cpp b/vm/object_start_map.cpp index 105f934f99..6b5b5139b9 100644 --- a/vm/object_start_map.cpp +++ b/vm/object_start_map.cpp @@ -70,7 +70,7 @@ void object_start_map::update_card_for_sweep(cell index, u16 mask) else { /* Move the object start forward if necessary */ - object_start_offsets[index] = offset + (rightmost_set_bit(mask) * data_alignment); + object_start_offsets[index] = (card)(offset + (rightmost_set_bit(mask) * data_alignment)); } } } diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index 8276d3ee5c..4b5040ab8b 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -73,20 +73,20 @@ void factor_vm::init_ffi() void factor_vm::ffi_dlopen(dll *dll) { - dll->dll = dlopen(alien_offset(dll->path), RTLD_LAZY); + dll->handle = dlopen(alien_offset(dll->path), RTLD_LAZY); } void *factor_vm::ffi_dlsym(dll *dll, symbol_char *symbol) { - void *handle = (dll == NULL ? null_dll : dll->dll); + void *handle = (dll == NULL ? null_dll : dll->handle); return dlsym(handle,symbol); } void factor_vm::ffi_dlclose(dll *dll) { - if(dlclose(dll->dll)) + if(dlclose(dll->handle)) general_error(ERROR_FFI,false_object,false_object,NULL); - dll->dll = NULL; + dll->handle = NULL; } void factor_vm::primitive_existsp() diff --git a/vm/os-unix.hpp b/vm/os-unix.hpp index bb784bc93c..7faab4d8b8 100644 --- a/vm/os-unix.hpp +++ b/vm/os-unix.hpp @@ -22,6 +22,7 @@ typedef char symbol_char; #define STRCMP strcmp #define STRNCMP strncmp #define STRDUP strdup +#define SNPRINTF snprintf #define FTELL ftello #define FSEEK fseeko diff --git a/vm/os-windows-ce.hpp b/vm/os-windows-ce.hpp old mode 100644 new mode 100755 index 48da3fa551..02de1cd4a8 --- a/vm/os-windows-ce.hpp +++ b/vm/os-windows-ce.hpp @@ -12,7 +12,6 @@ typedef wchar_t symbol_char; #define FACTOR_OS_STRING "wince" #define FACTOR_DLL L"factor-ce.dll" -#define FACTOR_DLL_NAME "factor-ce.dll" int errno; char *strerror(int err); diff --git a/vm/os-windows-nt.cpp b/vm/os-windows-nt.cpp index cab30b121e..2fceb130f4 100755 --- a/vm/os-windows-nt.cpp +++ b/vm/os-windows-nt.cpp @@ -112,7 +112,7 @@ LONG factor_vm::exception_handler(PEXCEPTION_POINTERS pe) return EXCEPTION_CONTINUE_EXECUTION; } -FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe) +FACTOR_STDCALL(LONG) exception_handler(PEXCEPTION_POINTERS pe) { return tls_vm()->exception_handler(pe); } diff --git a/vm/os-windows-nt.hpp b/vm/os-windows-nt.hpp index f8407aeee5..1559d1147d 100755 --- a/vm/os-windows-nt.hpp +++ b/vm/os-windows-nt.hpp @@ -8,18 +8,27 @@ #include #include +#ifdef _MSC_VER + #undef min + #undef max +#endif + namespace factor { typedef char symbol_char; #define FACTOR_OS_STRING "winnt" -#define FACTOR_DLL L"factor.dll" -#define FACTOR_DLL_NAME "factor.dll" -#define FACTOR_STDCALL __attribute__((stdcall)) +#ifdef _MSC_VER + #define FACTOR_DLL NULL + #define FACTOR_STDCALL(return_type) return_type __stdcall +#else + #define FACTOR_DLL L"factor.dll" + #define FACTOR_STDCALL(return_type) __attribute__((stdcall)) return_type +#endif -FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe); +FACTOR_STDCALL(LONG) exception_handler(PEXCEPTION_POINTERS pe); // SSE traps raise these exception codes, which are defined in internal NT headers // but not winbase.h diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index 5ca666d828..e7353c6517 100755 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -9,26 +9,26 @@ void factor_vm::init_ffi() { hFactorDll = GetModuleHandle(FACTOR_DLL); if(!hFactorDll) - fatal_error("GetModuleHandle(\"" FACTOR_DLL_NAME "\") failed", 0); + fatal_error("GetModuleHandle() failed", 0); } void factor_vm::ffi_dlopen(dll *dll) { - dll->dll = LoadLibraryEx((WCHAR *)alien_offset(dll->path), NULL, 0); + dll->handle = LoadLibraryEx((WCHAR *)alien_offset(dll->path), NULL, 0); } void *factor_vm::ffi_dlsym(dll *dll, symbol_char *symbol) { - return (void *)GetProcAddress(dll ? (HMODULE)dll->dll : hFactorDll, symbol); + return (void *)GetProcAddress(dll ? (HMODULE)dll->handle : hFactorDll, symbol); } void factor_vm::ffi_dlclose(dll *dll) { - FreeLibrary((HMODULE)dll->dll); - dll->dll = NULL; + FreeLibrary((HMODULE)dll->handle); + dll->handle = NULL; } -bool factor_vm::windows_stat(vm_char *path) +BOOL factor_vm::windows_stat(vm_char *path) { BY_HANDLE_FILE_INFORMATION bhfi; HANDLE h = CreateFileW(path, @@ -50,15 +50,14 @@ bool factor_vm::windows_stat(vm_char *path) FindClose(h); return true; } - bool ret; - ret = GetFileInformationByHandle(h, &bhfi); + BOOL ret = GetFileInformationByHandle(h, &bhfi); CloseHandle(h); return ret; } void factor_vm::windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length) { - snwprintf(temp_path, length-1, L"%s.image", full_path); + SNWPRINTF(temp_path, length-1, L"%s.image", full_path); temp_path[length - 1] = 0; } @@ -75,7 +74,7 @@ const vm_char *factor_vm::default_image_path() if((ptr = wcsrchr(full_path, '.'))) *ptr = 0; - snwprintf(temp_path, MAX_UNICODE_PATH-1, L"%s.image", full_path); + SNWPRINTF(temp_path, MAX_UNICODE_PATH-1, L"%s.image", full_path); temp_path[MAX_UNICODE_PATH - 1] = 0; return safe_strdup(temp_path); @@ -138,4 +137,120 @@ long getpagesize() return g_pagesize; } +/* + Windows argument parsing ported to work on + int main(int argc, wchar_t **argv). + + Based on MinGW's public domain char** version. + + Used by WinMain() implementation in main-windows-ce.cpp + and main-windows-nt.cpp. + +*/ + +VM_C_API int parse_tokens(wchar_t *string, wchar_t ***tokens, int length) +{ + /* Extract whitespace- and quotes- delimited tokens from the given string + and put them into the tokens array. Returns number of tokens + extracted. Length specifies the current size of tokens[]. + THIS METHOD MODIFIES string. */ + + const wchar_t *whitespace = L" \t\r\n"; + wchar_t *tokenEnd = 0; + const wchar_t *quoteCharacters = L"\"\'"; + wchar_t *end = string + wcslen(string); + + if (string == NULL) + return length; + + while (1) + { + const wchar_t *q; + /* Skip over initial whitespace. */ + string += wcsspn(string, whitespace); + if (*string == '\0') + break; + + for (q = quoteCharacters; *q; ++q) + { + if (*string == *q) + break; + } + if (*q) + { + /* Token is quoted. */ + wchar_t quote = *string++; + tokenEnd = wcschr(string, quote); + /* If there is no endquote, the token is the rest of the string. */ + if (!tokenEnd) + tokenEnd = end; + } + else + { + tokenEnd = string + wcscspn(string, whitespace); + } + + *tokenEnd = '\0'; + + { + wchar_t **new_tokens; + int newlen = length + 1; + new_tokens = (wchar_t **)realloc (*tokens, sizeof (wchar_t**) * newlen); + if (!new_tokens) + { + /* Out of memory. */ + return -1; + } + + *tokens = new_tokens; + (*tokens)[length] = string; + length = newlen; + } + if (tokenEnd == end) + break; + string = tokenEnd + 1; + } + return length; +} + +VM_C_API void parse_args(int *argc, wchar_t ***argv, wchar_t *cmdlinePtrW) +{ + wchar_t cmdnameBufW[MAX_UNICODE_PATH]; + int cmdlineLen = 0; + int modlen; + + /* argv[0] is the path of invoked program - get this from CE. */ + cmdnameBufW[0] = 0; + modlen = GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof (cmdnameBufW[0])); + + if (!cmdlinePtrW) + cmdlineLen = 0; + else + cmdlineLen = wcslen(cmdlinePtrW); + + /* gets realloc()'d later */ + *argv = (wchar_t **)malloc (sizeof (wchar_t**) * 1); + if (!*argv) + ExitProcess(1); + + (*argv)[0] = wcsdup(cmdnameBufW); + if(!(*argv[0])) + ExitProcess(1); + /* Add one to account for argv[0] */ + (*argc)++; + + if (cmdlineLen > 0) + { + wchar_t *argv1 = (*argv)[0] + wcslen((*argv)[0]) + 1; + argv1 = wcsdup(cmdlinePtrW); + if(!argv1) + ExitProcess(1); + *argc = parse_tokens(argv1, argv, 1); + if (*argc < 0) + ExitProcess(1); + } + (*argv)[*argc] = 0; + return; +} + } diff --git a/vm/os-windows.hpp b/vm/os-windows.hpp old mode 100644 new mode 100755 index 6a280ea580..13db2035bc --- a/vm/os-windows.hpp +++ b/vm/os-windows.hpp @@ -1,8 +1,8 @@ #include #ifndef wcslen - /* for cygwin */ - #include + /* for cygwin */ + #include #endif namespace factor @@ -18,8 +18,18 @@ typedef wchar_t vm_char; #define STRCMP wcscmp #define STRNCMP wcsncmp #define STRDUP _wcsdup -#define FTELL ftello64 -#define FSEEK fseeko64 + +#ifdef _MSC_VER + #define FTELL ftell + #define FSEEK fseek + #define SNPRINTF _snprintf + #define SNWPRINTF _snwprintf +#else + #define FTELL ftello64 + #define FSEEK fseeko64 + #define SNPRINTF snprintf + #define SNWPRINTF snwprintf +#endif #ifdef WIN64 #define CELL_HEX_FORMAT "%Ix" @@ -41,4 +51,8 @@ u64 nano_count(); void sleep_nanos(u64 nsec); long getpagesize(); +/* Used by-main-windows-*.cpp */ +VM_C_API int parse_tokens(wchar_t* string, wchar_t*** tokens, int length); +VM_C_API void parse_args(int *argc, wchar_t ***argv, wchar_t *cmdlinePtrW); + } diff --git a/vm/platform.hpp b/vm/platform.hpp old mode 100644 new mode 100755 index 96e19ad7f4..2a38c91171 --- a/vm/platform.hpp +++ b/vm/platform.hpp @@ -1,16 +1,20 @@ #if defined(WINDOWS) #if defined(WINCE) #include "os-windows-ce.hpp" - #else + #include "os-windows.hpp" + #elif defined(WINNT) #include "os-windows-nt.hpp" - #endif - - #include "os-windows.hpp" + #include "os-windows.hpp" - #if defined(FACTOR_AMD64) - #include "os-windows-nt.64.hpp" - #elif defined(FACTOR_X86) - #include "os-windows-nt.32.hpp" + #if defined(FACTOR_AMD64) + #include "os-windows-nt.64.hpp" + #elif defined(FACTOR_X86) + #include "os-windows-nt.32.hpp" + #else + #error "Unsupported Windows flavor" + #endif + #else + #error "Unsupported Windows flavor" #endif #else #include "os-unix.hpp" diff --git a/vm/strings.cpp b/vm/strings.cpp index c7e0354cba..67e4fb4508 100644 --- a/vm/strings.cpp +++ b/vm/strings.cpp @@ -24,7 +24,7 @@ cell string::nth(cell index) const void factor_vm::set_string_nth_fast(string *str, cell index, cell ch) { - str->data()[index] = ch; + str->data()[index] = (u8)ch; } void factor_vm::set_string_nth_slow(string *str_, cell index, cell ch) @@ -51,7 +51,7 @@ void factor_vm::set_string_nth_slow(string *str_, cell index, cell ch) write_barrier(&str->aux); } - aux->data()[index] = ((ch >> 7) ^ 1); + aux->data()[index] = (u16)((ch >> 7) ^ 1); } /* allocates memory */ diff --git a/vm/vm.hpp b/vm/vm.hpp index 92e921000b..348a7128cc 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -267,8 +267,8 @@ struct factor_vm inline void write_barrier(object *obj, cell size) { - cell start = (cell)obj & -card_size; - cell end = ((cell)obj + size + card_size - 1) & -card_size; + cell start = (cell)obj & (~card_size + 1); + cell end = ((cell)obj + size + card_size - 1) & (~card_size + 1); for(cell offset = start; offset < end; offset += card_size) write_barrier((cell *)offset); @@ -671,7 +671,7 @@ struct factor_vm const vm_char *vm_executable_path(); const vm_char *default_image_path(); void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length); - bool windows_stat(vm_char *path); + BOOL windows_stat(vm_char *path); #if defined(WINNT) void open_console(); -- 2.34.1