Use script VM structure

This commit is contained in:
momo5502 2019-01-19 14:46:48 +01:00
parent 8a9efb47ee
commit 9d83fc2766
4 changed files with 76 additions and 52 deletions

View File

@ -37,10 +37,7 @@ namespace game
char** scrMemTreePub;
char* scrMemTreeGlob;
unsigned int* scr_numParam;
unsigned int* scr_numArgs;
VariableValue** scr_stackPtr;
VariableValue** scr_stackEndPtr;
scrVmPub_t* scr_VmPub;
scr_call_t* scr_instanceFunctions;
scr_call_t* scr_globalFunctions;
@ -119,14 +116,14 @@ namespace game
void Scr_ClearOutParams()
{
const auto num_params = *scr_numParam;
const auto num_params = scr_VmPub->outparamcount;
for (unsigned int i = num_params; i > 0; --i)
{
const auto value = (*scr_stackPtr)[i - 1];
const auto value = scr_VmPub->top[i - 1];
RemoveRefToValue(value.type, value.u);
}
*scr_stackPtr -= num_params;
scr_VmPub->top -= num_params;
}
scr_entref_t Scr_GetEntityIdRef(const unsigned int id)
@ -220,12 +217,7 @@ namespace game
native::scrMemTreePub = reinterpret_cast<char**>(SELECT_VALUE(0x196FB00, 0x1E32000, 0x1C152A4));
native::scrMemTreeGlob = reinterpret_cast<char*>(SELECT_VALUE(0x186DA00, 0x1D6FF00, 0x1C16600));
native::scr_numParam = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BF2598, 0x20B4A98, 0x1F5B098));
native::scr_numArgs = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BF2594, 0x20B4A94, 0x1F5B094));
native::scr_stackPtr = reinterpret_cast<native::VariableValue**>(SELECT_VALUE(0x1BF2590, 0x20B4A90, 0x1F5B090));
native::scr_stackEndPtr = reinterpret_cast<native::VariableValue**>( SELECT_VALUE(0x1BF2584, 0x20B4A84,
0x1F5B084
));
native::scr_VmPub = reinterpret_cast<native::scrVmPub_t*>(SELECT_VALUE(0x1BF2580, 0x20B4A80, 0x1F5B080));
native::scr_instanceFunctions = reinterpret_cast<native::scr_call_t*>( SELECT_VALUE(0x184CDB0, 0x1D4F258,
0x1BF59C8));

View File

@ -52,10 +52,7 @@ namespace game
extern char** scrMemTreePub;
extern char* scrMemTreeGlob;
extern unsigned int* scr_numParam;
extern unsigned int* scr_numArgs;
extern VariableValue** scr_stackPtr;
extern VariableValue** scr_stackEndPtr;
extern scrVmPub_t* scr_VmPub;
extern scr_call_t* scr_instanceFunctions;
extern scr_call_t* scr_globalFunctions;

View File

@ -452,5 +452,39 @@ namespace game
VariableUnion u;
scriptType_e type;
};
struct function_stack_t
{
const char *pos;
unsigned int localId;
unsigned int localVarCount;
VariableValue *top;
VariableValue *startTop;
};
struct function_frame_t
{
function_stack_t fs;
int topType;
};
struct scrVmPub_t
{
unsigned int *localVars;
VariableValue *maxstack;
int function_count;
function_frame_t *function_frame;
VariableValue *top;
/*bool debugCode;
bool abort_on_error;
bool terminal_error;
bool block_execution;*/
unsigned int inparamcount;
unsigned int outparamcount;
unsigned int breakpointOutparamcount;
bool showError;
function_frame_t function_frame_start[32];
VariableValue stack[2048];
};
}
}

View File

