#include "../../Headers/Sagittarius.h" #include "../../Headers/SagittariusInternal.h" #include #include SAGITTARIUS_API SagittariusVM* sagittarius_vm_new(uint64_t memory_size){ SagittariusVM* vm = malloc(sizeof(SagittariusVM)); if (!vm) return NULL; vm->Memory.data = malloc(memory_size); vm->Memory.size = memory_size; // Clear registers memset(vm->core.reg.head, 0, sizeof(vm->core.reg.head)); // Link core vm->core.memory = &vm->Memory; vm->core.vm = vm; vm->core.pc = 0; // Initialize syscalls vm->SagittariusSyscallEntries = NULL; vm->SagittariusSyscallCount = 0; vm->SagittariusSyscallCapacity = 0; vm->panic_handler = NULL; return vm; } SAGITTARIUS_API void sagittarius_vm_free(SagittariusVM* vm){ if (vm) { if (vm->Memory.data) free(vm->Memory.data); if (vm->SagittariusSyscallEntries) free(vm->SagittariusSyscallEntries); free(vm); } } SAGITTARIUS_API void sagittarius_register_syscall(SagittariusVM *vm, uint64_t id, SagittariusSyscall syscall) { if (!vm) return; if (vm->SagittariusSyscallCount >= vm->SagittariusSyscallCapacity) { vm->SagittariusSyscallCapacity = vm->SagittariusSyscallCapacity == 0 ? 4 : vm->SagittariusSyscallCapacity * 2; vm->SagittariusSyscallEntries = realloc(vm->SagittariusSyscallEntries, vm->SagittariusSyscallCapacity * sizeof(SagittariusSyscallEntry)); } vm->SagittariusSyscallEntries[vm->SagittariusSyscallCount].id = id; vm->SagittariusSyscallEntries[vm->SagittariusSyscallCount].syscall = syscall; vm->SagittariusSyscallCount++; } SAGITTARIUS_API void sagittarius_mem_resize(SagittariusVM* vm, uint64_t new_size){ if (vm) { vm->Memory.data = realloc(vm->Memory.data, new_size); vm->Memory.size = new_size; } } SAGITTARIUS_API uint64_t sagittarius_mem_getsize(SagittariusVM* vm){ return vm ? vm->Memory.size : 0; } SAGITTARIUS_API void sagittarius_load_program_to_mem(SagittariusVM *vm, SagittariusProgram *program, uint64_t offset) { if (!vm || !program) return; uint64_t required_size = offset + program->instCount * 8 + program->data_size; if (required_size > vm->Memory.size) { sagittarius_mem_resize(vm, required_size); } if (program->instCount > 0) { memcpy(vm->Memory.data + offset, program->instructions, program->instCount * 8); } if (program->data_size > 0) { memcpy(vm->Memory.data + offset + program->instCount * 8, program->data, program->data_size); } vm->core.pc = offset; } SAGITTARIUS_API SagittariusProgram *sagittarius_load_program_from_byte_array(uint8_t *data, uint64_t size) { if (size < 28) return NULL; if (memcmp(data, SAGITTARUIS_PROGRAM_HEAD, 7) != 0) return NULL; uint32_t version; memcpy(&version, data + 8, 4); if (version != SAGITTARIUS_PROGRAM_FORMAT_VERSION) return NULL; uint64_t instCount; memcpy(&instCount, data + 12, 8); uint64_t data_size; memcpy(&data_size, data + 20, 8); if (size < 28 + instCount * 8 + data_size) return NULL; SagittariusProgram *prog = malloc(sizeof(SagittariusProgram)); prog->instCount = instCount; if (instCount > 0) { prog->instructions = malloc(instCount * sizeof(SagittariusInst)); memcpy(prog->instructions, data + 28, instCount * 8); } else { prog->instructions = NULL; } prog->data_size = data_size; if (data_size > 0) { prog->data = malloc(data_size); memcpy(prog->data, data + 28 + instCount * 8, data_size); } else { prog->data = NULL; } return prog; } SAGITTARIUS_API void sagittarius_step(SagittariusVM *vm) { if (!vm) return; if (vm->core.pc >= vm->Memory.size) { if (vm->panic_handler) vm->panic_handler(&vm->core, Sagittarius_Msg_OOB, "PC out of bounds"); return; } SagittariusInst inst; memcpy(&inst, &vm->Memory.data[vm->core.pc], sizeof(SagittariusInst)); uint8_t opcode = inst.data & 0xFF; bool success = false; switch ((SagittariusInstDef)opcode) { case math2: success = Math2Op(&vm->core, inst); break; case math1: success = Math1Op(&vm->core, inst); break; case cvt: success = SagCvt(&vm->core, inst); break; case set: success = SagSet(&vm->core, inst); break; case mv: success = SagMv(&vm->core, inst); break; case cp: success = SagCp(&vm->core, inst); break; case save: success = SagSave(&vm->core, inst); break; case load: success = SagLoad(&vm->core, inst); break; case jmp: success = SagJmp(&vm->core, inst); break; case jmp_if: success = SagJmpIf(&vm->core, inst); break; case call: success = SagCall(&vm->core, inst); break; case ret: success = SagRet(&vm->core, inst); break; case cmp: success = SagCmp(&vm->core, inst); break; case mathv: success = SagMathV(&vm->core, inst); break; case halt: success = SagHalt(&vm->core, inst); break; case syscall: success = SagSyscall(&vm->core, inst); break; case tsyscall: success = SagTSyscall(&vm->core, inst); break; default: { if (vm->panic_handler) vm->panic_handler(&vm->core, Sagittarius_Msg_Unknown, "Unknown opcode"); break; } } (void)success; }