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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
#ifndef INTERPRETER_H #ifndef INTERPRETER_H
#define INTERPRETER_H #define INTERPRETER_H
#include "pointer_registry.h"
#include <setjmp.h> #include <setjmp.h>
#include <vector>
// The maximum number of opcodes. // The maximum number of opcodes.
#define OPCODE_MAX_COUNT (342) #define OPCODE_MAX_COUNT (342)
@ -121,6 +121,7 @@ enum RawValueType {
#define VALUE_TYPE_FLOAT 0xA001 #define VALUE_TYPE_FLOAT 0xA001
#define VALUE_TYPE_STRING 0x9001 #define VALUE_TYPE_STRING 0x9001
#define VALUE_TYPE_DYNAMIC_STRING 0x9801 #define VALUE_TYPE_DYNAMIC_STRING 0x9801
#define VALUE_TYPE_PTR 0xE001
typedef unsigned short opcode_t; typedef unsigned short opcode_t;
@ -133,6 +134,19 @@ typedef struct Procedure {
int field_14; int field_14;
} Procedure; } 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 // It's size in original code is 144 (0x8C) bytes due to the different
// size of `jmp_buf`. // size of `jmp_buf`.
typedef struct Program { typedef struct Program {
@ -143,10 +157,6 @@ typedef struct Program {
int instructionPointer; // current pos in data int instructionPointer; // current pos in data
int framePointer; // saved stack 1 pos - probably beginning of local variables - probably called base 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 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* staticStrings; // static strings table
unsigned char* dynamicStrings; // dynamic strings table unsigned char* dynamicStrings; // dynamic strings table
unsigned char* identifiers; unsigned char* identifiers;
@ -159,7 +169,9 @@ typedef struct Program {
int flags; // flags int flags; // flags
int field_84; int field_84;
bool exited; bool exited;
PointerRegistry *pointerRegistry; ProgramStack* stackValues;
ProgramStack* returnStackValues;
int arg;
} Program; } Program;
typedef void OpcodeHandler(Program* program); typedef void OpcodeHandler(Program* program);
@ -171,10 +183,6 @@ void _interpretOutputFunc(int (*func)(char*));
int _interpretOutput(const char* format, ...); int _interpretOutput(const char* format, ...);
[[noreturn]] void programFatalError(const char* str, ...); [[noreturn]] void programFatalError(const char* str, ...);
void programPopString(Program* program, opcode_t a2, int a3); 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); Program* programCreateByPath(const char* path);
char* programGetString(Program* program, opcode_t opcode, int offset); char* programGetString(Program* program, opcode_t opcode, int offset);
char* programGetIdentifier(Program* program, int offset); char* programGetIdentifier(Program* program, int offset);
@ -190,7 +198,24 @@ void _updatePrograms();
void programListFree(); void programListFree();
void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler); void interpreterRegisterOpcode(int opcode, OpcodeHandler* handler);
int programPtrToInt(Program* program, void* ptr); void programStackPushValue(Program* program, ProgramValue& programValue);
void* programIntToPtr(Program* program, int ref, bool remove = false); 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 */ #endif /* INTERPRETER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff