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.
parent
9bc328b50d
commit
e4da687413
|
@ -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
|
|
@ -3,6 +3,7 @@ temp
|
|||
logs
|
||||
.git
|
||||
.gitignore
|
||||
Makefile
|
||||
GNUmakefile
|
||||
Nmakefile
|
||||
unmaintained
|
||||
build-support
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
12
vm/gc.cpp
12
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())
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
10
vm/math.cpp
10
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<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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue