Just like my other project the Rust JVM, I'm making a JVM in Zig to learn the language.
I will also utilize this opportunity to improve on my old design. I'll admit that the Rust version wasn't very "Rusty" and could've been solved in a much better way.
Current Java Code:
public class Main {
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = a + b;
Main.println("Hello World, from Java!");
Main.println(c);
}
public static native void exit(int status);
public static native void println(int status);
public static native void println(String text);
}pub fn main() !void {
// **create memory allocators etc**
// Load the main class file
const mainClass = try loadClassFile("Main.class", arena.allocator());
// Create a new jvm
var vm = VirtualMachine().init(arena.allocator());
defer vm.deinit();
// Load the natives "<class>.<function_name>"
const main_naitves = @import("./natives/Main.zig");
try vm.addNative("Main.println", &main_naitves.println);
try vm.addNative("Main.exit", &main_naitves.exit);
// add the main class to the jvm
try vm.addClass(mainClass);
// Run the jvm
try vm.run();
}Output of the above program:
Hello World, from Java!
3
The class parser with the code above produces:
Magic: 0xCAFEBABE
Version: 67.0
This Class: #12 'Main'
Super Class: #4 'java/lang/Object'
Constant Pool(24):
#1: MethodRef: #2.#3 'java/lang/Object.<init>:()V'
#2: Class: #4 'java/lang/Object'
#3: NameAndType: #5.#6 '<init>:()V'
#4: Utf8: 'java/lang/Object'
#5: Utf8: '<init>'
#6: Utf8: '()V'
#7: String: #8 'Hello World, from Java!'
#8: Utf8: 'Hello World, from Java!'
#9: MethodRef: #10.#11 'Main.println:(Ljava/lang/String;)V'
#10: Class: #12 'Main'
#11: NameAndType: #13.#14 'println:(Ljava/lang/String;)V'
#12: Utf8: 'Main'
#13: Utf8: 'println'
#14: Utf8: '(Ljava/lang/String;)V'
#15: MethodRef: #10.#16 'Main.println:(I)V'
#16: NameAndType: #13.#17 'println:(I)V'
#17: Utf8: '(I)V'
#18: Utf8: 'Code'
#19: Utf8: 'LineNumberTable'
#20: Utf8: 'main'
#21: Utf8: '([Ljava/lang/String;)V'
#22: Utf8: 'exit'
#23: Utf8: 'SourceFile'
#24: Utf8: 'Main.java'
Methods(5):
#1: <init>:()V
Code
Max Stack: 1
Max Locals: 1
Code Length: 3
Instructions:
0: aload_0
1: invokespecial #1
2: return
#2: main:([Ljava/lang/String;)V
Code
Max Stack: 2
Max Locals: 4
Code Length: 13
Instructions:
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: ldc #7
9: invokestatic #9
10: iload_3
11: invokestatic #15
12: return
#3: exit:(I)V
#4: println:(I)V
#5: println:(Ljava/lang/String;)V