More Bytecode and Attributes support

This commit is contained in:
VegOwOtenks 2024-08-29 18:33:03 +02:00
parent 8a79a28b5f
commit b751fc3588
3 changed files with 274 additions and 22 deletions

68
src/bytecode.rs Normal file
View file

@ -0,0 +1,68 @@
use core::fmt::Debug;
use core::fmt;
pub struct Bytecode {
pub code: Box<[u8]>
}
impl Bytecode {
pub fn opcodes(&self) -> Box<[Instruction]> {
let mut v = Vec::with_capacity(self.code.len());
let mut i = 0;
while i < self.code.len() {
let opcode = self.code[i];
let (instruction, offset) = match opcode {
0x12 => (Instruction::LoadConstant(self.code[i+1]), 2),
0x2A => (Instruction::LoadReference0(), 1),
0x2B => (Instruction::LoadReference1(), 1),
0x2C => (Instruction::LoadReference2(), 1),
0x2D => (Instruction::LoadReference3(), 1),
0x59 => (Instruction::Duplicate(), 1),
0xB0 => (Instruction::ReturnReference(), 1),
0xB1 => (Instruction::ReturnVoid(), 1),
0xB2 => (Instruction::GetStatic(self.code[i+1], self.code[i+2]), 3),
0xB4 => (Instruction::GetField(self.code[i+1], self.code[i+2]), 3),
0xB5 => (Instruction::PutField(self.code[i+1], self.code[i+2]), 3),
0xB6 => (Instruction::InvokeVirtual(self.code[i+1], self.code[i+2]), 3),
0xB7 => (Instruction::InvokeSpecial(self.code[i+1], self.code[i+2]), 3),
0xBB => (Instruction::NewObject(self.code[i+1], self.code[i+2]), 3),
_ => (Instruction::Unknown(opcode), 1)
};
v.push(instruction);
i += offset;
}
v.into_boxed_slice()
}
}
impl Debug for Bytecode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
f.debug_list()
.entries(self.opcodes())
.finish()
}
}
#[derive(Debug)]
#[repr(u8)]
pub enum Instruction {
LoadConstant(u8) = 0x12, // Push from constant pool
LoadReference0() = 0x2A, // Load local variable reference onto stack
LoadReference1() = 0x2B, // Load local variable reference onto stack
LoadReference2() = 0x2C, // Load local variable reference onto stack
LoadReference3() = 0x2D, // Load local variable reference onto stack
Duplicate() = 0x59, // duplicate top stack value
ReturnReference() = 0xB0, // return top-ref from current function
ReturnVoid() = 0xB1, // return void from function
GetStatic(u8, u8) = 0xB2, // get static field from class
GetField(u8, u8) = 0xB4, // get field from class
PutField(u8, u8) = 0xB5, // set field to a value
InvokeVirtual(u8, u8) = 0xB6, // invoke function on a class
InvokeSpecial(u8, u8) = 0xB7, // invoke instance method
NewObject(u8, u8) = 0xBB, // Create a new object from a constant-pool reference
Unknown(u8),
}