Type correction and opcode implementations

This commit is contained in:
vegowotenks 2024-09-10 17:15:20 +02:00
parent c6e4ecec3d
commit b053461e74
5 changed files with 307 additions and 148 deletions

View file

@ -25,12 +25,16 @@ impl Bytecode {
0x0E => (Instruction::PushConstDouble0(), 1),
0x0F => (Instruction::PushConstDouble1(), 1),
0x10 => (Instruction::LoadByteImmediate(self.bytes[offset+1]), 2),
0x11 => (Instruction::LoadShortImmediate((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0x10 => (Instruction::LoadByteImmediate(i8::from_be_bytes([self.bytes[offset+1]])), 2),
0x11 => {
let bytes = [self.bytes[offset+1], self.bytes[offset+2]];
(Instruction::LoadShortImmediate(i16::from_be_bytes(bytes)), 3)
}
0x12 => (Instruction::LoadConstant(self.bytes[offset+1]), 2),
0x13 => (Instruction::LoadCostantWide((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0x14 => (Instruction::LoadConstant64((self.bytes[offset+1] as u16) << 8 | self.bytes[offset+2] as u16), 3),
0x19 => (Instruction::LoadLocalReference(self.bytes[offset+1]), 2),
0x1A => (Instruction::LoadLocalInt0(), 1),
0x1B => (Instruction::LoadLocalInt1(), 1),
0x1C => (Instruction::LoadLocalInt2(), 1),
@ -51,17 +55,19 @@ impl Bytecode {
0x32 => (Instruction::ArrayElement(), 1),
0x33 => (Instruction::LoadFromBArray(), 1),
0x36 => (Instruction::StoreLocalInt(self.bytes[offset+1]), 2),
0x3A => (Instruction::StoreLocalReference(self.bytes[offset+1]), 2),
0x3B => (Instruction::StoreLocalInt0(), 1),
0x3C => (Instruction::StoreLocalInt1(), 1),
0x3D => (Instruction::StoreLocalInt2(), 1),
0x3E => (Instruction::StoreLocalInt3(), 1),
0x4B => (Instruction::StoreReference0(), 1),
0x4C => (Instruction::StoreReference1(), 1),
0x4D => (Instruction::StoreReference2(), 1),
0x4E => (Instruction::StoreReference3(), 1),
0x4B => (Instruction::StoreLocalReference0(), 1),
0x4C => (Instruction::StoreLocalReference1(), 1),
0x4D => (Instruction::StoreLocalReference2(), 1),
0x4E => (Instruction::StoreLocalReference3(), 1),
0x53 => (Instruction::StoreIntoRArray(), 1),
0x54 => (Instruction::StoreIntoBArray(), 1),
0x55 => (Instruction::StoreIntoCArray(), 1),
0x57 => (Instruction::Pop(), 1),
0x59 => (Instruction::Duplicate(), 1),
@ -72,7 +78,8 @@ impl Bytecode {
0x6C => (Instruction::DivideInt(), 1),
0x6D => (Instruction::DivideLong(), 1),
0x7A => (Instruction::ShiftIntRight(), 1),
0x7A => (Instruction::ArithmeticShiftIntRight(), 1),
0x7C => (Instruction::LogicalShiftIntRight(), 1),
0x80 => (Instruction::OrInt(), 1),
0x84 => (Instruction::IncrementLocalInt(self.bytes[offset+1], i8::from_be_bytes([self.bytes[offset+2]])), 3),
@ -136,13 +143,31 @@ impl Bytecode {
let bytes = [self.bytes[offset+1], self.bytes[offset+2]];
(Instruction::BranchReferenceInequality(i16::from_be_bytes(bytes)), 3)
}
0xAC => (Instruction::ReturnInt(), 1),
0xA7 => {
let bytes = [self.bytes[offset+1], self.bytes[offset+2]];
(Instruction::BranchAlways(i16::from_be_bytes(bytes)), 3)
}
0xAB => {
let padding = 4 - (offset % 4) - 1;
let default_bytes = [self.bytes[offset+padding+1], self.bytes[offset+padding+2], self.bytes[offset+padding+3], self.bytes[offset+padding+4]];
let default = i32::from_be_bytes(default_bytes);
let npairs_bytes = [self.bytes[offset+padding+5], self.bytes[offset+padding+6], self.bytes[offset+padding+7], self.bytes[offset+padding+8]];
let npairs = i32::from_be_bytes(npairs_bytes);
let mut pairs_vec = Vec::with_capacity(npairs as usize);
for i in 0..npairs as usize {
let match_bytes = [self.bytes[offset+padding+8*(1+i)+1], self.bytes[offset+padding+8*(1+i)+2], self.bytes[offset+padding+8*(1+i)+3], self.bytes[offset+padding+8*(1+i)+4]];
let offset_bytes = [self.bytes[offset+padding+8*(1+i)+5], self.bytes[offset+padding+8*(1+i)+6], self.bytes[offset+padding+8*(1+i)+7], self.bytes[offset+padding+8*(1+i)+8]];
pairs_vec.push((i32::from_be_bytes(match_bytes), i32::from_be_bytes(offset_bytes)));
}
(Instruction::LookupSwitch(default, pairs_vec.into()), 1 + padding + 4 + 4 + npairs as usize * 8)
}
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),
@ -202,115 +227,120 @@ impl Debug for Bytecode {
#[derive(Debug)]
#[repr(u8)]
pub enum Instruction {
NoOperation() = 0x00, // No-Operation
PushNull() = 0x01, // ..., arrayref, index, value
PushConstIntM1() = 0x02, // Push -1
PushConstInt0() = 0x03, // Push 0
PushConstInt1() = 0x04, // Push 1
PushConstInt2() = 0x05, // Push 2
PushConstInt3() = 0x06, // Push 3
PushConstInt4() = 0x07, // Push 4
PushConstInt5() = 0x08, // Push 5
PushConstFloat0() = 0x0B, // Push 0.0f
PushConstFloat1() = 0x0C, // Push 1.0f
PushConstFloat2() = 0x0D, // Push 2.0f
PushConstDouble0() = 0x0E, // Push 0.0
PushConstDouble1() = 0x0F, // Push 1.0
NoOperation() = 0x00, // No-Operation
PushNull() = 0x01, // ..., arrayref, index, value
PushConstIntM1() = 0x02, // Push -1
PushConstInt0() = 0x03, // Push 0
PushConstInt1() = 0x04, // Push 1
PushConstInt2() = 0x05, // Push 2
PushConstInt3() = 0x06, // Push 3
PushConstInt4() = 0x07, // Push 4
PushConstInt5() = 0x08, // Push 5
PushConstFloat0() = 0x0B, // Push 0.0f
PushConstFloat1() = 0x0C, // Push 1.0f
PushConstFloat2() = 0x0D, // Push 2.0f
PushConstDouble0() = 0x0E, // Push 0.0
PushConstDouble1() = 0x0F, // Push 1.0
LoadByteImmediate(u8) = 0x10, // push immediate short
LoadShortImmediate(u16) = 0x11, // push immediate short
LoadConstant(u8) = 0x12, // Push from constant pool
LoadCostantWide(u16) = 0x13, // Push from constant pool with wide index, don't load
// double or long or whatever
LoadConstant64(u16) = 0x14, // Push Long or Double from constant pool
LoadLocalInt0() = 0x1A, // Load int from local variable
LoadLocalInt1() = 0x1B, // Load int from local variable
LoadLocalInt2() = 0x1C, // Load int from local variable
LoadLocalInt3() = 0x1D, // Load int from local variable
LoadByteImmediate(i8) = 0x10, // push immediate short
LoadShortImmediate(i16) = 0x11, // push immediate short
LoadConstant(u8) = 0x12, // Push from constant pool
LoadCostantWide(u16) = 0x13, // Push from constant pool with wide index, don't load
// double or long or whatever
LoadConstant64(u16) = 0x14, // Push Long or Double from constant pool
LoadLocalReference(u8) = 0x19, // Load reference from indexed local variable
LoadLocalInt0() = 0x1A, // Load int from local variable
LoadLocalInt1() = 0x1B, // Load int from local variable
LoadLocalInt2() = 0x1C, // Load int from local variable
LoadLocalInt3() = 0x1D, // Load int from local variable
LoadLocalFloat0() = 0x22, // Load local double variable reference onto stack
LoadLocalFloat1() = 0x23, // Load local double variable reference onto stack
LoadLocalFloat2() = 0x24, // Load local double variable reference onto stack
LoadLocalFloat3() = 0x25, // Load local double variable reference onto stack
LoadLocalDouble0() = 0x26, // Load local double variable reference onto stack
LoadLocalDouble1() = 0x27, // Load local double variable reference onto stack
LoadLocalDouble2() = 0x28, // Load local double variable reference onto stack
LoadLocalDouble3() = 0x29, // Load local double variable reference onto stack
LoadLocalReference0() = 0x2A, // Load local reference variable reference onto stack
LoadLocalReference1() = 0x2B, // Load local reference variable reference onto stack
LoadLocalReference2() = 0x2C, // Load local reference variable reference onto stack
LoadLocalReference3() = 0x2D, // Load local reference variable reference onto stack
LoadLocalFloat0() = 0x22, // Load local double variable reference onto stack
LoadLocalFloat1() = 0x23, // Load local double variable reference onto stack
LoadLocalFloat2() = 0x24, // Load local double variable reference onto stack
LoadLocalFloat3() = 0x25, // Load local double variable reference onto stack
LoadLocalDouble0() = 0x26, // Load local double variable reference onto stack
LoadLocalDouble1() = 0x27, // Load local double variable reference onto stack
LoadLocalDouble2() = 0x28, // Load local double variable reference onto stack
LoadLocalDouble3() = 0x29, // Load local double variable reference onto stack
LoadLocalReference0() = 0x2A, // Load local reference variable reference onto stack
LoadLocalReference1() = 0x2B, // Load local reference variable reference onto stack
LoadLocalReference2() = 0x2C, // Load local reference variable reference onto stack
LoadLocalReference3() = 0x2D, // Load local reference variable reference onto stack
ArrayElement() = 0x32, // load element from array
LoadFromBArray() = 0x33, // store into byte array
StoreLocalInt(u8) = 0x36, // store into indexed local variable
StoreLocalInt0() = 0x3B, // store int into local variable
StoreLocalInt1() = 0x3C, // store int into local variable
StoreLocalInt2() = 0x3D, // store int into local variable
StoreLocalInt3() = 0x3E, // store int into local variable
StoreReference0() = 0x4B, // store reference into local variable
StoreReference1() = 0x4C, // store reference into local variable
StoreReference2() = 0x4D, // store reference into local variable
StoreReference3() = 0x4E, // store reference into local variable
ArrayElement() = 0x32, // load element from array
LoadFromBArray() = 0x33, // store into byte array
StoreLocalInt(u8) = 0x36, // store into indexed local variable
StoreLocalReference(u8) = 0x3A, // store into indexed local variable
StoreLocalInt0() = 0x3B, // store int into local variable
StoreLocalInt1() = 0x3C, // store int into local variable
StoreLocalInt2() = 0x3D, // store int into local variable
StoreLocalInt3() = 0x3E, // store int into local variable
StoreLocalReference0() = 0x4B, // store reference into local variable
StoreLocalReference1() = 0x4C, // store reference into local variable
StoreLocalReference2() = 0x4D, // store reference into local variable
StoreLocalReference3() = 0x4E, // store reference into local variable
StoreIntoRArray() = 0x53, // store value into reference array
StoreIntoBArray() = 0x54, // store value into byte or boolean array
Pop() = 0x57, // Pop top stack value
Duplicate() = 0x59, // duplicate top stack value
StoreIntoRArray() = 0x53, // store value into reference array
StoreIntoBArray() = 0x54, // store value into byte or boolean array
StoreIntoCArray() = 0x55, // store value into char array
Pop() = 0x57, // Pop top stack value
Duplicate() = 0x59, // duplicate top stack value
AddInt() = 0x60, // int addition
SubtractInt() = 0x64, // int subtraction
MultiplyInt() = 0x68, // int multiplication
DivideInt() = 0x6C, // integer division, round toward zero and more rules
DivideLong() = 0x6D, // long division
AddInt() = 0x60, // int addition
SubtractInt() = 0x64, // int subtraction
MultiplyInt() = 0x68, // int multiplication
DivideInt() = 0x6C, // integer division, round toward zero and more rules
DivideLong() = 0x6D, // long division
ShiftIntRight() = 0x7a, // shift int
ArithmeticShiftIntRight() = 0x7A, // shift int
LogicalShiftIntRight() = 0x7C, // shift int right with zero extension
OrInt() = 0x80, // value, value => or
IncrementLocalInt(u8, i8) = 0x84, // increment local variable by constant i8
OrInt() = 0x80, // value, value => or
IncrementLocalInt(u8, i8) = 0x84, // increment local variable by constant i8
CompareFloatL() = 0x95, // compare float, push -1 if one is NaN
CompareFloatG() = 0x96, // compare float, push 1 if one is NaN
BranchZero(i16) = 0x99, // branch if value == 0
BranchNonZero(i16) = 0x9A, // branch if value != 0
BranchNegative(i16) = 0x9B, // branch if value < 0
BranchNonNegative(i16) = 0x9C, // branch if value <= 0
BranchPositive(i16) = 0x9D, // branch if value > 0
BranchNonPositive(i16) = 0x9E, // branch if value >= 0
CompareFloatL() = 0x95, // compare float, push -1 if one is NaN
CompareFloatG() = 0x96, // compare float, push 1 if one is NaN
BranchZero(i16) = 0x99, // branch if value == 0
BranchNonZero(i16) = 0x9A, // branch if value != 0
BranchNegative(i16) = 0x9B, // branch if value < 0
BranchNonNegative(i16) = 0x9C, // branch if value <= 0
BranchPositive(i16) = 0x9D, // branch if value > 0
BranchNonPositive(i16) = 0x9E, // branch if value >= 0
BranchIntEquality(i16) = 0x9F,
BranchIntInequality(i16) = 0xA0,
BranchIntLessThan(i16) = 0xA1,
BranchIntGreaterEquals(i16) = 0xA2,
BranchIntGreaterThan(i16) = 0xA3,
BranchIntLessEquals(i16) = 0xA4,
BranchReferenceEquality(i16) = 0xA5,
BranchReferenceInequality(i16) = 0xA6,
BranchIntEquality(i16) = 0x9F,
BranchIntInequality(i16) = 0xA0,
BranchIntLessThan(i16) = 0xA1,
BranchIntGreaterEquals(i16) = 0xA2,
BranchIntGreaterThan(i16) = 0xA3,
BranchIntLessEquals(i16) = 0xA4,
BranchReferenceEquality(i16) = 0xA5,
BranchReferenceInequality(i16) = 0xA6,
BranchAlways(i16) = 0xA7, // branch if true
ReturnInt() = 0xAC, // return integer from function
BranchAlways(i16) = 0xA7, // branch if true
LookupSwitch(i32, Box<[(i32, i32)]>) = 0xAB, // offset based on switch value
ReturnInt() = 0xAC, // return integer from function
ReturnReference() = 0xB0, // return top-ref from current function
ReturnVoid() = 0xB1, // return void from function
GetStatic(u16) = 0xB2, // get static field from class
PutStatic(u16) = 0xB3, // set static field on class
GetField(u16) = 0xB4, // get field from class
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 class reference
NewPrimitiveArray(u8) = 0xBC, // make a primitive array
NewArray(u16) = 0xBD, // Create a new array from a constant-pool component class reference
ArrayLength() = 0xBE, // Get length from array reference
ReturnReference() = 0xB0, // return top-ref from current function
ReturnVoid() = 0xB1, // return void from function
GetStatic(u16) = 0xB2, // get static field from class
PutStatic(u16) = 0xB3, // set static field on class
GetField(u16) = 0xB4, // get field from class
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 class reference
NewPrimitiveArray(u8) = 0xBC, // make a primitive array
NewArray(u16) = 0xBD, // Create a new array from a constant-pool component class reference
ArrayLength() = 0xBE, // Get length from array reference
CheckCast(u16) = 0xC0, // throw exception on fail
InstanceOf(u16) = 0xC1, // push integer result for success
EnterMonitor() = 0xC2, // enter the synchronization monitor of an object
ExitMonitor() = 0xC3, // exit the synchronization monitor of an object
BranchNull(i16) = 0xC6, // branch if Null
BranchNonNull(i16) = 0xC7, // branch if Null
CheckCast(u16) = 0xC0, // throw exception on fail
InstanceOf(u16) = 0xC1, // push integer result for success
EnterMonitor() = 0xC2, // enter the synchronization monitor of an object
ExitMonitor() = 0xC3, // exit the synchronization monitor of an object
BranchNull(i16) = 0xC6, // branch if Null
BranchNonNull(i16) = 0xC7, // branch if Null
Unknown(u8),
}