Port FFI to win32
parent
2f8d25d9e6
commit
d9afca04f8
3
Makefile
3
Makefile
|
|
@ -22,7 +22,8 @@ OBJS = native/arithmetic.o native/array.o native/bignum.o \
|
||||||
native/unix/socket.o \
|
native/unix/socket.o \
|
||||||
native/unix/signal.o \
|
native/unix/signal.o \
|
||||||
native/unix/read.o \
|
native/unix/read.o \
|
||||||
native/unix/write.o
|
native/unix/write.o \
|
||||||
|
native/unix/ffi.o
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@echo "Run 'make' with one of the following parameters:"
|
@echo "Run 'make' with one of the following parameters:"
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="FFI;WIN32"
|
||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
GlobalOptimizations="TRUE"
|
GlobalOptimizations="TRUE"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
OmitFramePointers="TRUE"
|
OmitFramePointers="TRUE"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="FFI;WIN32"
|
||||||
StringPooling="TRUE"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="4"
|
RuntimeLibrary="4"
|
||||||
EnableFunctionLevelLinking="TRUE"
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
|
@ -204,6 +204,21 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="win32"
|
Name="win32"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath=".\native\win32\ffi.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
ObjectFile="$(IntDir)/$(InputName)2.obj"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
ObjectFile="$(IntDir)/$(InputName)2.obj"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="native\win32\file.c">
|
RelativePath="native\win32\file.c">
|
||||||
</File>
|
</File>
|
||||||
|
|
@ -235,6 +250,23 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="unix"
|
Name="unix"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath=".\native\unix\ffi.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="native\unix\file.c">
|
RelativePath="native\unix\file.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ INLINE F_ARRAY* untag_bignum(CELL tagged)
|
||||||
F_FIXNUM to_integer(CELL x);
|
F_FIXNUM to_integer(CELL x);
|
||||||
void box_integer(F_FIXNUM integer);
|
void box_integer(F_FIXNUM integer);
|
||||||
void box_cell(CELL cell);
|
void box_cell(CELL cell);
|
||||||
F_FIXNUM unbox_integer(void);
|
DLLEXPORT F_FIXNUM unbox_integer(void);
|
||||||
CELL unbox_cell(void);
|
CELL unbox_cell(void);
|
||||||
F_ARRAY* to_bignum(CELL tagged);
|
F_ARRAY* to_bignum(CELL tagged);
|
||||||
void primitive_to_bignum(void);
|
void primitive_to_bignum(void);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ CELL cs;
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FFI
|
#if defined(FFI) && !defined(WIN32)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif /* FFI */
|
#endif /* FFI */
|
||||||
|
|
||||||
|
|
@ -122,9 +122,9 @@ typedef unsigned char BYTE;
|
||||||
#include "float.h"
|
#include "float.h"
|
||||||
#include "complex.h"
|
#include "complex.h"
|
||||||
#include "arithmetic.h"
|
#include "arithmetic.h"
|
||||||
|
#include "string.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "relocate.h"
|
#include "relocate.h"
|
||||||
#include "string.h"
|
|
||||||
#include "sbuf.h"
|
#include "sbuf.h"
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
|
||||||
80
native/ffi.c
80
native/ffi.c
|
|
@ -9,86 +9,6 @@ DLL* untag_dll(CELL tagged)
|
||||||
return (DLL*)UNTAG(tagged);
|
return (DLL*)UNTAG(tagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void primitive_dlopen(void)
|
|
||||||
{
|
|
||||||
#ifdef FFI
|
|
||||||
char* path;
|
|
||||||
void* dllptr;
|
|
||||||
DLL* dll;
|
|
||||||
|
|
||||||
maybe_garbage_collection();
|
|
||||||
|
|
||||||
path = unbox_c_string();
|
|
||||||
dllptr = dlopen(path,RTLD_LAZY);
|
|
||||||
|
|
||||||
if(dllptr == NULL)
|
|
||||||
{
|
|
||||||
general_error(ERROR_FFI,tag_object(
|
|
||||||
from_c_string(dlerror())));
|
|
||||||
}
|
|
||||||
|
|
||||||
dll = allot_object(DLL_TYPE,sizeof(DLL));
|
|
||||||
dll->dll = dllptr;
|
|
||||||
dpush(tag_object(dll));
|
|
||||||
#else
|
|
||||||
general_error(ERROR_FFI_DISABLED,F);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void primitive_dlsym(void)
|
|
||||||
{
|
|
||||||
#ifdef FFI
|
|
||||||
DLL* dll = untag_dll(dpop());
|
|
||||||
void* sym = dlsym(dll->dll,unbox_c_string());
|
|
||||||
if(sym == NULL)
|
|
||||||
{
|
|
||||||
general_error(ERROR_FFI,tag_object(
|
|
||||||
from_c_string(dlerror())));
|
|
||||||
}
|
|
||||||
dpush(tag_cell((CELL)sym));
|
|
||||||
#else
|
|
||||||
general_error(ERROR_FFI_DISABLED,F);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void primitive_dlsym_self(void)
|
|
||||||
{
|
|
||||||
#if defined(FFI)
|
|
||||||
void* sym = dlsym(NULL,unbox_c_string());
|
|
||||||
if(sym == NULL)
|
|
||||||
{
|
|
||||||
general_error(ERROR_FFI,tag_object(
|
|
||||||
from_c_string(dlerror())));
|
|
||||||
}
|
|
||||||
dpush(tag_cell((CELL)sym));
|
|
||||||
#elif defined(WIN32)
|
|
||||||
void *sym = GetProcAddress(GetModuleHandle(NULL), unbox_c_string());
|
|
||||||
if(sym == NULL)
|
|
||||||
{
|
|
||||||
general_error(ERROR_FFI, tag_object(
|
|
||||||
from_c_string("bad symbol")));
|
|
||||||
}
|
|
||||||
dpush(tag_cell((CELL)sym));
|
|
||||||
#else
|
|
||||||
general_error(ERROR_FFI_DISABLED,F);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void primitive_dlclose(void)
|
|
||||||
{
|
|
||||||
#ifdef FFI
|
|
||||||
DLL* dll = untag_dll(dpop());
|
|
||||||
if(dlclose(dll->dll) == -1)
|
|
||||||
{
|
|
||||||
general_error(ERROR_FFI,tag_object(
|
|
||||||
from_c_string(dlerror())));
|
|
||||||
}
|
|
||||||
dll->dll = NULL;
|
|
||||||
#else
|
|
||||||
general_error(ERROR_FFI_DISABLED,F);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FFI
|
#ifdef FFI
|
||||||
CELL unbox_alien(void)
|
CELL unbox_alien(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -57,3 +57,26 @@ void primitive_random_int(void)
|
||||||
maybe_garbage_collection();
|
maybe_garbage_collection();
|
||||||
dpush(tag_object(s48_long_to_bignum(rand())));
|
dpush(tag_object(s48_long_to_bignum(rand())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
F_STRING *last_error()
|
||||||
|
{
|
||||||
|
char *buffer;
|
||||||
|
F_STRING *error;
|
||||||
|
DWORD dw = GetLastError();
|
||||||
|
|
||||||
|
FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
|
NULL,
|
||||||
|
dw,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPTSTR) &buffer,
|
||||||
|
0, NULL);
|
||||||
|
|
||||||
|
error = from_c_string(buffer);
|
||||||
|
LocalFree(buffer);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,7 @@ int64_t current_millis(void);
|
||||||
void primitive_millis(void);
|
void primitive_millis(void);
|
||||||
void primitive_init_random(void);
|
void primitive_init_random(void);
|
||||||
void primitive_random_int(void);
|
void primitive_random_int(void);
|
||||||
|
#ifdef WIN32
|
||||||
|
F_STRING *last_error();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,24 +67,9 @@ void collect_port(F_PORT* port)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
CELL make_io_error(const char* func)
|
CELL make_io_error(const char* func)
|
||||||
{
|
{
|
||||||
char *buffer;
|
|
||||||
F_STRING *function = from_c_string(func);
|
F_STRING *function = from_c_string(func);
|
||||||
F_STRING *error;
|
|
||||||
DWORD dw = GetLastError();
|
|
||||||
|
|
||||||
FormatMessage(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
|
||||||
NULL,
|
|
||||||
dw,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
(LPTSTR) &buffer,
|
|
||||||
0, NULL);
|
|
||||||
|
|
||||||
error = from_c_string(buffer);
|
return cons(tag_object(function),cons(tag_object(last_error()),F));
|
||||||
LocalFree(buffer);
|
|
||||||
|
|
||||||
return cons(tag_object(function),cons(tag_object(error),F));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
CELL make_io_error(const char* func)
|
CELL make_io_error(const char* func)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "../factor.h"
|
||||||
|
|
||||||
|
void primitive_dlopen(void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
char* path;
|
||||||
|
void* dllptr;
|
||||||
|
DLL* dll;
|
||||||
|
|
||||||
|
maybe_garbage_collection();
|
||||||
|
|
||||||
|
path = unbox_c_string();
|
||||||
|
dllptr = dlopen(path,RTLD_LAZY);
|
||||||
|
|
||||||
|
if(dllptr == NULL)
|
||||||
|
{
|
||||||
|
general_error(ERROR_FFI,tag_object(
|
||||||
|
from_c_string(dlerror())));
|
||||||
|
}
|
||||||
|
|
||||||
|
dll = allot_object(DLL_TYPE,sizeof(DLL));
|
||||||
|
dll->dll = dllptr;
|
||||||
|
dpush(tag_object(dll));
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED,F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void primitive_dlsym(void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
DLL* dll = untag_dll(dpop());
|
||||||
|
void* sym = dlsym(dll->dll,unbox_c_string());
|
||||||
|
if(sym == NULL)
|
||||||
|
{
|
||||||
|
general_error(ERROR_FFI,tag_object(
|
||||||
|
from_c_string(dlerror())));
|
||||||
|
}
|
||||||
|
dpush(tag_cell((CELL)sym));
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED,F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void primitive_dlsym_self(void)
|
||||||
|
{
|
||||||
|
#if defined(FFI)
|
||||||
|
void* sym = dlsym(NULL,unbox_c_string());
|
||||||
|
if(sym == NULL)
|
||||||
|
{
|
||||||
|
general_error(ERROR_FFI,tag_object(
|
||||||
|
from_c_string(dlerror())));
|
||||||
|
}
|
||||||
|
dpush(tag_cell((CELL)sym));
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED,F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void primitive_dlclose(void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
DLL* dll = untag_dll(dpop());
|
||||||
|
if(dlclose(dll->dll) == -1)
|
||||||
|
{
|
||||||
|
general_error(ERROR_FFI,tag_object(
|
||||||
|
from_c_string(dlerror())));
|
||||||
|
}
|
||||||
|
dll->dll = NULL;
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED,F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "../factor.h"
|
||||||
|
|
||||||
|
void primitive_dlopen (void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
char *path;
|
||||||
|
HMODULE module;
|
||||||
|
DLL *dll;
|
||||||
|
|
||||||
|
maybe_garbage_collection();
|
||||||
|
|
||||||
|
path = unbox_c_string();
|
||||||
|
module = LoadLibrary(path);
|
||||||
|
|
||||||
|
if (!module)
|
||||||
|
general_error(ERROR_FFI, tag_object(last_error()));
|
||||||
|
|
||||||
|
dll = allot_object(DLL_TYPE, sizeof(DLL));
|
||||||
|
dll->dll = module;
|
||||||
|
dpush(tag_object(dll));
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED, F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void primitive_dlsym (void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
DLL *dll = untag_dll(dpop());
|
||||||
|
void *sym = GetProcAddress((HMODULE)dll->dll, unbox_c_string());
|
||||||
|
|
||||||
|
|
||||||
|
if (!sym)
|
||||||
|
general_error(ERROR_FFI, tag_object(last_error()));
|
||||||
|
|
||||||
|
dpush(tag_cell((CELL)sym));
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED, F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void primitive_dlclose (void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
DLL *dll = untag_dll(dpop());
|
||||||
|
FreeLibrary((HMODULE)dll->dll);
|
||||||
|
dll->dll = NULL;
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED, F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void primitive_dlsym_self (void)
|
||||||
|
{
|
||||||
|
#ifdef FFI
|
||||||
|
void *sym = GetProcAddress(GetModuleHandle(NULL), unbox_c_string());
|
||||||
|
|
||||||
|
if(sym == NULL)
|
||||||
|
{
|
||||||
|
general_error(ERROR_FFI, tag_object(last_error()));
|
||||||
|
}
|
||||||
|
dpush(tag_cell((CELL)sym));
|
||||||
|
#else
|
||||||
|
general_error(ERROR_FFI_DISABLED, F);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ void primitive_add_copy_io_task (void)
|
||||||
void primitive_close (void)
|
void primitive_close (void)
|
||||||
{
|
{
|
||||||
F_PORT *port = untag_port(dpop());
|
F_PORT *port = untag_port(dpop());
|
||||||
|
|
||||||
CloseHandle((HANDLE)port->fd);
|
CloseHandle((HANDLE)port->fd);
|
||||||
port->closed = true;
|
port->closed = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue