Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
jit.c
Go to the documentation of this file.
1/* -*- C -*-
2 * Serene programming language
3 * Copyright (C) 2019-2026 Sameer Rahmani <[email protected]>
4 *
5 * This library is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#include "serene/jit/jit.h"
20
21#include <llvm-c/Core.h>
22#include <llvm-c/Error.h>
23#include <llvm-c/LLJIT.h>
24#include <llvm-c/Support.h>
25#include <llvm-c/Target.h>
26
27#include <stdio.h>
28#include <string.h>
29
30#include "serene/rt/context.h"
31#include "serene/rt/engine.h"
33#include "serene/utils.h"
34
35static inline int handle_error(LLVMErrorRef err) {
36 // TODO(lxsameer): Use the runtime diagnostic system here.
37 char *err_msg = LLVMGetErrorMessage(err);
38 UNUSED(fprintf(stderr, "Error: %s\n", err_msg));
39 LLVMDisposeErrorMessage(err_msg);
40 return 1;
41}
42
44 PANIC_IF_NULL(mm);
46 PANIC_IF_NULL(jit);
47 jit->builder = nullptr;
48 jit->llvm_jit = nullptr;
49 return jit;
50}
51
52int srn_jit_init(srn_jit_t *result) {
53 PANIC_IF_NULL(result);
54
55 int error = 0;
56 // TODO(lxsameer): Check for the target platform and setup the codegen
57 // and printer accordingly. Only applies to when we want to
58 // link the jit library into the target binary.
59
60 // Initialize native target codegen and asm printer.
61 LLVMInitializeNativeTarget();
62 LLVMInitializeNativeAsmPrinter();
63
64 LLVMErrorRef err = nullptr;
65 err = LLVMOrcCreateLLJIT(&result->llvm_jit, result->builder);
66 if (err) {
67 error = handle_error(err);
68 LLVMShutdown();
69 return error;
70 }
71 return 0;
72}
73
75 PANIC_IF_NULL(jit);
76 // A jit that was made but never initialized has no LLJIT instance to
77 // dispose.
78 if (jit->llvm_jit == nullptr) {
79 return 0;
80 }
81 LLVMErrorRef err = LLVMOrcDisposeLLJIT(jit->llvm_jit);
82 if (err) {
83 return handle_error(err);
84 }
85 return 0;
86}
87
89 PANIC_IF_NULL(ctx);
90 PANIC_IF_NULL(module);
91
92 LLVMOrcLLJITRef j = ctx->engine->jit->llvm_jit;
93
94 LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(j);
95 LLVMErrorRef err = LLVMOrcLLJITAddLLVMIRModule(j, jd, module->tsm);
96 srn_error_t *srn_err = nullptr;
97
98 if (err != nullptr) {
99 // If adding the ThreadSafeModule fails then we need to clean it up
100 // ourselves. If adding it succeeds the JIT will manage the memory.
101 // LLVMOrcDisposeThreadSafeModule(module);
102
103 // LLVM owns the string message, but we want to own it. The copy has to
104 // include the terminator; srn_copy_bytes copies exactly the byte count
105 // it is given.
106 char *jit_err_msg = LLVMGetErrorMessage(err);
107 char *msg = srn_copy_bytes(ctx, jit_err_msg, strlen(jit_err_msg) + 1, alignof(char));
108 srn_err = srn_errors_make(ctx, FAILED_TO_ADD_MODULE, msg);
109 LLVMDisposeErrorMessage(jit_err_msg);
110 }
111 return srn_err;
112}
srn_error_t * srn_errors_make(const srn_context_t *ctx, srn_error_tag_t tag, const char *msg)
Build an error in ctx's memory, tagged tag and carrying msg.
Definition errors.c:31
@ FAILED_TO_ADD_MODULE
Definition errors.h:80
#define srn_mm_immortal_allocate(mm, T)
Definition interface.h:183
int srn_jit_shutdown(srn_jit_t *jit)
Definition jit.c:74
srn_jit_t * srn_jit_make(srn_mm_t *mm)
Definition jit.c:43
static int handle_error(LLVMErrorRef err)
Definition jit.c:35
srn_error_t * srn_jit_add_module(srn_context_t *ctx, srn_jit_module_t *module)
Add a module to the jit compiler.
Definition jit.c:88
int srn_jit_init(srn_jit_t *result)
Creates a jit engine and sets the given result to it.
Definition jit.c:52
srn_engine_t * engine
Long term state of the compiler.
Definition context.h:49
A runtime error, a tag classifying the failure and a human-readable message.
Definition errors.h:125
LLVMOrcThreadSafeModuleRef tsm
Definition jit.h:29
LLVMOrcLLJITRef llvm_jit
Definition jit.h:36
LLVMOrcLLJITBuilderRef builder
Definition jit.h:37
Main memory manager structure that will own all the allocated blocks and data.
Definition interface.h:107
#define PANIC_IF_NULL(ptr)
Definition utils.h:66
char * srn_copy_bytes(const srn_context_t *ctx, const char *src, size_t len, size_t alignment)
Definition utils.c:56
#define UNUSED(x)
Definition utils.h:45