// for glibc < 2.37 #define _BSD_SOURCE #define _DEFAULT_SOURCE #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <assert.h> #if _WIN32 #include <windows.h> #else #include <sys/mman.h> #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) #define MAP_ANONYMOUS MAP_ANON #endif #endif #if defined(__APPLE__) && defined(__MACH__) #define MAP_JIT_VALUE MAP_JIT void sys_icache_invalidate(void *start, size_t len); #else #define MAP_JIT_VALUE 0 #endif #include "arena.h" #include "jit.h" // dasm_proto.h #include "dasm_x86.h" //|.arch x64 //|.actionlist my_dasm_actions //|.section code //|.globals DASM_LBL_ // Avoid IDE warnings about names that will defined after DynASM preprocessing // step. //|| #define PREPROCESSED_WITH_DASM #ifndef PREPROCESSED_WITH_DASM unsigned char my_dasm_actions[] = {}; #define DASM_SECTION_CODE 0 #define DASM_MAXSECTION 1 enum { DASM_LBL__MAX, }; #endif static void * dasm_link_and_encode(Dst_DECL) { size_t size; void* code; assert(dasm_checkstep(Dst, 0) == DASM_S_OK); assert(dasm_link(Dst, &size) == DASM_S_OK); #ifdef _WIN32 code = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); #else code = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT_VALUE, -1, 0); #endif assert(dasm_encode(Dst, code) == DASM_S_OK); #ifdef _WIN32 DWORD original; VirtualProtect(code, size, PAGE_EXECUTE_READ, &original); #else mprotect(code, size, PROT_READ | PROT_EXEC); #endif #if defined(__APPLE__) && defined(__MACH__) sys_icache_invalidate(code, size); #endif return code; } void jit_init(Dst_DECL, Arena *arena) { (void) arena; dasm_init(Dst, DASM_MAXSECTION); ms->global_labels = arena_alloc(arena, DASM_LBL__MAX * sizeof(ms->global_labels[0])); dasm_setupglobal(Dst, ms->global_labels, DASM_LBL__MAX); } void jit_free(Dst_DECL) { dasm_free(Dst); } int_plus_const_func * jit_addition_with_constant(Dst_DECL, int constant) { (void) constant; dasm_setup(Dst, my_dasm_actions); //| lea eax, [rdi + constant] //| ret return (int_plus_const_func *) dasm_link_and_encode(Dst); }