-
Notifications
You must be signed in to change notification settings - Fork 1
/
1. JIT Compiled Expression Evaluator.c
103 lines (90 loc) · 2.16 KB
/
1. JIT Compiled Expression Evaluator.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* Tony Givargis
* Copyright (C), 2023
* University of California, Irvine
*
* CS 238P - Operating Systems
* jitc.c
*/
/**
* Needs:
* fork()
* execv()
* waitpid()
* WIFEXITED()
* WEXITSTATUS()
* dlopen()
* dlclose()
* dlsym()
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dlfcn.h>
#include "jitc.h"
#include "system.h"
struct jitc {
void *module_handle;
};
int jitc_compile(const char *input, const char *output) {
pid_t child_pid = fork();
if (child_pid == -1) {
TRACE("Fork failed");
return -1;
}
if (child_pid == 0) {
const char *args[] = {"/usr/bin/gcc", "-ansi", "-O3", "-fpic", "-shared", NULL, "-o", NULL, NULL};
args[5] = input;
args[7] = output;
execv("/usr/bin/gcc",(char *const *)args);
perror("execv");
exit(EXIT_FAILURE);
} else {
int status;
waitpid(child_pid, &status, 0);
if (WIFEXITED(status)) {
int exit_status = WEXITSTATUS(status);
if (exit_status != 0) {
TRACE("Compilation failed");
return exit_status;
}
} else {
TRACE("Child process did not exit normally");
return -1;
}
}
return 0;
}
struct jitc *jitc_open(const char *pathname) {
struct jitc *jitc = (struct jitc *)malloc(sizeof(struct jitc));
if (!jitc) {
TRACE("Failed to allocate memory for struct jitc");
return NULL;
}
jitc->module_handle = dlopen(pathname, RTLD_LAZY | RTLD_LOCAL);
if (!jitc->module_handle) {
TRACE(dlerror());
FREE(jitc);
return NULL;
}
return jitc;
}
void jitc_close(struct jitc *jitc) {
if (jitc) {
if (jitc->module_handle) {
dlclose(jitc->module_handle);
}
FREE(jitc);
}
}
long jitc_lookup(struct jitc *jitc, const char *function_name) {
long *function_address = dlsym(jitc->module_handle, function_name);
if (!function_address) {
TRACE(dlerror());
return 0;
}
return (long)function_address;
}