bugfix pop order

This commit is contained in:
Shautvast 2023-12-06 14:39:33 +01:00
parent 7b6a01dfda
commit 2149c8d3de
2 changed files with 44 additions and 20 deletions

View file

@ -4,9 +4,10 @@ use crate::vm::object::ObjectRef::*;
use log::debug; use log::debug;
use rand::random; use rand::random;
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{Debug, Formatter, Pointer};
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, Clone)] #[derive(Clone)]
pub enum ObjectRef { pub enum ObjectRef {
ByteArray(Vec<i8>), //maybe use arrays? ByteArray(Vec<i8>), //maybe use arrays?
ShortArray(Vec<i16>), ShortArray(Vec<i16>),
@ -22,6 +23,26 @@ pub enum ObjectRef {
Class(Class), Class(Class),
} }
impl Debug for ObjectRef {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let name = match self {
ByteArray(_) => "[B", //length for arrays
ShortArray(_) => "[S",
IntArray(_) => "[I]",
LongArray(_) => "[J",
FloatArray(_) => "[F",
DoubleArray(_) => "[D]",
BooleanArray(_) => "[Z",
CharArray(_) => "[C",
StringArray(_) => "[Ljava/lang/String]",
ObjectArray(_, _) => "[L",
Object(_) => "L",
Class(_) => "Class",
};
write!(f, "{}", name)
}
}
impl ObjectRef { impl ObjectRef {
pub fn get_array_length(&self) -> usize { pub fn get_array_length(&self) -> usize {
match self { match self {
@ -58,14 +79,14 @@ impl ObjectRef {
pub fn new_array(arraytype: u8, size: usize) -> Self { pub fn new_array(arraytype: u8, size: usize) -> Self {
match arraytype { match arraytype {
8 => ByteArray(vec![0;size]), 8 => ByteArray(vec![0; size]),
9 => ShortArray(vec![0;size]), 9 => ShortArray(vec![0; size]),
10 => IntArray(vec![0;size]), 10 => IntArray(vec![0; size]),
11 => LongArray(vec![0;size]), 11 => LongArray(vec![0; size]),
6 => FloatArray(vec![0.0;size]), 6 => FloatArray(vec![0.0; size]),
7 => DoubleArray(vec![0.0;size]), 7 => DoubleArray(vec![0.0; size]),
4 => BooleanArray(vec![false;size]), 4 => BooleanArray(vec![false; size]),
5 => CharArray(vec![0 as char;size]), 5 => CharArray(vec![0 as char; size]),
_ => unreachable!("impossible array type"), _ => unreachable!("impossible array type"),
} }
} }

View file

@ -6,9 +6,10 @@ use anyhow::Error;
use log::debug; use log::debug;
use crate::class::ClassId; use crate::class::ClassId;
use crate::classloader::classdef::{CpEntry::*, CpEntry, Modifier}; use crate::classloader::classdef::{CpEntry, CpEntry::*, Modifier};
use crate::classloader::io::PATH_SEPARATOR; use crate::classloader::io::PATH_SEPARATOR;
use crate::classmanager::ClassManager; use crate::classmanager::ClassManager;
use crate::value::ComputationalType;
use crate::value::Value::{self, *}; use crate::value::Value::{self, *};
use crate::vm::array::{array_load, array_store}; use crate::vm::array::{array_load, array_store};
use crate::vm::native::invoke_native; use crate::vm::native::invoke_native;
@ -18,7 +19,6 @@ use crate::vm::object::ObjectRef::Object;
use crate::vm::opcodes::Opcode; use crate::vm::opcodes::Opcode;
use crate::vm::opcodes::Opcode::*; use crate::vm::opcodes::Opcode::*;
use std::io::Write; use std::io::Write;
use crate::value::ComputationalType;
const MASK_LOWER_5BITS: i32 = 0b00011111; const MASK_LOWER_5BITS: i32 = 0b00011111;
@ -275,8 +275,8 @@ impl Stackframe {
DUP2_X2 => { DUP2_X2 => {
let value1 = self.pop(); let value1 = self.pop();
let value2 = self.pop(); let value2 = self.pop();
if value1.category_as_u8() == 2 if value1.category_as_u8() == 2 && value2.category_as_u8() == 2 {
&& value2.category_as_u8() == 2 { // Form 4 // Form 4
self.push(value1.clone()); self.push(value1.clone());
self.push(value2); self.push(value2);
self.push(value1); self.push(value1);
@ -284,7 +284,9 @@ impl Stackframe {
let value3 = self.pop(); let value3 = self.pop();
if value1.category_as_u8() == 1 if value1.category_as_u8() == 1
&& value2.category_as_u8() == 1 && value2.category_as_u8() == 1
&& value3.category_as_u8() == 2 { // Form 3 && value3.category_as_u8() == 2
{
// Form 3
self.push(value2.clone()); self.push(value2.clone());
self.push(value1.clone()); self.push(value1.clone());
self.push(value3); self.push(value3);
@ -292,12 +294,14 @@ impl Stackframe {
self.push(value1); self.push(value1);
} else if value1.category_as_u8() == 2 // Form 2 } else if value1.category_as_u8() == 2 // Form 2
&& value2.category_as_u8() == 1 && value2.category_as_u8() == 1
&& value3.category_as_u8() == 1 { && value3.category_as_u8() == 1
{
self.push(value1.clone()); self.push(value1.clone());
self.push(value3); self.push(value3);
self.push(value2); self.push(value2);
self.push(value1); self.push(value1);
} else { // Form 1 } else {
// Form 1
let value4 = self.pop(); let value4 = self.pop();
self.push(value2.clone()); self.push(value2.clone());
self.push(value1.clone()); self.push(value1.clone());
@ -438,13 +442,12 @@ impl Stackframe {
IF_ICMPEQ(jmp_to) | IF_ICMPNE(jmp_to) | IF_ICMPGT(jmp_to) | IF_ICMPGE(jmp_to) IF_ICMPEQ(jmp_to) | IF_ICMPNE(jmp_to) | IF_ICMPGT(jmp_to) | IF_ICMPGE(jmp_to)
| IF_ICMPLT(jmp_to) | IF_ICMPLE(jmp_to) => { | IF_ICMPLT(jmp_to) | IF_ICMPLE(jmp_to) => {
let value1 = self.pop();
let value2 = self.pop(); let value2 = self.pop();
let value1 = self.pop();
if_cmp(&mut self.pc, opcode, jmp_to, &value1, &value2); if_cmp(&mut self.pc, opcode, jmp_to, &value1, &value2);
} }
GOTO(jmp_to) => { GOTO(jmp_to) => {
self.pc += *jmp_to as usize; self.pc += *jmp_to as usize;
// debug!("GOTO {}", *pc)
} }
INVOKEVIRTUAL(c) => { INVOKEVIRTUAL(c) => {
if let Some(invocation) = get_signature_for_invoke(&constant_pool, *c) { if let Some(invocation) = get_signature_for_invoke(&constant_pool, *c) {