[Server] Add CallFF dependency

0.6.1
Koncord 8 years ago
parent 9506f9ca35
commit 1c09e0c255

@ -1,5 +1,10 @@
project(tes3mp-server) project(tes3mp-server)
if(UNIX) #temporarly disabled for non-unix
find_package(CallFF REQUIRED)
include_directories(${CallFF_INCLUDES})
endif(UNIX)
option(BUILD_WITH_PAWN "Enable Pawn language" OFF) option(BUILD_WITH_PAWN "Enable Pawn language" OFF)
option(ENABLE_BREAKPAD "Enable Google Breakpad for Crash reporting" OFF) option(ENABLE_BREAKPAD "Enable Google Breakpad for Crash reporting" OFF)
@ -99,6 +104,7 @@ set(SERVER_HEADER
${PawnScript_Headers} ${PawnScript_Headers}
${LuaScript_Headers} ${LuaScript_Headers}
${NativeScript_Headers} ${NativeScript_Headers}
${CallFF_INCLUDES}
) )
source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER}) source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER})
@ -168,6 +174,7 @@ target_link_libraries(tes3mp-server
${LUA_LIBRARIES} ${LUA_LIBRARIES}
${Pawn_LIBRARY} ${Pawn_LIBRARY}
${Breakpad_Library} ${Breakpad_Library}
${CallFF_LIBRARY}
) )
if (UNIX) if (UNIX)

@ -6,6 +6,10 @@
#include <stdexcept> #include <stdexcept>
#include "ScriptFunction.hpp" #include "ScriptFunction.hpp"
#ifndef _WIN32 // temporally disabled
#include <call.hpp>
#endif
#if defined (ENABLE_LUA) #if defined (ENABLE_LUA)
#include "LangLua/LangLua.hpp" #include "LangLua/LangLua.hpp"
#endif #endif
@ -120,105 +124,42 @@ boost::any ScriptFunction::Call(const vector<boost::any> &args)
#endif #endif
else else
{ {
throw runtime_error("Native Call: native calls does not supported yet");
#if 0
#ifdef ARCH_X86
// cdecl convention
string::iterator it; string::iterator it;
vector<boost::any>::const_iterator it2; vector<boost::any>::const_iterator it2;
vector<unsigned int> data; vector<intptr_t> data;
CallArgs callArgs;
for (it = def.begin(), it2 = args.begin(); it != def.end(); ++it, ++it2) for (it = def.begin(), it2 = args.begin(); it != def.end(); ++it, ++it2)
{ {
switch (*it) switch (*it)
{ {
case 'i': case 'i':
{ callArgs.push_integer(boost::any_cast<unsigned int>(*it2));
unsigned int value = boost::any_cast<unsigned int>(*it2);
data.push_back(value);
break; break;
}
case 'q': case 'q':
{ callArgs.push_integer(boost::any_cast<signed int>(*it2));
unsigned int value = boost::any_cast<signed int>(*it2);
data.push_back(value);
break;
}
case 'l':
{
unsigned long long value = boost::any_cast<unsigned long long>(*it2);
data.push_back(*reinterpret_cast<unsigned int *>(&value));
data.push_back(*reinterpret_cast<unsigned int *>((unsigned) &value + 4));
break;
}
case 'w':
{
signed long long value = boost::any_cast<signed long long>(*it2);
data.push_back(*reinterpret_cast<unsigned int *>(&value));
data.push_back(*reinterpret_cast<unsigned int *>((unsigned) &value + 4));
break; break;
}
case 'f': case 'f':
{ callArgs.push_double(boost::any_cast<double>(*it2));
double value = boost::any_cast<double>(*it2);
data.push_back(*reinterpret_cast<unsigned int *>(&value));
data.push_back(*reinterpret_cast<unsigned int *>((unsigned) &value + 4));
break; break;
} case 'd':
callArgs.push_double(boost::any_cast<double*>(*it2));
case 'p':
{
void *value = boost::any_cast<void *>(*it2);
data.push_back(reinterpret_cast<unsigned int>(value));
break; break;
}
case 's': case 's':
{ callArgs.push_stringPtr(boost::any_cast<const char *>(*it2));
const string *value = boost::any_cast<string>(&*it2); break;
data.push_back(reinterpret_cast<unsigned int>(value->c_str())); case 'v':
result = boost::any();
break; break;
}
default: default:
throw runtime_error("C++ call: Unknown argument identifier " + *it); throw runtime_error("C++ call: Unknown argument identifier " + *it);
} }
} }
#ifndef _WIN32 // temporally disabled
unsigned int result_low; Func f = reinterpret_cast<Func>(fCpp);
unsigned int result_high; result = ::Call(f, callArgs);
unsigned int *source = &data[0];
unsigned int size = data.size() * 4;
asm(
"MOV EDI,ESP\n"
"SUB EDI,%3\n" // allocate memory in stack.
"MOV ESI,%4\n" // move ptr of source to ESI.
"MOV ECX,%3\n" // length of data.
"PUSH DS\n" // move DS
"POP ES\n" // to ES.
"CLD\n" // clear direction flag.
"REP MOVSB\n" // Move bytes at address DS:ESI to address ES:EDI (move to stack).
"MOV ESI,ESP\n" // stack pointer.
"SUB ESP,%3\n"
"CALL %2\n"
"MOV ESP,ESI\n"
"MOV %0,EAX\n" // move low result from eax
"MOV %1,EDX\n" // move high result from edx
: "=m"(result_low), "=m"(result_high)
: "m"(fCpp) //2, "m"(size) //3, "m"(source) //4
: "eax", "edx", "ecx", "esi", "edi", "cc"
);
*reinterpret_cast<unsigned int *>(&result) = result_low;
*reinterpret_cast<unsigned int *>(((unsigned) &result) + 4) = result_high;
#else #else
throw runtime_error("x64 Not supported yet (builtin timers and [Call/Make]Public"); throw runtime_error("C++ call: Windows not supported yet.")
#endif
#endif #endif
} }

@ -0,0 +1,28 @@
FIND_PATH(CallFF_INCLUDES call.hpp
ENV CPATH
PATH_SUFFIXES include/CallFF include
/usr/include
/usr/local/include
/opt/local/include
$ENV{CallFF_ROOT}/include
)
FIND_LIBRARY(CallFF_LIBRARY NAMES callff
PATHS
ENV LD_LIBRARY_PATH
ENV LIBRARY_PATH
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/opt/local/lib
$ENV{CallFF_ROOT}/lib/*
)
if(CallFF_LIBRARY)
set(CallFF_LIBRARIES "${CallFF_LIBRARY}" CACHE STRING "CallFF Libraries")
endif()
if(CallFF_INCLUDES AND CallFF_LIBRARY)
set(CallFF_FOUND TRUE)
endif(CallFF_INCLUDES AND CallFF_LIBRARY)
Loading…
Cancel
Save