Refactor stack handling

This commit is contained in:
Alexander Batalov 2022-07-05 09:07:19 +03:00
parent d5724b6614
commit c9e0a311f1
6 changed files with 1406 additions and 4596 deletions

View File

@ -10,11 +10,8 @@
typedef struct ExternalVariable {
char name[32];
char* programName;
opcode_t type;
union {
int value;
char* stringValue;
};
ProgramValue value;
char* stringValue;
} ExternalVariable;
typedef struct ExternalProcedure {
@ -172,47 +169,46 @@ ExternalVariable* externalVariableAdd(const char* identifier)
}
// 0x44127C
int externalVariableSetValue(Program* program, const char* name, opcode_t opcode, int data)
int externalVariableSetValue(Program* program, const char* name, ProgramValue& programValue)
{
ExternalVariable* exportedVariable = externalVariableFind(name);
if (exportedVariable == NULL) {
return 1;
}
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 169
}
if ((opcode & 0xF7FF) == VALUE_TYPE_STRING) {
if ((programValue.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
if (program != NULL) {
const char* stringValue = programGetString(program, opcode, data);
exportedVariable->type = VALUE_TYPE_DYNAMIC_STRING;
const char* stringValue = programGetString(program, programValue.opcode, programValue.integerValue);
exportedVariable->value.opcode = VALUE_TYPE_DYNAMIC_STRING;
exportedVariable->stringValue = (char*)internal_malloc_safe(strlen(stringValue) + 1, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 175
strcpy(exportedVariable->stringValue, stringValue);
}
} else {
exportedVariable->value = data;
exportedVariable->type = opcode;
exportedVariable->value = programValue;
}
return 0;
}
// 0x4413D4
int externalVariableGetValue(Program* program, const char* name, opcode_t* opcodePtr, int* dataPtr)
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value)
{
ExternalVariable* exportedVariable = externalVariableFind(name);
if (exportedVariable == NULL) {
return 1;
}
*opcodePtr = exportedVariable->type;
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
*dataPtr = programPushString(program, exportedVariable->stringValue);
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
value.opcode = exportedVariable->value.opcode;
value.integerValue = programPushString(program, exportedVariable->stringValue);
} else {
*dataPtr = exportedVariable->value;
value = exportedVariable->value;
}
return 0;
@ -229,7 +225,7 @@ int externalVariableCreate(Program* program, const char* identifier)
return 1;
}
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 234
}
} else {
@ -244,8 +240,8 @@ int externalVariableCreate(Program* program, const char* identifier)
strcpy(exportedVariable->programName, programName);
}
exportedVariable->type = VALUE_TYPE_INT;
exportedVariable->value = 0;
exportedVariable->value.opcode = VALUE_TYPE_INT;
exportedVariable->value.integerValue = 0;
return 0;
}
@ -278,7 +274,7 @@ void externalVariablesClear()
internal_free_safe(exportedVariable->programName, __FILE__, __LINE__); // ..\\int\\EXPORT.C, 274
}
if (exportedVariable->type == VALUE_TYPE_DYNAMIC_STRING) {
if (exportedVariable->value.opcode == VALUE_TYPE_DYNAMIC_STRING) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // ..\\int\\EXPORT.C, 276
}
}
@ -332,7 +328,7 @@ void _exportClearAllVariables()
for (int index = 0; index < 1013; index++) {
ExternalVariable* exportedVariable = &(gExternalVariables[index]);
if (exportedVariable->name[0] != '\0') {
if ((exportedVariable->type & 0xF7FF) == VALUE_TYPE_STRING) {
if ((exportedVariable->value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
if (exportedVariable->stringValue != NULL) {
internal_free_safe(exportedVariable->stringValue, __FILE__, __LINE__); // "..\\int\\EXPORT.C", 387
}
@ -344,7 +340,7 @@ void _exportClearAllVariables()
}
exportedVariable->name[0] = '\0';
exportedVariable->type = 0;
exportedVariable->value.opcode = 0;
}
}
}

View File

@ -3,8 +3,8 @@
#include "interpreter.h"
int externalVariableSetValue(Program* program, const char* identifier, opcode_t opcode, int data);
int externalVariableGetValue(Program* program, const char* name, opcode_t* opcodePtr, int* dataPtr);
int externalVariableSetValue(Program* program, const char* identifier, ProgramValue& value);
int externalVariableGetValue(Program* program, const char* name, ProgramValue& value);
int externalVariableCreate(Program* program, const char* identifier);
void _initExport();
void externalVariablesClear();

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include "pointer_registry.h"
#include <setjmp.h>
#include <vector>
// The maximum number of opcodes.
#define OPCODE_MAX_COUNT (342)
@ -121,6 +121,7 @@ enum RawValueType {
#define VALUE_TYPE_FLOAT 0xA001
#define VALUE_TYPE_STRING 0x9001
#define VALUE_TYPE_DYNAMIC_STRING 0x9801
#define VALUE_TYPE_PTR 0xE001
typedef unsigned short opcode_t;
@ -133,6 +134,19 @@ typedef struct Procedure {
int field_14;
} Procedure;
typedef struct ProgramValue {
opcode_t opcode;
union {
int integerValue;
float floatValue;
void* pointerValue;
};
bool isEmpty();
} ProgramValue;
typedef std::vector<ProgramValue> ProgramStack;
// It's size in original code is 144 (0x8C) bytes due to the different
// size of `jmp_buf`.
typedef struct Program {
@ -143,10 +157,6 @@ typedef struct Program {
int instructionPointer; // current pos in data
int framePointer; // saved stack 1 pos - probably beginning of local variables - probably called base
int basePointer; // saved stack 1 pos - probably beginning of global variables
unsigned char* stack; // stack 1 (4096 bytes)
unsigned char* returnStack; // stack 2 (4096 bytes)
int stackPointer; // stack pointer 1
int returnStackPointer; // stack pointer 2
unsigned char* staticStrings; // static strings table
unsigned char* dynamicStrings; // dynamic strings table
unsigned char* identifiers;
@ -159,7 +169,9 @@ typedef struct Program {
int flags; // flags
int field_84;
bool exited;
PointerRegistry *pointerRegistry;
ProgramStack* stackValues;
ProgramStack* returnStackValues;
int arg;
} Program;
typedef void OpcodeHandler(Program* program);
@ -171,10 +183,6 @@ void _interpretOutputFunc(int (*func)(char*));
int _interpretOutput(const char* format, ...);
[[noreturn]] void programFatalError(const char* str, ...);
void programPopString(Program* program, opcode_t a2, int a3);
void programStackPushInt16(Program* program, int value);
void programStackPushInt32(Program* program, int value);
opcode_t programStackPopInt16(Program* program);
int programStackPopInt32(Program* program);
Program* programCreateByPath(const char* path);
char* programGetString(Program* program, opcode_t opcode, int offset);
char* programGetIdentifier(Program* program, int offset);
@ -190,7 +198,24 @@ void _updatePrograms();
void programListFree();
void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler);
int programPtrToInt(Program* program, void* ptr);
void* programIntToPtr(Program* program, int ref, bool remove = false);
void programStackPushValue(Program* program, ProgramValue& programValue);
void programStackPushInteger(Program* program, int value);
void programStackPushFloat(Program* program, float value);
void programStackPushString(Program* program, char* string);
void programStackPushPointer(Program* program, void* value);
ProgramValue programStackPopValue(Program* program);
int programStackPopInteger(Program* program);
float programStackPopFloat(Program* program);
char* programStackPopString(Program* program);
void* programStackPopPointer(Program* program);
void programReturnStackPushValue(Program* program, ProgramValue& programValue);
void programReturnStackPushInteger(Program* program, int value);
void programReturnStackPushPointer(Program* program, void* value);
ProgramValue programReturnStackPopValue(Program* program);
int programReturnStackPopInteger(Program* program);
void* programReturnStackPopPointer(Program* program);
#endif /* INTERPRETER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff