Archive ScriptVM and ScriptThread appropriately

This commit is contained in:
smallmodel 2023-11-27 19:30:40 +01:00
parent 969255c48e
commit fad555308b
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
3 changed files with 123 additions and 37 deletions

View file

@ -925,44 +925,59 @@ void ScriptMaster::ArchiveString(Archiver& arc, const_str& s)
void ScriptMaster::Archive(Archiver& arc)
{
ScriptClass *scr;
ScriptVM *m_current;
ScriptThread *m_thread;
int numClasses;
int numThreads;
int i, j;
int count;
int i, j;
ScriptClass *c;
int num;
ScriptVM *scriptVM;
ScriptVM *prevScriptVM;
if (arc.Saving()) {
numClasses = (int)ScriptClass_allocator.Count();
arc.ArchiveInteger(&numClasses);
count = (int)ScriptClass_allocator.Count();
arc.ArchiveInteger(&count);
MEM_BlockAlloc_enum<ScriptClass> en = ScriptClass_allocator;
for (scr = en.NextElement(); scr != NULL; scr = en.NextElement()) {
scr->ArchiveInternal(arc);
for (c = en.NextElement(); c != NULL; c = en.NextElement()) {
c->ArchiveInternal(arc);
numThreads = 0;
for (m_current = scr->m_Threads; m_current != NULL; m_current = m_current->next) {
numThreads++;
num = 0;
for (scriptVM = c->m_Threads; scriptVM != NULL; scriptVM = scriptVM->next) {
num++;
}
arc.ArchiveInteger(&numThreads);
arc.ArchiveInteger(&num);
for (m_current = scr->m_Threads; m_current != NULL; m_current = m_current->next) {
m_current->m_Thread->ArchiveInternal(arc);
for (scriptVM = c->m_Threads; scriptVM != NULL; scriptVM = scriptVM->next) {
scriptVM->m_Thread->ArchiveInternal(arc);
}
}
} else {
arc.ArchiveInteger(&numClasses);
arc.ArchiveInteger(&count);
for (i = 0; i < numClasses; i++) {
scr = new ScriptClass();
scr->ArchiveInternal(arc);
for (i = 0; i < count; i++) {
c = new ScriptClass();
c->ArchiveInternal(arc);
arc.ArchiveInteger(&numThreads);
arc.ArchiveInteger(&num);
for (j = 0; j < numThreads; j++) {
m_thread = new ScriptThread(scr, NULL);
m_thread->ArchiveInternal(arc);
c->m_Threads = NULL;
prevScriptVM = NULL;
for (j = 0; j < num; j++) {
scriptVM = new ScriptVM;
scriptVM->m_Thread = new ScriptThread;
scriptVM->m_Thread->m_ScriptVM = scriptVM;
scriptVM->m_ScriptClass = c;
scriptVM->next = NULL;
if (prevScriptVM) {
prevScriptVM->next = scriptVM;
} else {
c->m_Threads = scriptVM;
}
prevScriptVM = scriptVM;
scriptVM->m_Thread->ArchiveInternal(arc);
}
}
}

View file

@ -82,18 +82,9 @@ ScriptVMStack::ScriptVMStack()
{}
ScriptVMStack::ScriptVMStack(size_t stackSize)
: ScriptVMStack()
{
if (!stackSize) {
stackSize = 1;
}
// allocate at once
uint8_t *data = (uint8_t *)gi.Malloc((sizeof(ScriptVariable) + sizeof(ScriptVariable *)) * stackSize);
localStack = new (data) ScriptVariable[stackSize];
data += sizeof(ScriptVariable) * stackSize;
pTop = localStack;
stackBottom = localStack + stackSize;
Allocate(stackSize);
}
ScriptVMStack::ScriptVMStack(ScriptVMStack&& other)
@ -117,6 +108,31 @@ ScriptVMStack& ScriptVMStack::operator=(ScriptVMStack&& other)
}
ScriptVMStack::~ScriptVMStack()
{
Free();
}
void ScriptVMStack::Allocate(size_t stackSize)
{
if (localStack) {
// free the current local stack
Free();
}
if (!stackSize) {
stackSize = 1;
}
// allocate at once
uint8_t *data = (uint8_t *)gi.Malloc((sizeof(ScriptVariable) + sizeof(ScriptVariable *)) * stackSize);
localStack = new (data) ScriptVariable[stackSize];
data += sizeof(ScriptVariable) * stackSize;
pTop = localStack;
stackBottom = localStack + stackSize;
}
void ScriptVMStack::Free()
{
const size_t localStackSize = GetStackSize();
for (uintptr_t i = 0; i < localStackSize; ++i) {
@ -215,6 +231,33 @@ ScriptVariable& ScriptVMStack::PushAndGet(size_t offset)
return *pTop;
}
void ScriptVMStack::Archive(Archiver& arc)
{
unsigned int size;
unsigned int offset;
unsigned int i;
if (arc.Saving()) {
size = stackBottom - localStack;
offset = pTop - localStack;
arc.ArchiveUnsigned(&size);
arc.ArchiveUnsigned(&offset);
} else {
arc.ArchiveUnsigned(&size);
arc.ArchiveUnsigned(&offset);
Allocate(size);
pTop = localStack + offset;
}
if (localStack) {
for (i = 0; i < size; i++) {
localStack[i].ArchiveInternal(arc);
}
}
}
void ScriptVMStack::MoveTop(ScriptVariable&& other)
{
*pTop = std::move(other);
@ -246,6 +289,23 @@ void ScriptVM::operator delete(void *ptr)
ScriptVM_allocator.Free(ptr);
}
/*
====================
ScriptVM
====================
*/
ScriptVM::ScriptVM()
{
m_Stack = NULL;
m_PrevCodePos = NULL;
m_pOldData = NULL;
m_OldDataSize = 0;
m_bMarkStack = false;
m_StackPos = NULL;
}
/*
====================
ScriptVM
@ -318,6 +378,8 @@ void ScriptVM::Archive(Archiver& arc)
m_Stack = new ScriptStack;
m_Stack->m_Array = new ScriptVariable[stack];
m_Stack->m_Count = stack;
} else {
m_Stack = NULL;
}
}
@ -330,6 +392,8 @@ void ScriptVM::Archive(Archiver& arc)
m_ScriptClass->ArchiveCodePos(arc, &m_CodePos);
arc.ArchiveByte(&state);
arc.ArchiveByte(&m_ThreadState);
m_VMStack.Archive(arc);
}
/*

View file

@ -98,7 +98,7 @@ public:
ScriptVariable *GetTopPtr(size_t offset) const;
ScriptVariable *GetTopArray(size_t offset = 0) const;
uintptr_t GetIndex() const;
void MoveTop(ScriptVariable &&other);
void MoveTop(ScriptVariable&& other);
/** Pop and return the previous value. */
ScriptVariable& Pop();
@ -111,6 +111,12 @@ public:
ScriptVariable& PushAndGet();
ScriptVariable& PushAndGet(size_t offset);
void Archive(Archiver& arc);
private:
void Allocate(size_t stackSize);
void Free();
private:
/** The VM's local stack. */
ScriptVariable *localStack;
@ -181,12 +187,13 @@ private:
bool Switch(StateScript *stateScript, ScriptVariable& var);
unsigned char *ProgBuffer();
void HandleScriptException(ScriptException &exc);
void HandleScriptException(ScriptException& exc);
public:
void *operator new(size_t size);
void operator delete(void *ptr);
ScriptVM();
ScriptVM(ScriptClass *scriptClass, unsigned char *pCodePos, ScriptThread *thread);
~ScriptVM();