stdout und stderr encoding

This commit is contained in:
vegowotenks 2024-10-22 13:01:20 +02:00
parent 022bfe9ee6
commit b4c33a0d9b
4 changed files with 116 additions and 6 deletions

View file

@ -667,7 +667,9 @@ impl JVM {
let (instruction, offset) = bytecode.next_instruction(frame.instruction_pointer as usize);
frame.instruction_pointer += offset as u32;
println!("{}{:25}.{:15}:{:<10}{instruction:?}", " ".repeat(frame_index), class.get_classname().unwrap(), method.name, frame.instruction_pointer);
//println!("{} locals: {:?}", " ".repeat(frame_index), frame.locals);
println!("{} stack: {:?}", " ".repeat(frame_index), frame.operand_stack);
println!("{}{:25}.{:15}:{:<10}{instruction:?}\n", " ".repeat(frame_index), class.get_classname().unwrap(), method.name, frame.instruction_pointer);
match instruction {
@ -835,6 +837,16 @@ impl JVM {
}
}
Instruction::BranchReferenceEquality(branch_offset) => {
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
if value_1 == value_2 {
frame.instruction_pointer -= offset as u32;
frame.instruction_pointer = if branch_offset < 0 { frame.instruction_pointer - branch_offset.abs() as u32} else { frame.instruction_pointer + branch_offset.abs() as u32};
}
}
Instruction::BranchReferenceInequality(branch_offset) => {
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
@ -914,6 +926,17 @@ impl JVM {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(comparison_result)))?;
}
Instruction::ConvertFloatToInt() => {
let float = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let int_value = match float {
f32::INFINITY => i32::MAX,
f32::NEG_INFINITY => i32::MIN,
v @ _ => if v.is_nan() { 0 } else { v as i32 } ,
};
frame.operand_stack.push(StackValue::Int(int_value)).unwrap();
}
Instruction::ConvertIntToChar() => {
let int_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
let char_value = int_value & 0x0000FFFF;
@ -921,6 +944,13 @@ impl JVM {
frame.operand_stack.push(StackValue::Int(char_value)).unwrap();
}
Instruction::ConvertIntToFloat() => {
let int_value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
let float_value = int_value as f32;
frame.operand_stack.push(StackValue::Float(float_value)).unwrap();
}
Instruction::DivideInt() => {
// TODO: Obey all the rules
let quotient = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
@ -935,6 +965,15 @@ impl JVM {
wrap_stackframe_error(class, method, frame.operand_stack.push(popped_value))?;
}
Instruction::DuplicateInsertDown() => {
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_computational_1(0))?;
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_computational_1(0))?;
wrap_stackframe_error(class, method, frame.operand_stack.push(value_1))?;
wrap_stackframe_error(class, method, frame.operand_stack.push(value_2))?;
wrap_stackframe_error(class, method, frame.operand_stack.push(value_1))?;
}
Instruction::EnterMonitor() => {
// TODO: Revisit this when doing multi-threading
let _monitored_object = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
@ -1410,6 +1449,9 @@ impl JVM {
}
}
Instruction::LoadLocalFloat(index) => {
load_local_float(class, method, frame, index as usize)?;
}
Instruction::LoadLocalFloat0() => {
load_local_float(class, method, frame, 0)?;
}
@ -1476,10 +1518,28 @@ impl JVM {
frame.instruction_pointer = if jump_offset < 0 { frame.instruction_pointer - jump_offset.abs() as u32} else { frame.instruction_pointer + jump_offset.abs() as u32};
}
Instruction::MultiplyFloat() => {
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
let result = factor_1 * factor_2;
let java_result = result;
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Float(java_result)))?;
}
Instruction::MultiplyInt() => {
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(factor_1 * factor_2)))?;
let (result, overflowed) = i32::overflowing_mul(factor_1, factor_2);
let java_result = match (overflowed, factor_1, factor_2) {
(true, 0..=i32::MAX, 0..=i32::MAX) => if result > 0 { -result } else { result },
(true, 0..=i32::MAX, i32::MIN..0) | (true, i32::MIN..0, 0..=i32::MAX) => if result < 0 { -result } else { result },
(true, i32::MIN..0, i32::MIN..0) => if result > 0 { - result } else { result },
(false, _, _) => result,
};
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(java_result)))?;
}
Instruction::NewArray(component_class_index) => {
@ -1799,6 +1859,12 @@ impl JVM {
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_1 - value_2)))?;
}
Instruction::StoreLocalFloat(index) => {
let float = wrap_stackframe_error(class, method, frame.operand_stack.pop_float(0))?;
wrap_stackframe_error(class, method, frame.store_local(index as u16, StackValue::Float(float)))?;
}
Instruction::StoreLocalInt(index) => {
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
@ -2038,7 +2104,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
},
AbstractTypeKind::Boolean() => {
arguments.push_front(
StackValue::Boolean(
StackValue::Int(
wrap_stackframe_error(
class,
method,