Fix script function calling + expose lui globals

This commit is contained in:
Federico Cecchetto 2021-10-01 23:41:32 +02:00
parent 52cf0aad1b
commit cd79cd4d87
6 changed files with 136 additions and 25 deletions

View File

@ -969,11 +969,11 @@ namespace game
TNUMBER = 0x3,
TSTRING = 0x4,
TTABLE = 0x5,
TFUNCTION = 0x6,
TFUNCTION = 0x6, // idk
TUSERDATA = 0x7,
TTHREAD = 0x8,
TIFUNCTION = 0x9,
TCFUNCTION = 0xA,
TIFUNCTION = 0x9, // Lua function
TCFUNCTION = 0xA, // C function
TUI64 = 0xB,
TSTRUCT = 0xC,
NUM_TYPE_OBJECTS = 0xE,
@ -985,13 +985,27 @@ namespace game
HksValue v;
};
const struct hksInstruction
{
unsigned int code;
};
struct ActivationRecord
{
HksObject* m_base;
const hksInstruction* m_returnAddress;
__int16 m_tailCallDepth;
__int16 m_numVarargs;
int m_numExpectedReturns;
};
struct CallStack
{
void* m_records;
void* m_lastrecord;
void* m_current;
const unsigned int* m_current_lua_pc;
const unsigned int* m_hook_return_addr;
ActivationRecord* m_records;
ActivationRecord* m_lastrecord;
ActivationRecord* m_current;
const hksInstruction* m_current_lua_pc;
const hksInstruction* m_hook_return_addr;
int m_hook_level;
};
@ -1003,11 +1017,73 @@ namespace game
HksObject* bottom;
};
struct lua_State
struct UpValue : ChunkHeader
{
char __pad0[24];
HksObject m_storage;
HksObject* loc;
UpValue* m_next;
};
struct CallSite
{
_SETJMP_FLOAT128 m_jumpBuffer[16];
CallSite* m_prev;
};
enum Status
{
NEW = 0x1,
RUNNING = 0x2,
YIELDED = 0x3,
DEAD_ERROR = 0x4,
};
enum HksError
{
HKS_NO_ERROR = 0x0,
LUA_ERRSYNTAX = 0xFFFFFFFC,
LUA_ERRFILE = 0xFFFFFFFB,
LUA_ERRRUN = 0xFFFFFF9C,
LUA_ERRMEM = 0xFFFFFF38,
LUA_ERRERR = 0xFFFFFED4,
HKS_THROWING_ERROR = 0xFFFFFE0C,
HKS_GC_YIELD = 0x1,
};
struct lua_Debug
{
int event;
const char* name;
const char* namewhat;
const char* what;
const char* source;
int currentline;
int nups;
int nparams;
int ishksfunc;
int linedefined;
int lastlinedefined;
char short_src[512];
int callstack_level;
int is_tail_call;
};
struct lua_State : ChunkHeader
{
void* m_global;
CallStack m_callStack;
ApiStack m_apistack;
UpValue* pending;
HksObject globals;
HksObject m_cEnv;
CallSite* m_callsites;
int m_numberOfCCalls;
void* m_context;
InternString* m_name;
lua_State* m_nextState;
lua_State* m_nextStateStack;
Status m_status;
HksError m_error;
};
using lua_function = int(__fastcall*)(lua_State*);

View File

@ -18,20 +18,19 @@ namespace ui_scripting
value get_return_value(int offset)
{
const auto state = *game::hks::lua_state;
const auto top = &state->m_apistack.top[-1 - offset];
return *top;
return state->m_apistack.top[-1 - offset];
}
void call_script_function(const function& function, const arguments& arguments)
arguments call_script_function(const function& function, const arguments& arguments)
{
const auto state = *game::hks::lua_state;
stack_isolation _;
for (auto i = arguments.rbegin(); i != arguments.rend(); ++i)
push_value(function);
for (auto i = arguments.begin(); i != arguments.end(); ++i)
{
push_value(*i);
}
push_value(function);
enable_error_hook();
const auto __ = gsl::finally([]()
@ -39,11 +38,27 @@ namespace ui_scripting
disable_error_hook();
});
// Not sure about this
try
{
game::hks::vm_call_internal(state, static_cast<int>(arguments.size()), 0, 0);
game::hks::vm_call_internal(state, static_cast<int>(arguments.size()), -1, 0);
std::vector<value> values;
const auto top = state->m_apistack.top;
const auto base = state->m_apistack.base;
const auto num = top - base;
for (auto i = 0; i < num; i++)
{
values.push_back(get_return_value(i));
}
if (values.size() == 0)
{
values.push_back({});
}
return values;
}
catch (const std::exception& e)
{

View File

@ -8,7 +8,7 @@ namespace ui_scripting
void push_value(const value& value);
value get_return_value(int offset);
void call_script_function(const function& function, const arguments& arguments);
arguments call_script_function(const function& function, const arguments& arguments);
value get_field(const userdata& self, const value& key);
value get_field(const table& self, const value& key);

View File

@ -1047,6 +1047,18 @@ namespace ui_scripting::lua
auto table_type = state.new_usertype<table>("table_");
table_type["get"] = [](const table& table, const sol::this_state s,
const std::string& name)
{
return convert(s, table.get(name));
};
table_type["set"] = [](const table& table, const sol::this_state s,
const std::string& name, const sol::lua_value& value)
{
table.set(name, convert({s, value}));
};
table_type[sol::meta_function::index] = [](const table& table, const sol::this_state s,
const std::string& name)
{
@ -1077,7 +1089,9 @@ namespace ui_scripting::lua
return result;
};
auto function_type = state.new_usertype<function>("function");
state["luiglobals"] = table((*::game::hks::lua_state)->globals.v.table);
auto function_type = state.new_usertype<function>("function_");
function_type[sol::meta_function::call] = [](const function& function, const sol::this_state s, sol::variadic_args va)
{
@ -1088,7 +1102,15 @@ namespace ui_scripting::lua
arguments.push_back(convert({s, arg}));
}
function.call(arguments);
const auto values = function.call(arguments);
std::vector<sol::lua_value> returns;
for (const auto& value : values)
{
returns.push_back(convert(s, value));
}
return sol::as_returns(returns);
};
struct player

View File

@ -92,7 +92,6 @@ namespace ui_scripting
arguments function::call(const arguments& arguments) const
{
call_script_function(*this, arguments);
return {};
return call_script_function(*this, arguments);
}
}

View File

@ -259,8 +259,7 @@ namespace ui_scripting
template <>
bool value::is<function>() const
{
return this->get_raw().t == game::hks::TIFUNCTION
|| this->get_raw().t == game::hks::TCFUNCTION;
return this->get_raw().t == game::hks::TIFUNCTION;
}
template <>