Entrypoint call entry methodgit add .

This commit is contained in:
VegOwOtenks 2024-09-02 11:28:00 +02:00
parent ea3666aad3
commit 2042007242
9 changed files with 573 additions and 119 deletions

View file

@ -1,71 +1,78 @@
use core::fmt::Debug;
pub struct Bytecode {
pub code: Box<[u8]>
pub bytes: Box<[u8]>
}
impl Bytecode {
pub fn opcodes(&self) -> Box<[Instruction]> {
let mut v = Vec::with_capacity(self.code.len());
pub fn next_instruction(&self, offset: usize) -> (Instruction, usize) {
let opcode = self.bytes[offset];
match opcode {
0x00 => (Instruction::NoOperation(), 1),
0x01 => (Instruction::StoreIntoIntArray(), 1),
0x02 => (Instruction::PushConstIntM1(), 1),
0x03 => (Instruction::PushConstInt0(), 1),
0x04 => (Instruction::PushConstInt1(), 1),
0x05 => (Instruction::PushConstInt2(), 1),
0x06 => (Instruction::PushConstInt3(), 1),
0x07 => (Instruction::PushConstInt4(), 1),
0x08 => (Instruction::PushConstInt5(), 1),
0x0E => (Instruction::PushConstDouble0(), 1),
0x0F => (Instruction::PushConstDouble1(), 1),
0x11 => (Instruction::LoadShortImmediate((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0x12 => (Instruction::LoadConstant(self.bytes[offset+1]), 2),
0x14 => (Instruction::LoadConstant64((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0x26 => (Instruction::LoadDouble0(), 1),
0x27 => (Instruction::LoadDouble1(), 1),
0x28 => (Instruction::LoadDouble2(), 1),
0x29 => (Instruction::LoadDouble3(), 1),
0x2A => (Instruction::LoadReference0(), 1),
0x2B => (Instruction::LoadReference1(), 1),
0x2C => (Instruction::LoadReference2(), 1),
0x2D => (Instruction::LoadReference3(), 1),
0x4B => (Instruction::StoreReference0(), 1),
0x4C => (Instruction::StoreReference1(), 1),
0x4D => (Instruction::StoreReference2(), 1),
0x4E => (Instruction::StoreReference3(), 1),
0x57 => (Instruction::Pop(), 1),
0x59 => (Instruction::Duplicate(), 1),
0x6D => (Instruction::DivideLong(), 1),
0x7A => (Instruction::ShiftIntRight(), 1),
0x80 => (Instruction::OrInt(), 1),
0xAC => (Instruction::ReturnInt(), 1),
0xB0 => (Instruction::ReturnReference(), 1),
0xB1 => (Instruction::ReturnVoid(), 1),
0xB2 => (Instruction::GetStatic((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xB3 => (Instruction::PutStatic((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xB4 => (Instruction::GetField((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xB5 => (Instruction::PutField((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xB6 => (Instruction::InvokeVirtual((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xB7 => (Instruction::InvokeSpecial((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xB8 => (Instruction::InvokeStatic((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0xBA => (Instruction::InvokeDynamic((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16, (self.bytes[offset+3] as u16) << 8 | self.bytes[offset+4] as u16), 5),
0xBB => (Instruction::NewObject((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
_ => (Instruction::Unknown(opcode), 1)
}
}
pub fn instructions(&self) -> Box<[Instruction]> {
let mut v = Vec::with_capacity(self.bytes.len());
let mut i = 0;
while i < self.code.len() {
let opcode = self.code[i];
while i < self.bytes.len() {
let (instruction, offset) = match opcode {
0x00 => (Instruction::NoOperation(), 1),
0x01 => (Instruction::StoreIntoIntArray(), 1),
0x02 => (Instruction::PushConstIntM1(), 1),
0x03 => (Instruction::PushConstInt0(), 1),
0x04 => (Instruction::PushConstInt1(), 1),
0x05 => (Instruction::PushConstInt2(), 1),
0x06 => (Instruction::PushConstInt3(), 1),
0x07 => (Instruction::PushConstInt4(), 1),
0x08 => (Instruction::PushConstInt5(), 1),
0x0E => (Instruction::PushConstDouble0(), 1),
0x0F => (Instruction::PushConstDouble1(), 1),
0x11 => (Instruction::LoadShortImmediate((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0x12 => (Instruction::LoadConstant(self.code[i+1]), 2),
0x14 => (Instruction::LoadConstant64((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0x26 => (Instruction::LoadDouble0(), 1),
0x27 => (Instruction::LoadDouble1(), 1),
0x28 => (Instruction::LoadDouble2(), 1),
0x29 => (Instruction::LoadDouble3(), 1),
0x2A => (Instruction::LoadReference0(), 1),
0x2B => (Instruction::LoadReference1(), 1),
0x2C => (Instruction::LoadReference2(), 1),
0x2D => (Instruction::LoadReference3(), 1),
0x4B => (Instruction::StoreReference0(), 1),
0x4C => (Instruction::StoreReference1(), 1),
0x4D => (Instruction::StoreReference2(), 1),
0x4E => (Instruction::StoreReference3(), 1),
0x57 => (Instruction::Pop(), 1),
0x59 => (Instruction::Duplicate(), 1),
0x6D => (Instruction::DivideLong(), 1),
0x7A => (Instruction::ShiftIntRight(), 1),
0x80 => (Instruction::OrInt(), 1),
0xAC => (Instruction::ReturnInt(), 1),
0xB0 => (Instruction::ReturnReference(), 1),
0xB1 => (Instruction::ReturnVoid(), 1),
0xB2 => (Instruction::GetStatic((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0xB3 => (Instruction::PutStatic((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0xB4 => (Instruction::GetField((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0xB5 => (Instruction::PutField((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0xB6 => (Instruction::InvokeVirtual((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0xB7 => (Instruction::InvokeSpecial((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
0xBA => (Instruction::InvokeDynamic((self.code[i+1] as u16) << 8 | self.code[i+2] as u16, (self.code[i+3] as u16) << 8 | self.code[i+4] as u16), 5),
0xBB => (Instruction::NewObject((self.code[i+1] as u16) << 8 | self.code[i+2] as u16), 3),
_ => (Instruction::Unknown(opcode), 1)
};
let (instruction, offset) = self.next_instruction(i);
v.push(instruction);
i += offset;
@ -78,7 +85,7 @@ impl Bytecode {
impl Debug for Bytecode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
f.debug_list()
.entries(self.opcodes())
.entries(self.instructions())
.finish()
}
}
@ -135,6 +142,7 @@ pub enum Instruction {
PutField(u16) = 0xB5, // set field to a value
InvokeVirtual(u16) = 0xB6, // invoke function on a class
InvokeSpecial(u16) = 0xB7, // invoke instance method
InvokeStatic(u16) = 0xB8, // invoke static function
InvokeDynamic(u16, u16) = 0xBA, // invoke dynamic function
NewObject(u16) = 0xBB, // Create a new object from a constant-pool reference
Unknown(u8),