Skip to content

Commit 0dfd655

Browse files
committed
first commit
0 parents  commit 0dfd655

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+6184
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
./class2ir/target
3+
./class2ir/.idea
4+
./app/out/classes

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
#java2llvm
3+
An Example Project Show Convert Java Byte Code to LLVM IR assembler , compile standalone executable file
4+
5+
This project is baseed on [class2ir](https://github.com/MParygin/class2ir)
6+
7+
Class2ir look like based on an old llvm version, it can't running on greate than llvm 3.9.
8+
So i changed some instruct syntex, and repair bug.
9+
The class2ir can print number on console.
10+
11+
Currently:
12+
Can generte linux x64 executable file.
13+
14+
Make:
15+
1. Enter directory java2exe/
16+
2. Run java -jar target/
17+
18+
Known issue:
19+
1. No GC.
20+
2. May be some of java instruction can't work, need test
21+
3. some of java instruction no convertion, see MV.java
22+
23+
24+
change log:
25+
1. Add base class java.lang.*, java.io.PrintStream
26+
2. Add String to handle text output, StringBuilder to handle string concat
27+
3. Trace instruction flow , to fix register var scope bug.
28+
29+
30+
31+
32+
=================================
33+
class2ir readme
34+
35+
This project is the compiler from class files (Java byte code) to LL files (LLVM IR assembler).
36+
Result files can be compiled by llvm-as to standalone binary ELF files.
37+
38+
Features:
39+
40+
* No JDK, no JVM
41+
* Linux x86_64 target arch
42+
* Extreme small size (~10-20 kB ordinary program)
43+
* Use glibc
44+
* Use clang for system object
45+
46+
At this moment project in active development, many things does not work.

app/c/Makefile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
TARGET=$(shell basename `pwd`)
2+
LLS=$(wildcard *.ll)
3+
CS=$(wildcard *.c)
4+
ASMS=$(LLS:%.ll=%.s)
5+
ASMS2=$(CS:%.c=%.s)
6+
7+
all: $(TARGET)
8+
9+
$(TARGET): $(ASMS) $(ASMS2)
10+
clang -v -o $(TARGET) $(ASMS) $(ASMS2)
11+
# strip $(TARGET)
12+
13+
%.ll: %.c
14+
# clang -S -emit-llvm -o $@ $<
15+
clang -S -emit-llvm $<
16+
17+
%.bc: %.ll
18+
llvm-as $<
19+
20+
21+
%.s: %.bc
22+
llc $<
23+
24+
25+
clean:
26+
rm -f ./*.s
27+
rm -f $(TARGET)
28+
rm -f ./*.ll
29+
rm -f ./*.bc
30+
rm -f ./*.gch

app/c/Makefile~

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
TARGET=$(shell basename `pwd`)
2+
LLS=$(wildcard *.ll)
3+
CS=$(wildcard *.c)
4+
ASMS=$(LLS:%.ll=%.s)
5+
ASMS2=$(CS:%.c=%.s)
6+
7+
all: $(TARGET)
8+
9+
$(TARGET): $(ASMS) $(ASMS2)
10+
clang -o $(TARGET) $(ASMS) $(ASMS2)
11+
strip $(TARGET)
12+
13+
%.ll: %.c
14+
# clang -S -emit-llvm -o $@ $<
15+
clang -S -emit-llvm $<
16+
17+
%.bc: %.ll
18+
llvm-as $<
19+
20+
21+
%.s: %.bc
22+
llc $<
23+
24+
25+
clean:
26+
rm -f ./*.s
27+
rm -f $(TARGET)
28+
rm -f ./*.ll
29+
rm -f ./*.bc
30+
rm -f ./*.gch

app/c/jni_func.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <stdio.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
#include <sys/time.h>
5+
#include <time.h>
6+
#include <unistd.h>
7+
8+
long long java_lang_System_currentTimeMillis() {
9+
struct timeval tv;
10+
gettimeofday(&tv, NULL);
11+
long long v=tv.tv_sec * 1000 + tv.tv_usec / 1000;
12+
return v;
13+
}
14+
15+
long long java_lang_System_nanoTime() {
16+
struct timeval tv;
17+
gettimeofday(&tv, NULL);
18+
long long v=tv.tv_sec * 1000000 + tv.tv_usec;
19+
v*=1000;
20+
return v;
21+
}
22+
23+
24+
void java_io_PrintStream_println_I(int value) {
25+
printf("%d\n", value);
26+
}
27+
28+
void java_io_PrintStream_println_J(long long value) {
29+
printf("%lld\n", value);
30+
}
31+
32+
void java_io_PrintStream_print_C(short value) {
33+
printf("%c\n", (char)value);
34+
printf("%d\n", (int)value);
35+
}

app/c/runner.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include <stdio.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
6+
#include "runner.h"
7+
8+
void test_Test__clinit_();
9+
10+
void test_Test_main();
11+
12+
int main() {
13+
test_Test__clinit_();
14+
test_Test_main();
15+
}
16+
17+
18+
inline s32 stack_size(RuntimeStack *stack) {
19+
return (stack->sp - stack->store);
20+
}
21+
22+
/* push Integer */
23+
inline void push_int(RuntimeStack *stack, s32 value) {
24+
stack->sp->ivalue = value;//clear 64bit
25+
stack->sp->type = STACK_ENTRY_INT;
26+
stack->sp++;
27+
}
28+
29+
30+
/* pop Integer */
31+
inline s32 pop_int(RuntimeStack *stack) {
32+
stack->sp--;
33+
return stack->sp->ivalue;
34+
}
35+
36+
/* push Double */
37+
inline void push_double(RuntimeStack *stack, f64 value) {
38+
stack->sp->dvalue = value;
39+
stack->sp->type = STACK_ENTRY_DOUBLE;
40+
stack->sp++;
41+
stack->sp->type = STACK_ENTRY_DOUBLE;
42+
// ptr->dvalue = value;
43+
stack->sp++;
44+
}
45+
46+
/* pop Double */
47+
inline f64 pop_double(RuntimeStack *stack) {
48+
stack->sp -= 2;
49+
return stack->sp->dvalue;
50+
}
51+
52+
/* push Float */
53+
inline void push_float(RuntimeStack *stack, f32 value) {
54+
//ptr->lvalue = 0;//clear 64bit
55+
stack->sp->fvalue = value;
56+
stack->sp->type = STACK_ENTRY_FLOAT;
57+
stack->sp++;
58+
}
59+
60+
/* pop Float */
61+
inline f32 pop_float(RuntimeStack *stack) {
62+
stack->sp--;
63+
return stack->sp->fvalue;
64+
}
65+
66+
67+
/* push Long */
68+
inline void push_long(RuntimeStack *stack, s64 value) {
69+
stack->sp->lvalue = value;
70+
stack->sp->type = STACK_ENTRY_LONG;
71+
stack->sp++;
72+
stack->sp->type = STACK_ENTRY_LONG;
73+
// ptr->lvalue = value;
74+
stack->sp++;
75+
}
76+
77+
/* pop Long */
78+
inline s64 pop_long(RuntimeStack *stack) {
79+
stack->sp -= 2;
80+
return stack->sp->lvalue;
81+
}
82+
83+
/* push Ref */
84+
inline void push_ref(RuntimeStack *stack, __refer value) {
85+
stack->sp->type = STACK_ENTRY_REF;
86+
stack->sp->rvalue = value;
87+
stack->sp++;
88+
}
89+
90+
inline __refer pop_ref(RuntimeStack *stack) {
91+
stack->sp--;
92+
return stack->sp->rvalue;
93+
}
94+
95+
96+
inline void push_entry(RuntimeStack *stack, StackEntry *entry) {
97+
stack->sp->lvalue = entry->lvalue;
98+
stack->sp->type = entry->type;
99+
stack->sp++;
100+
}
101+
102+
/* Pop Stack Entry */
103+
inline void pop_entry(RuntimeStack *stack, StackEntry *entry) {
104+
stack->sp--;
105+
entry->lvalue = stack->sp->lvalue;
106+
entry->type = stack->sp->type;
107+
108+
}
109+
110+
inline void pop_empty(RuntimeStack *stack) {
111+
stack->sp--;
112+
}
113+
114+
115+
inline void peek_entry(StackEntry *src, StackEntry *dst) {
116+
dst->lvalue = src->lvalue;
117+
dst->type = src->type;
118+
}
119+
120+
121+
/* Entry to Int */
122+
inline s32 entry_2_int(StackEntry *entry) {
123+
return entry->ivalue;
124+
}
125+
126+
inline s64 entry_2_long(StackEntry *entry) {
127+
return entry->lvalue;
128+
}
129+
130+
inline __refer entry_2_refer(StackEntry *entry) {
131+
return entry->rvalue;
132+
}

app/c/runner.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#ifndef RUNNER_H
2+
#define RUNNER_H
3+
4+
5+
#define STACK_ENTRY_NONE 0
6+
#define STACK_ENTRY_INT 1
7+
#define STACK_ENTRY_FLOAT 2
8+
#define STACK_ENTRY_LONG 4
9+
#define STACK_ENTRY_DOUBLE 8
10+
#define STACK_ENTRY_REF 16
11+
12+
typedef unsigned char u8;
13+
typedef signed char s8;
14+
typedef char c8;
15+
typedef unsigned short int u16;
16+
typedef signed short int s16;
17+
typedef unsigned int u32;
18+
typedef signed int s32;
19+
typedef float f32;
20+
typedef double f64;
21+
typedef unsigned long long int u64;
22+
typedef signed long long int s64;
23+
typedef void *__refer;
24+
25+
typedef struct _StackEntry {
26+
union {
27+
s64 lvalue;
28+
f64 dvalue;
29+
f32 fvalue;
30+
s32 ivalue;
31+
__refer rvalue;
32+
};
33+
s32 type;
34+
} StackEntry, LocalVarItem;
35+
36+
typedef struct _StackFrame {
37+
StackEntry *store;
38+
StackEntry *sp;
39+
s32 max_size;
40+
}RuntimeStack;
41+
42+
43+
void push_entry(RuntimeStack *stack, StackEntry *entry);
44+
45+
void push_int(RuntimeStack *stack, s32 value);
46+
47+
void push_long(RuntimeStack *stack, s64 value);
48+
49+
void push_double(RuntimeStack *stack, f64 value);
50+
51+
void push_float(RuntimeStack *stack, f32 value);
52+
53+
void push_ref(RuntimeStack *stack, __refer value);
54+
55+
__refer pop_ref(RuntimeStack *stack);
56+
57+
s32 pop_int(RuntimeStack *stack);
58+
59+
s64 pop_long(RuntimeStack *stack);
60+
61+
f64 pop_double(RuntimeStack *stack);
62+
63+
f32 pop_float(RuntimeStack *stack);
64+
65+
void pop_entry(RuntimeStack *stack, StackEntry *entry);
66+
67+
void pop_empty(RuntimeStack *stack);
68+
69+
s32 entry_2_int(StackEntry *entry);
70+
71+
void peek_entry(StackEntry *src, StackEntry *dst);
72+
73+
s64 entry_2_long(StackEntry *entry);
74+
75+
__refer entry_2_refer(StackEntry *entry);
76+
77+
78+
#endif //RUNNER_H

app/java/java/io/PrintStream.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package java.io;
2+
3+
public class PrintStream {
4+
5+
native public void println(int v);
6+
7+
native public void println(long v);
8+
9+
native public void print(char v);
10+
11+
public void println(String s) {
12+
if (s == null) return;
13+
for (int i = 0; i < s.length(); i++) {
14+
print(s.charAt(i));
15+
}
16+
print('\n');
17+
}
18+
//
19+
// native public void println_J(long v);
20+
}

0 commit comments

Comments
 (0)