-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVirtualMachine.java
More file actions
104 lines (86 loc) · 2.77 KB
/
VirtualMachine.java
File metadata and controls
104 lines (86 loc) · 2.77 KB
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
104
/*
*
* CS365 Project 2
*
* Contributors: Alex Teepe, Brandon Yen, Austin Saporito, Austin Day, and Charles Rizzo
*
* Entry point for jar file that creates a virtual machine to interpret byte code generated from project 1.
* Can be ran in Verbose mode with -v as second command line arg.
*/
import java.io.*;
import java.util.*;
public class VirtualMachine extends ByteCode {
//Constructs a VirtualMachine object with 4096 bytes of memory
public VirtualMachine() {
size = 1024;
memory = new int[size];
sp = size - 1;
ip = 0;
}
//Constructs a VirtualMachine object with user specified amount bytes of memory
public VirtualMachine(int sizeInBytes) {
size = sizeInBytes/4;
memory = new int[size];
sp = size - 1;
ip = 0;
}
//Reads throught bytecode file; Checks to make sure file starts with 0xfeedbeef; Inserts all commands into an ArrayList that is converted into an Array
public void readFile(String filename) {
DataInputStream r;
int fromFile, fileHeaderCheck;
ArrayList <Integer> instrs = new ArrayList <Integer>();
try{
r = new DataInputStream(new FileInputStream(filename));
}catch(IOException ex){
System.err.println("Unable to open file " + filename);
return;
}
fileHeaderCheck = 1;
do{
try{
fromFile = r.readInt();
}catch(IOException ex){
break;
}
if((fileHeaderCheck == 1) && (fromFile != 0xfeedbeef)){
System.err.println("Bin file does not start with magic header.");
return;
}else if(fileHeaderCheck == 0){
instrs.add(swap(fromFile));
}
fileHeaderCheck = 0;
}while(true);
try{ r.close(); } catch(IOException ex){}
int []instructions = instrs.stream().mapToInt(Integer::intValue).toArray();
this.loadInstructions(instructions);
}
//Runs the virtual machine
public int run() {
jump(0);
try {
return execLoop();
} catch (Exception e) {
System.err.println("Erroroneous instruction, terminating program: " + e.toString());
return -1;
}
}
//Major loop body of the virtual machine that calls Interpret() in ByteCode.java to interpret and run each command.
public int execLoop() {
int ipp = this.ip;
while(interpret() != -1) {
if (ipp == this.ip) {
this.ip++;
}
ipp = this.ip;
}
return this.exitCode;
}
//Used to swap byte endianness because Java and C# don't like each other
public int swap (int value){
int b1 = (value >> 0) & 0xff;
int b2 = (value >> 8) & 0xff;
int b3 = (value >> 16) & 0xff;
int b4 = (value >> 24) & 0xff;
return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
}
}