progress (need to review further)

This commit is contained in:
2026-02-22 18:09:22 -05:00
parent 03fb6a8180
commit f18af12968
2 changed files with 114 additions and 24 deletions

View File

@@ -139,6 +139,9 @@ WinAPI B4 ms_close_handle(void* hObject) asm("CloseHandle");
#define PRIM_DROP 12
#define PRIM_SUB 13
#define PRIM_EXECUTE 14
#define PRIM_IF 15
#define PRIM_END 16
#define PRIM_RECURSE 17
global const char* prim_names[] = {
"",
@@ -155,7 +158,10 @@ global const char* prim_names[] = {
"DUP ",
"DROP ",
"SUB ",
"EXECUTE "
"EXECUTE ",
"[ ",
"] ",
"RECURSE "
};
internal U4 resolve_name_to_index(const char* ref_name);
@@ -460,6 +466,35 @@ IA_ void x64_CALL_RAX() {
}
IA_ void x64_RET() { emit8(x64_op_RET); } // RET
// Forward-jump placeholder: emits JMP rel32 with a zero displacement and writes
// the offset of the displacement field into *offset_out so it can be patched later.
IA_ void x64_JMP_fwd_placeholder(U4* offset_out) {
emit8(x64_op_JMP_rel32);
offset_out[0] = u4_(code_arena.used);
emit32(0);
}
// Patch a previously emitted forward-jump placeholder.
// offset is the value written by x64_JMP_fwd_placeholder; the displacement is
// computed relative to the end of the 4-byte field (i.e. offset + 4).
IA_ void x64_patch_fwd(U4 offset) {
u4_r(code_arena.start + offset)[0] = u4_(code_arena.used) - (offset + 4);
}
// Conditional Forward Jump (IF)
IA_ void x64_JMP_IF_ZERO_fwd_placeholder(U4* offset_out) {
x64_TEST_RAX_RAX();
emit8(0x0F); emit8(0x84); // JZ rel32
offset_out[0] = u4_(code_arena.used);
emit32(0);
}
// Unconditional Backward Jump (RECURSE)
IA_ void x64_JMP_back(U4 target) {
emit8(x64_op_JMP_rel32);
S4 rel32 = s4_(target) - s4_(code_arena.used + 4);
emit32(u4_(rel32));
}
// JIT Entry Prologue: save RBX, load vm_globals ptr from RCX, restore RAX/RDX state
// vm_globals[14] = RAX save slot (14 * 8 = 0x70)
// vm_globals[15] = RDX save slot (15 * 8 = 0x78)
@@ -623,10 +658,14 @@ IA_ void compile_and_run_tape(void)
U8*r anno_ptr = u8_r(anno_arena.start);
B4 in_def = false;
U4 def_jmp_offset = 0;
U4 current_def_idx = 0;
B4 in_lambda = false;
U4 lambda_jmp_offset = 0;
U4 ctrl_stack[32] = {0};
U4 ctrl_depth = 0;
U8 end_idx = run_full ? (tape_arena.used / sizeof(U4)) : (cursor_idx + 1);
for (U8 i = 0; i < end_idx; i++)
{
@@ -638,27 +677,24 @@ IA_ void compile_and_run_tape(void)
if (in_lambda && (is_terminator || tag == STag_Lambda)) {
x64_RET();
pad32();
U4 current = code_arena.used;
u4_r(code_arena.start + lambda_jmp_offset)[0] = current - (lambda_jmp_offset + 4);
x64_patch_fwd(lambda_jmp_offset);
in_lambda = false;
}
if (in_def && is_terminator) {
x64_RET();
pad32();
U4 current = code_arena.used;
u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4);
x64_patch_fwd(def_jmp_offset);
in_def = false;
}
if (tag == STag_Define)
{
pad32();
emit8(x64_op_CALL_rel32 - 3); // E9 = JMP rel32
def_jmp_offset = code_arena.used;
emit32(0);
x64_JMP_fwd_placeholder(& def_jmp_offset);
pad32();
in_def = true;
current_def_idx = i;
tape_to_code_offset[i] = code_arena.used;
@@ -687,9 +723,7 @@ IA_ void compile_and_run_tape(void)
pad32();
// jmp rel32 over lambda body
emit8(x64_op_JMP_rel32);
lambda_jmp_offset = code_arena.used;
emit32(0);
x64_JMP_fwd_placeholder(& lambda_jmp_offset);
pad32();
in_lambda = true;
@@ -699,7 +733,26 @@ IA_ void compile_and_run_tape(void)
}
else if (tag == STag_Call || tag == STag_Imm)
{
compile_action(val);
if (val == 0x10000 + PRIM_IF) {
x64_JMP_IF_ZERO_fwd_placeholder(& ctrl_stack[ctrl_depth++]);
pad32();
}
else if (val == 0x10000 + PRIM_END) {
if (ctrl_depth > 0) {
U4 offset = ctrl_stack[--ctrl_depth];
x64_patch_fwd(offset);
}
pad32();
}
else if (val == 0x10000 + PRIM_RECURSE) {
if (in_def) {
x64_JMP_back(tape_to_code_offset[current_def_idx]);
}
pad32();
}
else {
compile_action(val);
}
}
else if (tag == STag_Data)
{
@@ -715,14 +768,12 @@ IA_ void compile_and_run_tape(void)
if (in_lambda) {
x64_RET();
pad32();
U4 current = code_arena.used;
u4_r(code_arena.start + lambda_jmp_offset)[0] = current - (lambda_jmp_offset + 4);
x64_patch_fwd(lambda_jmp_offset);
}
if (in_def) {
x64_RET();
pad32();
U4 current = code_arena.used;
u4_r(code_arena.start + def_jmp_offset)[0] = current - (def_jmp_offset + 4);
x64_patch_fwd(def_jmp_offset);
}
x64_JIT_EPILOGUE();
@@ -1279,11 +1330,31 @@ int main(void) {
scatter(pack_token(STag_Format, 0xA), 0);
scatter(pack_token(STag_Call, 0), "RECURSE ");
scatter(pack_token(STag_Format, 0xA), 0);
scatter(pack_token(STag_Imm, 0), "F_STEP ");
scatter(pack_token(STag_Imm, 0), "F_STEP ");
scatter(pack_token(STag_Imm, 0), "F_STEP ");
scatter(pack_token(STag_Imm, 0), "F_STEP ");
scatter(pack_token(STag_Imm, 0), "F_STEP ");
}
// IF TEST
{
scatter(pack_token(STag_Comment, 0), "IF TEST ");
scatter(pack_token(STag_Format, 0xA), 0);
scatter(pack_token(STag_Data, 0), 0);
scatter(pack_token(STag_Call, 0), "[ ");
scatter(pack_token(STag_Data, 99), 0);
scatter(pack_token(STag_Call, 0), "PRINT ");
scatter(pack_token(STag_Call, 0), "] ");
scatter(pack_token(STag_Data, 11), 0);
scatter(pack_token(STag_Call, 0), "PRINT ");
scatter(pack_token(STag_Format, 0xA), 0);
scatter(pack_token(STag_Data, 1), 0);
scatter(pack_token(STag_Call, 0), "[ ");
scatter(pack_token(STag_Data, 22), 0);
scatter(pack_token(STag_Call, 0), "PRINT ");
scatter(pack_token(STag_Call, 0), "] ");
scatter(pack_token(STag_Format, 0xA), 0);
}
// Lambda test