static int add3(long a, long b, long c) { void *code; unsigned long len; func3_t func; /* Create a SLJIT compiler */ struct sljit_compiler *C = sljit_create_compiler(); /* Start a context(function entry), have 3 arguments, discuss later */ sljit_emit_enter(C, 0, 3, 1, 3, 0, 0, 0); /* The first arguments of function is register SLJIT_S0, 2nd, SLJIT_S1, etc. */ /* R0 = first */ sljit_emit_op1(C, SLJIT_MOV, SLJIT_R0, 0, SLJIT_S0, 0); /* R0 = R0 + second */ sljit_emit_op2(C, SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_S1, 0); /* R0 = R0 + third */ sljit_emit_op2(C, SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_S2, 0); /* This statement mov R0 to RETURN REG and return */ /* in fact, R0 is RETURN REG itself */ sljit_emit_return(C, SLJIT_MOV, SLJIT_R0, 0); /* Generate machine code */ code = sljit_generate_code(C); len = sljit_get_generated_code_size(C); /* Execute code */ func = (func3_t)code; printf("func return %ld\n", func(a, b, c)); /* dump_code(code, len); */ /* Clean up */ sljit_free_compiler(C); sljit_free_code(code); return 0; }
void PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl) { #ifndef SUPPORT_JIT (void)executable_jit; (void)memctl; #else /* SUPPORT_JIT */ executable_functions *functions = (executable_functions *)executable_jit; void *allocator_data = memctl; int i; for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) { if (functions->executable_funcs[i] != NULL) sljit_free_code(functions->executable_funcs[i]); PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data); } SLJIT_FREE(functions, allocator_data); #endif /* SUPPORT_JIT */ }