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.

db4
Slava Pestov 2010-01-17 03:43:22 +13:00
parent 9bc328b50d
commit e4da687413
29 changed files with 318 additions and 217 deletions

65
Nmakefile Executable file
View File

@ -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

View File

@ -3,6 +3,7 @@ temp
logs
.git
.gitignore
Makefile
GNUmakefile
Nmakefile
unmaintained
build-support

View File

@ -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"

View File

@ -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<dll>(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<dll>(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<dll>(library)->dll != NULL));
ctx->push(tag_boolean(untag_check<dll>(library)->handle != NULL));
else
ctx->push(true_object);
}

14
vm/bitwise_hacks.hpp Normal file → Executable file
View File

@ -4,8 +4,18 @@ namespace factor
inline cell log2(cell x)
{
cell n;
#if defined(FACTOR_X86) || defined(FACTOR_AMD64)
#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)

View File

@ -159,7 +159,7 @@ cell factor_vm::compute_dlsym_address(array *literals, cell index)
dll *d = (to_boolean(library) ? untag<dll>(library) : NULL);
if(d != NULL && !d->dll)
if(d != NULL && !d->handle)
return (cell)factor::undefined_symbol;
switch(tagged<object>(symbol).type())

View File

@ -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;

View File

@ -3,7 +3,6 @@
namespace factor
{
factor_vm *vm;
std::map<THREADHANDLE, factor_vm*> 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;
#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);
@ -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);
}

2
vm/factor.hpp Normal file → Executable file
View File

@ -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);
}

2
vm/free_list.hpp Normal file → Executable file
View File

@ -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();
}

View File

@ -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())

View File

@ -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());

View File

@ -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 {

129
vm/main-windows-ce.cpp Normal file → Executable file
View File

@ -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;
}

34
vm/main-windows-nt.cpp Normal file → Executable file
View File

@ -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;
int argc;
wchar_t **argv;
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if(NULL == szArglist)
{
puts("CommandLineToArgvW failed");
return 1;
}
factor::parse_args(&argc, &argv, (wchar_t *)GetCommandLine());
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
LocalFree(szArglist);
wmain(argc,argv);
// memory leak from malloc, wcsdup
return 0;
}

View File

@ -16,7 +16,6 @@
#include <fcntl.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
@ -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 <stdbool.h>
#endif
/* Forward-declare this since it comes up in function prototypes */

View File

@ -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<byte_array>(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<bignum>(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<bignum>(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)

View File

@ -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));
}
}
}

View File

@ -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()

View File

@ -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

1
vm/os-windows-ce.hpp Normal file → Executable file
View File

@ -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);

View File

@ -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);
}

View File

@ -8,18 +8,27 @@
#include <windows.h>
#include <shellapi.h>
#ifdef _MSC_VER
#undef min
#undef max
#endif
namespace factor
{
typedef char symbol_char;
#define FACTOR_OS_STRING "winnt"
#ifdef _MSC_VER
#define FACTOR_DLL NULL
#define FACTOR_STDCALL(return_type) return_type __stdcall
#else
#define FACTOR_DLL L"factor.dll"
#define FACTOR_DLL_NAME "factor.dll"
#define FACTOR_STDCALL(return_type) __attribute__((stdcall)) return_type
#endif
#define FACTOR_STDCALL __attribute__((stdcall))
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

View File

@ -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;
}
}

14
vm/os-windows.hpp Normal file → Executable file
View File

@ -18,8 +18,18 @@ typedef wchar_t vm_char;
#define STRCMP wcscmp
#define STRNCMP wcsncmp
#define STRDUP _wcsdup
#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);
}

10
vm/platform.hpp Normal file → Executable file
View File

@ -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"
#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"

View File

@ -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<u16>()[index] = ((ch >> 7) ^ 1);
aux->data<u16>()[index] = (u16)((ch >> 7) ^ 1);
}
/* allocates memory */

View File

@ -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();