Skip to content
Snippets Groups Projects
jit.c 2.03 KiB
Newer Older
// 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);
}