#include "test.h" #include "opcodes.h" #include "str.h" #include "vm.h" #include u32 real_alloc(VM *vm, float v) { i32 fixed = TO_FIXED(v); u32 addr = vm->mp; write_u32(vm, memory, vm->mp, fixed); vm->mp += 4; vm->frames[vm->fp].end += 4; return addr; } u32 nat_alloc(VM *vm, u32 v) { u32 addr = vm->mp; write_u32(vm, memory, vm->mp, v); vm->mp += 4; vm->frames[vm->fp].end += 4; return addr; } u32 int_alloc(VM *vm, i32 v) { u32 addr = vm->mp; write_u32(vm, memory, vm->mp, v); vm->mp += 4; vm->frames[vm->fp].end += 4; return addr; } /* Array of test mappings */ struct TestMapping internal_tests[] = { {"simple.ul", test_simple_compile}, {"window.ul", test_window_click_compile}, {NULL, NULL} /* Sentinel to mark end of array */ }; bool compile_internal_test(const char *filename, VM *vm) { i32 i; for (i = 0; internal_tests[i].filename != NULL; i++) { if (streq(internal_tests[i].filename, filename)) { return internal_tests[i].test_func(vm); } } return false; } bool test_simple_compile(VM *vm) { u32 ptr; u32 newline_addr = str_alloc(vm, &vm->frames[vm->fp], "\n", 2); u32 terminal_path_addr = str_alloc(vm, &vm->frames[vm->fp], "/dev/term/0", 12); vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 0; ptr = real_alloc(vm, 1.0f); write_u32(vm, code, vm->cp, ptr); vm->cp += 4; vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 1; ptr = real_alloc(vm, 2.0f); write_u32(vm, code, vm->cp, ptr); vm->cp += 4; vm->code[vm->cp++] = OP_ADD_REAL; vm->code[vm->cp++] = 2; vm->code[vm->cp++] = 1; vm->code[vm->cp++] = 0; /* let sum = 1 + 2; */ vm->code[vm->cp++] = OP_REAL_TO_STRING; vm->code[vm->cp++] = 3; vm->code[vm->cp++] = 2; vm->code[vm->cp++] = OP_REAL_TO_STRING; vm->code[vm->cp++] = 3; vm->code[vm->cp++] = 2; vm->code[vm->cp++] = OP_LOAD_IMM; vm->code[vm->cp++] = 2; write_u32(vm, code, vm->cp, terminal_path_addr); vm->cp += 4; vm->code[vm->cp++] = OP_STRLEN; vm->code[vm->cp++] = 4; vm->code[vm->cp++] = 3; vm->code[vm->cp++] = OP_SYSCALL; write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE)); vm->cp += 4; vm->code[vm->cp++] = 3; /* arg_count */ vm->code[vm->cp++] = 2; /* first_reg */ /* syscall_id=WRITE, arg_count=2, start_reg=3 ; print(sum.toS()); */ vm->code[vm->cp++] = OP_HALT; /* explicit halt */ return true; } bool test_window_click_compile(VM *vm) { u32 test_pixel_addr, loop_start, screen_path_addr = str_alloc(vm, &vm->frames[vm->fp], "/dev/screen/0", 14); vm->code[vm->cp++] = OP_LOAD; /* R0 = screen path */ vm->code[vm->cp++] = 0; vm->code[vm->cp++] = nat_alloc(vm, screen_path_addr); vm->code[vm->cp++] = OP_LOAD; /* R1 = mode (0) */ vm->code[vm->cp++] = 1; vm->code[vm->cp++] = int_alloc(vm, 0); vm->code[vm->cp++] = OP_SYSCALL; vm->code[vm->cp++] = SYSCALL_DEVICE_OPEN; vm->code[vm->cp++] = 0; /* first_reg */ vm->code[vm->cp++] = 2; /* arg_count */ test_pixel_addr = vm->mp; vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64); vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64); vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64); vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64); vm->frames[vm->fp].end += 4; loop_start = vm->cp; vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 0; vm->code[vm->cp++] = nat_alloc(vm, screen_path_addr); vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 1; vm->code[vm->cp++] = nat_alloc(vm, test_pixel_addr); vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 2; vm->code[vm->cp++] = int_alloc(vm, 1); vm->code[vm->cp++] = OP_SYSCALL; vm->code[vm->cp++] = SYSCALL_DEVICE_WRITE; vm->code[vm->cp++] = 0; /* first_reg */ vm->code[vm->cp++] = 3; /* arg_count */ vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = 3; vm->code[vm->cp++] = nat_alloc(vm, loop_start); vm->code[vm->cp++] = OP_JMP; vm->code[vm->cp++] = 3; vm->code[vm->cp++] = OP_HALT; return true; }