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, TNUMBER = 0x3,
TSTRING = 0x4, TSTRING = 0x4,
TTABLE = 0x5, TTABLE = 0x5,
TFUNCTION = 0x6, TFUNCTION = 0x6, // idk
TUSERDATA = 0x7, TUSERDATA = 0x7,
TTHREAD = 0x8, TTHREAD = 0x8,
TIFUNCTION = 0x9, TIFUNCTION = 0x9, // Lua function
TCFUNCTION = 0xA, TCFUNCTION = 0xA, // C function
TUI64 = 0xB, TUI64 = 0xB,
TSTRUCT = 0xC, TSTRUCT = 0xC,
NUM_TYPE_OBJECTS = 0xE, NUM_TYPE_OBJECTS = 0xE,
@ -985,13 +985,27 @@ namespace game
HksValue v; 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 struct CallStack
{ {
void* m_records; ActivationRecord* m_records;
void* m_lastrecord; ActivationRecord* m_lastrecord;
void* m_current; ActivationRecord* m_current;
const unsigned int* m_current_lua_pc; const hksInstruction* m_current_lua_pc;
const unsigned int* m_hook_return_addr; const hksInstruction* m_hook_return_addr;
int m_hook_level; int m_hook_level;
}; };
@ -1003,11 +1017,73 @@ namespace game
HksObject* bottom; 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; CallStack m_callStack;
ApiStack m_apistack; 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*); using lua_function = int(__fastcall*)(lua_State*);

View File

@ -18,20 +18,19 @@ namespace ui_scripting
value get_return_value(int offset) value get_return_value(int offset)
{ {
const auto state = *game::hks::lua_state; const auto state = *game::hks::lua_state;
const auto top = &state->m_apistack.top[-1 - offset]; return state->m_apistack.top[-1 - offset];
return *top;
} }
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; const auto state = *game::hks::lua_state;
stack_isolation _; 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(*i);
} }
push_value(function);
enable_error_hook(); enable_error_hook();
const auto __ = gsl::finally([]() const auto __ = gsl::finally([]()
@ -39,11 +38,27 @@ namespace ui_scripting
disable_error_hook(); disable_error_hook();
}); });
// Not sure about this
try 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) catch (const std::exception& e)
{ {

View File

@ -8,7 +8,7 @@ namespace ui_scripting
void push_value(const value& value); void push_value(const value& value);
value get_return_value(int offset); 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 userdata& self, const value& key);
value get_field(const table& 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_"); 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, table_type[sol::meta_function::index] = [](const table& table, const sol::this_state s,
const std::string& name) const std::string& name)
{ {
@ -1077,7 +1089,9 @@ namespace ui_scripting::lua
return result; 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) 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})); 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 struct player

View File

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

View File

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