Skip to content

Commit b41c6cf

Browse files
committed
Multifile support
1 parent 34bdd58 commit b41c6cf

13 files changed

+143
-233
lines changed

.vscode/launch.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"type": "cppdbg",
1010
"request": "launch",
1111
"program": "${workspaceFolder}/bin/main",
12-
"args": ["test/Main.class"],
12+
"args": ["Main"],
1313
"stopAtEntry": false,
1414
"cwd": "${workspaceFolder}",
1515
"environment": [],

bin/main

80 Bytes
Binary file not shown.

src/class_loader.c

+41-23
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
#include "buffer.h"
44

5+
#include <dirent.h>
56
#include <stdlib.h>
67
#include <stdio.h>
78
#include <string.h>
89
#include <assert.h>
910

10-
ClassLoader ClassLoader_create() {
11+
ClassLoader ClassLoader_create(char **classpath, u64 num_paths) {
1112
return (ClassLoader) {
12-
.loaded_classes = HashMap_create()
13+
.classpath = classpath,
14+
.loaded_classes = HashMap_create(),
15+
.num_paths = num_paths
1316
};
1417
}
1518

@@ -145,45 +148,60 @@ Class *Class_from_class_file(ClassFile *class_file) {
145148
return class;
146149
}
147150

148-
// TODO:
149-
// Class_get_method(char *method_name, u32 method_name_length)
150-
151151
char *filename_from_classname(String classname) {
152-
int filename_length = classname.length + 6 + 1;
153152
char *file_extension = ".class";
153+
int filename_length = classname.length + strlen(file_extension) + 1;
154154
char *filename = malloc(filename_length);
155155

156156
memcpy(filename, classname.bytes, classname.length);
157-
memcpy(filename + classname.length, file_extension, 6);
157+
memcpy(filename + classname.length, file_extension, strlen(file_extension));
158158
filename[filename_length-1] = '\0';
159159

160160
return filename;
161161
}
162162

163+
char *find_classfile_in_classpath(ClassLoader loader, String classname) {
164+
char *classfile_name = filename_from_classname(classname);
165+
166+
for (u32 i = 0; i < loader.num_paths; ++i) {
167+
char *dir_path = loader.classpath[i];
168+
169+
DIR *dirp = opendir(dir_path);
170+
struct dirent *file_info = NULL;
171+
while ((file_info = readdir(dirp))) {
172+
if (strcmp(classfile_name, file_info->d_name) == 0) {
173+
u32 dir_len = strlen(dir_path);
174+
u32 classfile_name_len = strlen(classfile_name);
175+
176+
char *full_path = malloc(dir_len + classfile_name_len + 2);
177+
memcpy(full_path, dir_path, dir_len);
178+
full_path[dir_len] = '/';
179+
memcpy(full_path + dir_len + 1, classfile_name, classfile_name_len);
180+
full_path[dir_len+classfile_name_len+1] = '\0';
181+
182+
return full_path;
183+
}
184+
}
185+
}
186+
187+
free(classfile_name);
188+
return NULL;
189+
}
190+
163191
/* Loads a class from it's class file and convert it into its runtime representation.
164192
* Then execute the intitialization code. (<clinit>)
165193
*/
166194
Class *load_class(ClassLoader loader, String classname) {
167-
char *filename = filename_from_classname(classname);
168-
ClassFile *class_file = parse_class_file(filename);
169-
free(filename);
170-
171-
if (!class_file) return NULL;
172-
173-
Class *class = Class_from_class_file(class_file);
174-
HashMap_insert(loader.loaded_classes, classname, class);
175-
176-
return class;
177-
}
195+
char *path = find_classfile_in_classpath(loader, classname);
196+
if (!path) {
197+
return NULL;
198+
}
199+
ClassFile *class_file = parse_class_file(path);
200+
free(path);
178201

179-
Class *load_class_from_file(ClassLoader loader, String classname, String filename) {
180-
char *filename_nt = String_to_null_terminated(filename);
181-
ClassFile *class_file = parse_class_file(filename_nt);
182-
free(filename_nt);
183202
if (!class_file) return NULL;
184203

185204
Class *class = Class_from_class_file(class_file);
186-
187205
HashMap_insert(loader.loaded_classes, classname, class);
188206

189207
return class;

src/class_loader.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
typedef struct Class Class;
88

99
typedef struct {
10+
// List of directories. Not owned
11+
char **classpath;
12+
u64 num_paths;
13+
1014
// Map<String, class>
1115
HashMap *loaded_classes;
1216
} ClassLoader;
1317

14-
ClassLoader ClassLoader_create();
18+
ClassLoader ClassLoader_create(char **classpath, u64 num_paths);
1519

1620
Class *load_class(ClassLoader loader, String classname);
17-
Class *load_class_from_file(ClassLoader loader, String classname, String filename);
1821

1922
Class *get_class(ClassLoader loader, String classname);
2023

src/main.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ int main(int argc, char **argv) {
1515
return -1;
1616
}
1717

18+
/*
1819
ClassFile *class_file = parse_class_file(argv[1]);
1920
if (!class_file) {
2021
printf("Failed to parse class file \"%s\"\n", argv[1]);
@@ -44,13 +45,14 @@ int main(int argc, char **argv) {
4445
printf("source file name: \"%.*s\"\n", constant.as.utf8_info.length, constant.as.utf8_info.bytes);
4546
}
4647
}
48+
*/
4749

4850
// method_info fac_info = find_method(class_file, "main", 4);
4951
// code_attribute *code_attr = find_code(class_file, fac_info);
5052
// assert(code_attr != NULL);
51-
execute_main(argv[1]);
53+
// free_class_file(class_file);
5254

53-
free_class_file(class_file);
55+
execute_main(argv[1]);
5456

5557
return 0;
5658
}

src/parse_instructions.c

-103
This file was deleted.

src/runtime.c

+22-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "buffer.h"
44

5+
#include <unistd.h>
56
#include <stdlib.h>
67
#include <stdio.h>
78
#include <string.h>
@@ -60,15 +61,22 @@ void free_frame(Frame frame) {
6061
if (frame.locals) free(frame.locals);
6162
}
6263

63-
void execute_main(char *filename) {
64-
ClassLoader class_loader = ClassLoader_create();
64+
void execute_main(char *class_name) {
65+
char cwd[256];
66+
getcwd(cwd, 256);
67+
ClassLoader class_loader = ClassLoader_create(
68+
(char *[]){ "/home/haschisch/Projects/cl/test", cwd }, 2);
6569

66-
Class *main_class = load_class_from_file(
70+
Class *main_class = load_class(
6771
class_loader,
68-
(String) { .bytes = "Main", .length = 4 },// TODO: Classname
69-
(String) { .bytes = filename, .length = strlen(filename) }
72+
String_from_null_terminated(class_name)
7073
);
7174

75+
if (!main_class) {
76+
fprintf(stderr, "Failed to load class \"%s\"\n", class_name);
77+
return;
78+
}
79+
7280
// call <clinit>
7381
Method *clinit = HashMap_get(
7482
main_class->method_map,
@@ -116,12 +124,20 @@ intern Class *load_class_and_field_name_from_field_ref(
116124
});
117125
if (!class) {
118126
// load and initialize class
119-
load_class(
127+
class = load_class(
120128
class_loader,
121129
(String) {
122130
.bytes = (char *)class_name.as.utf8_info.bytes,
123131
.length = class_name.as.utf8_info.length
124132
});
133+
134+
Method *clinit = HashMap_get(
135+
class->method_map,
136+
(String) {
137+
.bytes = "<clinit>",
138+
.length = strlen("<clinit>")
139+
});
140+
execute(class_loader, clinit);
125141
// TODO: Initialize
126142
}
127143

test/Main.class

23 Bytes
Binary file not shown.

test/Main.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ public static void main(String[] args) {
1111
five();
1212
fac(5);
1313
fib(5);
14+
two();
1415

1516
Main main = new Main();
1617
main.getThree();
1718
}
1819

20+
public static int two() {
21+
return Two.TWO;
22+
}
23+
1924
public static int fac(int n) {
2025
if (n == 0) return 0;
2126

@@ -40,8 +45,4 @@ public static int fib(int i) {
4045
}
4146
return fib(i-1) + fib(i-2);
4247
}
43-
44-
public static void test() {
45-
if (MyField > 10) { return; }
46-
}
4748
}

test/StaticMain.java

-34
This file was deleted.

test/Two.class

262 Bytes
Binary file not shown.

test/Two.java

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Two {
2+
public static int TWO = 2;
3+
}

0 commit comments

Comments
 (0)