summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-x.bin/jrp.c156
1 files changed, 94 insertions, 62 deletions
diff --git a/.bin/jrp.c b/.bin/jrp.c
index 523a5d49..8c436163 100755
--- a/.bin/jrp.c
+++ b/.bin/jrp.c
@@ -4,6 +4,7 @@ exec cc -Wall -Wextra $@ -o $(dirname $0)/jrp $0
 
 #include <err.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/mman.h>
 #include <sysexits.h>
 #include <unistd.h>
@@ -13,9 +14,30 @@ typedef long long value;
 typedef unsigned long long uvalue;
 typedef value *(*fptr)(value *);
 
+static void rt_print_ascii(value val) {
+    printf("%c\n", (char)val);
+}
+static void rt_print_bin(value val) {
+    static char buf[sizeof(value) * 8 + 1];
+    uvalue uval = val;
+    int i = sizeof(buf);
+    do {
+        buf[--i] = '0' + (uval & 1);
+    } while (uval >>= 1);
+    printf("%s\n", &buf[i]);
+}
+static void rt_print_oct(value val) {
+    printf("%llo\n", val);
+}
+static void rt_print_dec(value val) {
+    printf("%lld\n", val);
+}
+static void rt_print_hex(value val) {
+    printf("%llx\n", val);
+}
+
 enum {
     HOP_NOP  = 0x90666666, // nop
-    HOP_RET  = 0x906666c3, // ret
     HOP_DROP = 0x9066665f, // pop rdi
     HOP_DUP  = 0x90666657, // push rdi
     HOP_SWAP = 0x244c8748, // xchg rdi, [rsp]
@@ -32,6 +54,7 @@ enum {
 enum {
     FOP_PROL = 0x5ffc8948e5894855, // push rbp; mov rbp, rsp; mov rsp, rdi; pop rdi
     FOP_EPIL = 0x5dec8948e0894857, // push rdi; mov rax, rsp; mov rsp, rbp; pop rbp
+    FOP_RET  = 0x90666690666666c3, // ret
     FOP_CRT  = 0xb848906666e58748, // xchg rsp, rbp; mov rax, strict qword 0
     FOP_CALL = 0x90665fe58748d0ff, // call rax; xchg rsp, rbp; pop rdi
     FOP_PUSH = 0xbf48909066666657, // push rdi; mov rdi, strict qword 0
@@ -42,80 +65,89 @@ enum {
     FOP_SHR  = 0x5f242cd348f98948, // mov rcx, rdi; shr qword [rsp], cl; pop rdi
 };
 
-#define FOP(a, b) ((op)(b) << 32 | (op)(a))
+static int page;
 
-#define JIT_PUSH(p, x) { \
-    *(p)++ = FOP_PUSH; \
-    *(p)++ = x; \
-}
+static int radix = 10;
 
-#define JIT_CALL(p, fn) { \
-    *(p)++ = FOP_CRT; \
-    *(p)++ = (op)(fn); \
-    *(p)++ = FOP_CALL; \
-}
+static value *stack;
 
-static void rt_print_ascii(value val) {
-    printf("%c\n", (char)val);
-}
+static struct {
+    op *base;
+    op *ptr;
+    op hop;
+} code;
 
-static void rt_print_bin(value val) {
-    static char buf[sizeof(value) * 8 + 1];
-    uvalue uval = val;
-    int i = sizeof(buf);
-    do {
-        buf[--i] = '0' + (uval & 1);
-    } while (uval >>= 1);
-    printf("%s\n", &buf[i]);
+static void jit_hop(op hop) {
+    if (code.hop) {
+        *code.ptr++ = hop << 32 | code.hop;
+        code.hop = 0;
+    } else {
+        code.hop = hop;
+    }
 }
 
-static void rt_print_oct(value val) {
-    printf("%llo\n", val);
+static void jit_fop(op fop) {
+    if (code.hop) jit_hop(HOP_NOP);
+    *code.ptr++ = fop;
 }
 
-static void rt_print_dec(value val) {
-    printf("%lld\n", val);
-}
+static void jit(char *src) {
+    int error;
 
-static void rt_print_hex(value val) {
-    printf("%llx\n", val);
+    code.ptr = code.base;
+    jit_fop(FOP_PROL);
+
+    jit_fop(FOP_PUSH);
+    jit_fop(7);
+    jit_fop(FOP_PUSH);
+    jit_fop(10);
+    jit_fop(FOP_PUSH);
+    jit_fop(9);
+    jit_fop(FOP_MUL);
+    jit_hop(HOP_ADD);
+    jit_hop(HOP_DUP);
+    jit_hop(HOP_DUP);
+    jit_hop(HOP_DUP);
+    jit_hop(HOP_DUP);
+    jit_fop(FOP_CRT);
+    jit_fop((op)rt_print_ascii);
+    jit_fop(FOP_CALL);
+    jit_fop(FOP_CRT);
+    jit_fop((op)rt_print_bin);
+    jit_fop(FOP_CALL);
+    jit_fop(FOP_CRT);
+    jit_fop((op)rt_print_oct);
+    jit_fop(FOP_CALL);
+    jit_fop(FOP_CRT);
+    jit_fop((op)rt_print_dec);
+    jit_fop(FOP_CALL);
+    jit_fop(FOP_CRT);
+    jit_fop((op)rt_print_hex);
+    jit_fop(FOP_CALL);
+
+    jit_fop(FOP_EPIL);
+    jit_fop(FOP_RET);
+
+    error = mprotect(code.base, page, PROT_READ | PROT_EXEC);
+    if (error) err(EX_OSERR, "mprotect");
+
+    stack = ((fptr)code.base)(stack);
+
+    error = mprotect(code.base, page, PROT_READ | PROT_WRITE);
+    if (error) err(EX_OSERR, "mprotect");
 }
 
 int main() {
-    int error;
-    int page = getpagesize();
-
-    value *base = mmap(0, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
-    if (base == MAP_FAILED) err(EX_OSERR, "mmap");
-    value *stack = base + page / sizeof(value) - 1;
-
-    op *ops = mmap(0, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
-    if (ops == MAP_FAILED) err(EX_OSERR, "mmap");
-
-    op *p = ops;
-    *p++ = FOP_PROL;
-    JIT_PUSH(p, 7);
-    JIT_PUSH(p, 10);
-    JIT_PUSH(p, 9);
-    *p++ = FOP_MUL;
-    *p++ = FOP(HOP_ADD, HOP_DUP);
-    *p++ = FOP(HOP_DUP, HOP_DUP);
-    *p++ = FOP(HOP_DUP, HOP_NOP);
-    JIT_CALL(p, rt_print_ascii);
-    JIT_CALL(p, rt_print_bin);
-    JIT_CALL(p, rt_print_oct);
-    JIT_CALL(p, rt_print_dec);
-    JIT_CALL(p, rt_print_hex);
-    *p++ = FOP_EPIL;
-    *p++ = FOP(HOP_RET, HOP_NOP);
-
-    error = mprotect(ops, page, PROT_READ | PROT_EXEC);
-    if (error) err(EX_OSERR, "mprotect");
+    page = getpagesize();
+
+    code.base = mmap(0, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
+    if (code.base == MAP_FAILED) err(EX_OSERR, "mmap");
 
-    fptr fn = (fptr)ops;
-    stack = fn(stack);
+    stack = mmap(0, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
+    if (stack == MAP_FAILED) err(EX_OSERR, "mmap");
+    stack += page / sizeof(value) - 1;
 
-    printf("%lld\n", *stack);
+    jit("7 10 9 * + :::: , b. o. d. h.");
 
-    return 0;
+    return EX_OK;
 }