@ -488,24 +488,25 @@ int scripting::get_field_id(const int classnum, const std::string& field) const
void scripting::notify(const std::string& event, const unsigned int entity_id,
std::vector<chaiscript::Boxed_Value> arguments)
{
const auto old_args = *game::native::scr_numArgs;
const auto old_params = *game::native::scr_numParam;
const auto old_stack_ptr = *game::native::scr_stackPtr;
const auto old_stack_end_ptr = *game::native::scr_stackEndPtr;
const auto old_args = game::native::scr_VmPub->inparamcount;
const auto old_params = game::native::scr_VmPub->outparamcount;
const auto old_stack_top = game::native::scr_VmPub->top;
const auto old_stack_end = game::native::scr_VmPub->maxstack;
game::native::VariableValue stack[512];
*game::native::scr_stackPtr = stack;
*game::native::scr_stackEndPtr = &stack[ARRAYSIZE(stack) - 1];
*game::native::scr_numArgs = 0;
*game::native::scr_numParam = 0;
game::native::scr_VmPub->top = stack;
game::native::scr_VmPub->maxstack = &stack[ARRAYSIZE(stack) - 1];
game::native::scr_VmPub->inparamcount = 0;
game::native::scr_VmPub->outparamcount = 0;
const auto cleanup = gsl::finally([=]()
{
game::native::Scr_ClearOutParams();
*game::native::scr_numArgs = old_args;
*game::native::scr_numParam = old_params;
*game::native::scr_stackPtr = old_stack_ptr;
*game::native::scr_stackEndPtr = old_stack_end_ptr;
game::native::scr_VmPub->inparamcount = old_args;
game::native::scr_VmPub->outparamcount = old_params;
game::native::scr_VmPub->top = old_stack_top;
game::native::scr_VmPub->maxstack = old_stack_end;
});
std::reverse(arguments.begin(), arguments.end());
@ -515,7 +516,7 @@ void scripting::notify(const std::string& event, const unsigned int entity_id,
}
const auto event_id = game::native::SL_GetString(event.data(), 0);
game::native::Scr_NotifyId(entity_id, event_id, *game::native::scr_numArgs);
game::native::Scr_NotifyId(entity_id, event_id, game::native::scr_VmPub->inparamcount);
}
chaiscript::Boxed_Value scripting::call(const std::string& function, const unsigned int entity_id,
@ -533,24 +534,24 @@ chaiscript::Boxed_Value scripting::call(const std::string& function, const unsig
const auto function_ptr = game::native::Scr_GetFunc(function_index);
const auto old_args = *game::native::scr_numArgs;
const auto old_params = *game::native::scr_numParam;
const auto old_stack_ptr = *game::native::scr_stackPtr;
const auto old_stack_end_ptr = *game::native::scr_stackEndPtr;
const auto old_args = game::native::scr_VmPub->inparamcount;
const auto old_params = game::native::scr_VmPub->outparamcount;
const auto old_stack_top = game::native::scr_VmPub->top;
const auto old_stack_end = game::native::scr_VmPub->maxstack;
game::native::VariableValue stack[512];
*game::native::scr_stackPtr = stack;
*game::native::scr_stackEndPtr = &stack[ARRAYSIZE(stack) - 1];
*game::native::scr_numArgs = 0;
*game::native::scr_numParam = 0;
game::native::scr_VmPub->top = stack;
game::native::scr_VmPub->maxstack = &stack[ARRAYSIZE(stack) - 1];
game::native::scr_VmPub->inparamcount = 0;
game::native::scr_VmPub->outparamcount = 0;
const auto cleanup = gsl::finally([=]()
{
game::native::Scr_ClearOutParams();
*game::native::scr_numArgs = old_args;
*game::native::scr_numParam = old_params;
*game::native::scr_stackPtr = old_stack_ptr;
*game::native::scr_stackEndPtr = old_stack_end_ptr;
game::native::scr_VmPub->inparamcount = old_args;
game::native::scr_VmPub->outparamcount = old_params;
game::native::scr_VmPub->top = old_stack_top;
game::native::scr_VmPub->maxstack = old_stack_end;
});
std::reverse(arguments.begin(), arguments.end());
@ -559,8 +560,8 @@ chaiscript::Boxed_Value scripting::call(const std::string& function, const unsig
this->push_param(argument);
}
*game::native::scr_numParam = *game::native::scr_numArgs;
*game::native::scr_numArgs = 0;
game::native::scr_VmPub->outparamcount = game::native::scr_VmPub->inparamcount;
game::native::scr_VmPub->inparamcount = 0;
if (!call_safe(function_ptr, entity))
{
@ -618,18 +619,18 @@ int scripting::find_function_index(const std::string& function, const bool prefe
void scripting::push_param(const chaiscript::Boxed_Value& value) const
{
if (*game::native::scr_numParam)
if (game::native::scr_VmPub->outparamcount)
{
game::native::Scr_ClearOutParams();
}
if (*game::native::scr_stackPtr == *game::native::scr_stackEndPtr)
if (game::native::scr_VmPub->top == game::native::scr_VmPub->maxstack)
{
throw std::runtime_error("Internal script stack overflow");
}
game::native::VariableValue* value_ptr = ++*game::native::scr_stackPtr;
++*game::native::scr_numArgs;
game::native::VariableValue* value_ptr = ++game::native::scr_VmPub->top;
++game::native::scr_VmPub->inparamcount;
value_ptr->type = game::native::SCRIPT_NONE;
value_ptr->u.intValue = 0;
@ -715,13 +716,13 @@ void scripting::push_param(const chaiscript::Boxed_Value& value) const
chaiscript::Boxed_Value scripting::get_return_value()
{
if (*game::native::scr_numArgs == 0) return {};
if (game::native::scr_VmPub->inparamcount == 0) return {};
game::native::Scr_ClearOutParams();
*game::native::scr_numParam = *game::native::scr_numArgs;
*game::native::scr_numArgs = 0;
game::native::scr_VmPub->outparamcount = game::native::scr_VmPub->inparamcount;
game::native::scr_VmPub->inparamcount = 0;
return this->make_boxed((*game::native::scr_stackPtr)[1 - *game::native::scr_numParam]);
return this->make_boxed(game::native::scr_VmPub->top[1 - game::native::scr_VmPub->outparamcount]);
}