Refactor stack handling
This commit is contained in:
parent
d5724b6614
commit
c9e0a311f1
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
1977
src/interpreter.cc
1977
src/interpreter.cc
File diff suppressed because it is too large
Load Diff
|
@ -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
Loading…
Reference in New Issue