bugfix pop order
This commit is contained in:
parent
7b6a01dfda
commit
2149c8d3de
2 changed files with 44 additions and 20 deletions
|
|
@ -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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
@ -511,7 +514,7 @@ impl Stackframe {
|
||||||
invocation.method.name.as_str(),
|
invocation.method.name.as_str(),
|
||||||
args,
|
args,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
// TODO remove unwrap in line above, error handling
|
// TODO remove unwrap in line above, error handling
|
||||||
} else {
|
} else {
|
||||||
let mut new_stackframe = Stackframe::new(args);
|
let mut new_stackframe = Stackframe::new(args);
|
||||||
|
|
@ -556,7 +559,7 @@ impl Stackframe {
|
||||||
invocation.method.name.as_str(),
|
invocation.method.name.as_str(),
|
||||||
args,
|
args,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
// TODO remove unwrap in line above, error handling
|
// TODO remove unwrap in line above, error handling
|
||||||
} else {
|
} else {
|
||||||
let mut new_stackframe = Stackframe::new(args);
|
let mut new_stackframe = Stackframe::new(args);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue