local params and first part of array stores
This commit is contained in:
parent
6feebec373
commit
a0823788d8
3 changed files with 103 additions and 71 deletions
|
|
@ -256,9 +256,8 @@ impl MethodCode {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Void,
|
Void, // variant returned for void methods
|
||||||
Null,
|
Null, // 'pointer' to nothing
|
||||||
// the $1_000_000 mistake
|
|
||||||
I32(i32),
|
I32(i32),
|
||||||
I64(i64),
|
I64(i64),
|
||||||
F32(f32),
|
F32(f32),
|
||||||
|
|
|
||||||
|
|
@ -53,20 +53,31 @@ pub const BALOAD: u8 = 51; //(0x33) Load byte or boolean from array
|
||||||
pub const CALOAD: u8 = 52; // (0x34) Load char from array
|
pub const CALOAD: u8 = 52; // (0x34) Load char from array
|
||||||
pub const SALOAD: u8 = 53; // (0x34) Load short from array
|
pub const SALOAD: u8 = 53; // (0x34) Load short from array
|
||||||
pub const ISTORE: u8 = 54; // (0x36) Store int into local variable
|
pub const ISTORE: u8 = 54; // (0x36) Store int into local variable
|
||||||
//
|
pub const LSTORE: u8 = 55; // (0x37) Store long into local variable
|
||||||
// pub const fstore: u8 = 56; // (0x38) Store float into local variable
|
pub const FSTORE: u8 = 56; // (0x38) Store float into local variable
|
||||||
// pub const dstore: u8 = 57; // (0x39) store double in local variable
|
pub const DSTORE: u8 = 57; // (0x39) store double in local variable
|
||||||
// pub const astore:u8 = 58; // (0x3a)
|
pub const ASTORE :u8 = 58; // (0x3a)
|
||||||
//
|
pub const ISTORE_0:u8 = 59; // (0x3b) Store int into local variable 0
|
||||||
// pub const dstore_0: u8 = 71; // (0x47) store double 0 in local variable
|
pub const ISTORE_1:u8 = 60; // (0x3c) Store int into local variable 1
|
||||||
// pub const dstore_1: u8 = 72; // (0x48) store double 1 in local variable
|
pub const ISTORE_2:u8 = 61; // (0x3d) Store int into local variable 2
|
||||||
// pub const dstore_2: u8 = 73; // (0x49) store double 2 in local variable
|
pub const ISTORE_3:u8 = 62; // (0x3e) Store int into local variable 3
|
||||||
// pub const dstore_3: u8 = 74; // (0x4a) store double 3 in local variable
|
pub const LSTORE_0:u8 = 63; // (0x3f) Store long into local variable 0
|
||||||
// pub const astore_0: u8 = 75; // (0x4b)
|
pub const LSTORE_1:u8 = 64; // (0x40) Store long into local variable 1
|
||||||
// pub const astore_1: u8 = 76; // (0x4c)
|
pub const LSTORE_2:u8 = 65; // (0x41) Store long into local variable 2
|
||||||
// pub const astore_2: u8 = 77; // (0x4d)
|
pub const LSTORE_3:u8 = 66; // (0x42) Store long into local variable 3
|
||||||
// pub const astore_3: u8 = 78; // (0x4e)
|
pub const FSTORE_0:u8 = 67; // (0x43) Store float into local variable 0
|
||||||
// pub const fastore: u8 = 81; // (0x51) Store into float array
|
pub const FSTORE_1:u8 = 68; // (0x44) Store float into local variable 1
|
||||||
|
pub const FSTORE_2:u8 = 69; // (0x45) Store float into local variable 2
|
||||||
|
pub const FSTORE_3:u8 = 70; // (0x46) Store float into local variable 3
|
||||||
|
pub const DSTORE_0: u8 = 71; // (0x47) store double in local variable 0
|
||||||
|
pub const DSTORE_1: u8 = 72; // (0x48) store double in local variable 1
|
||||||
|
pub const DSTORE_2: u8 = 73; // (0x49) store double in local variable 2
|
||||||
|
pub const DSTORE_3: u8 = 74; // (0x4a) store double in local variable 3
|
||||||
|
pub const ASTORE_0: u8 = 75; // (0x4b)
|
||||||
|
pub const ASTORE_1: u8 = 76; // (0x4c)
|
||||||
|
pub const ASTORE_2: u8 = 77; // (0x4d)
|
||||||
|
pub const ASTORE_3: u8 = 78; // (0x4e)
|
||||||
|
pub const FASTORE: u8 = 81; // (0x51) Store into float array
|
||||||
// pub const dastore:u8 = 82; //(0x52) store into double array
|
// pub const dastore:u8 = 82; //(0x52) store into double array
|
||||||
// pub const aastore: u8 = 83; // (0x53)
|
// pub const aastore: u8 = 83; // (0x53)
|
||||||
//
|
//
|
||||||
|
|
|
||||||
130
src/vm.rs
130
src/vm.rs
|
|
@ -111,6 +111,7 @@ impl Vm {
|
||||||
method_name: &str,
|
method_name: &str,
|
||||||
args: Vec<Arc<UnsafeCell<Value>>>,
|
args: Vec<Arc<UnsafeCell<Value>>>,
|
||||||
) -> Result<Arc<UnsafeCell<Value>>, Error> {
|
) -> Result<Arc<UnsafeCell<Value>>, Error> {
|
||||||
|
let mut local_params: Vec<Option<Arc<UnsafeCell<Value>>>> = args.clone().iter().map(|e| Some(e.clone())).collect();
|
||||||
println!("execute {}.{}", class_name, method_name);
|
println!("execute {}.{}", class_name, method_name);
|
||||||
let class = self.get_class(class_name)?;
|
let class = self.get_class(class_name)?;
|
||||||
let method = class.get_method(method_name)?;
|
let method = class.get_method(method_name)?;
|
||||||
|
|
@ -237,20 +238,38 @@ impl Vm {
|
||||||
// let index = self.local_stack().pop()?;
|
// let index = self.local_stack().pop()?;
|
||||||
// let array_ref = self.local_stack().pop()?;
|
// let array_ref = self.local_stack().pop()?;
|
||||||
}
|
}
|
||||||
ISTORE => {
|
ISTORE | LSTORE | FSTORE | DSTORE | ASTORE => {
|
||||||
unsafe {
|
let index = read_u8(&code.opcodes, pc) as usize;
|
||||||
let index = read_u8(&code.opcodes, pc);
|
self.store(&mut local_params, index)?;
|
||||||
let value = self.local_stack().pop()?;
|
}
|
||||||
if let Value::I32(int) = *value.get() {
|
ISTORE_0 | LSTORE_0 | DSTORE_0 | ASTORE_0 | FSTORE_0 => {
|
||||||
// TODO local vars
|
self.store(&mut local_params, 0)?;
|
||||||
|
}
|
||||||
|
ISTORE_1 | LSTORE_1 | DSTORE_1 | ASTORE_1 | FSTORE_1 => {
|
||||||
|
self.store(&mut local_params, 1)?;
|
||||||
|
}
|
||||||
|
ISTORE_2 | LSTORE_2 | DSTORE_2 | ASTORE_2 | FSTORE_2 => {
|
||||||
|
self.store(&mut local_params, 2)?;
|
||||||
|
}
|
||||||
|
ISTORE_3 | LSTORE_3 | DSTORE_3 | ASTORE_3 | FSTORE_3 => {
|
||||||
|
self.store(&mut local_params, 3)?;
|
||||||
|
}
|
||||||
|
FASTORE => unsafe {
|
||||||
|
if let Value::F32(value) = *self.local_stack().pop()?.get() {
|
||||||
|
if let Value::I32(index) = &mut *self.local_stack().pop()?.get() {
|
||||||
|
if let Value::Ref(ref mut objectref) = &mut *self.local_stack().pop()?.get() {
|
||||||
|
if let ObjectRef::FloatArray(ref mut array) = &mut *objectref.get() {
|
||||||
|
array[*index as usize] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
POP => {
|
POP => {
|
||||||
self.local_stack().pop().expect("Stack empty");
|
self.local_stack().pop()?;
|
||||||
}
|
}
|
||||||
DUP => {
|
DUP => {
|
||||||
let value = self.local_stack().pop().expect("Stack empty");
|
let value = self.local_stack().pop()?;
|
||||||
println!("{:?}", value);
|
println!("{:?}", value);
|
||||||
self.local_stack().push_arc(value.clone());
|
self.local_stack().push_arc(value.clone());
|
||||||
self.local_stack().push_arc(value);
|
self.local_stack().push_arc(value);
|
||||||
|
|
@ -282,57 +301,51 @@ impl Vm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PUTFIELD => {
|
PUTFIELD => unsafe {
|
||||||
unsafe {
|
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
|
||||||
if let CpEntry::Fieldref(_class_index, name_and_type_index) =
|
|
||||||
method.constant_pool.get(&cp_index).unwrap()
|
|
||||||
{
|
|
||||||
if let CpEntry::NameAndType(name_index, _) = method.constant_pool.get(name_and_type_index).unwrap() {
|
|
||||||
let value = self.local_stack().pop()?;
|
|
||||||
let mut objectref = self.local_stack().pop()?;
|
|
||||||
if let Value::Ref(instance) = &mut *objectref.get() {
|
|
||||||
if let ObjectRef::Object(ref mut object) = &mut *instance.get() {
|
|
||||||
object.data.insert(*name_index, value);
|
|
||||||
} else {
|
|
||||||
panic!("not an object, maybe array");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
INVOKEVIRTUAL => {
|
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
unsafe {
|
if let CpEntry::Fieldref(_class_index, name_and_type_index) =
|
||||||
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
method.constant_pool.get(&cp_index).unwrap()
|
||||||
let mut args = Vec::with_capacity(invocation.method.num_args);
|
{
|
||||||
for _ in 0..invocation.method.num_args {
|
if let CpEntry::NameAndType(name_index, _) = method.constant_pool.get(name_and_type_index).unwrap() {
|
||||||
args.insert(0, self.local_stack().pop()?);
|
let value = self.local_stack().pop()?;
|
||||||
}
|
let mut objectref = self.local_stack().pop()?;
|
||||||
args.insert(0, self.local_stack().pop()?);
|
if let Value::Ref(instance) = &mut *objectref.get() {
|
||||||
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
if let ObjectRef::Object(ref mut object) = &mut *instance.get() {
|
||||||
match *returnvalue.get() {
|
object.data.insert(*name_index, value);
|
||||||
Void => {}
|
} else {
|
||||||
_ => { self.local_stack().push_arc(returnvalue.clone()); }
|
panic!("not an object, maybe array");
|
||||||
}
|
}
|
||||||
|
} // else?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INVOKESPECIAL => {
|
INVOKEVIRTUAL => unsafe {
|
||||||
unsafe {
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
let cp_index = read_u16(&code.opcodes, pc);
|
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
||||||
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
let mut args = Vec::with_capacity(invocation.method.num_args);
|
||||||
let mut args = Vec::with_capacity(invocation.method.num_args);
|
for _ in 0..invocation.method.num_args {
|
||||||
for _ in 0..invocation.method.num_args {
|
|
||||||
args.insert(0, self.local_stack().pop()?);
|
|
||||||
}
|
|
||||||
args.insert(0, self.local_stack().pop()?);
|
args.insert(0, self.local_stack().pop()?);
|
||||||
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
}
|
||||||
match *returnvalue.get() {
|
args.insert(0, self.local_stack().pop()?);
|
||||||
Void => {}
|
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
||||||
_ => { self.local_stack().push_arc(returnvalue.clone()); }
|
match *returnvalue.get() {
|
||||||
}
|
Void => {}
|
||||||
|
_ => { self.local_stack().push_arc(returnvalue.clone()); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INVOKESPECIAL => unsafe {
|
||||||
|
let cp_index = read_u16(&code.opcodes, pc);
|
||||||
|
if let Some(invocation) = get_signature_for_invoke(Rc::clone(&method.constant_pool), cp_index) {
|
||||||
|
let mut args = Vec::with_capacity(invocation.method.num_args);
|
||||||
|
for _ in 0..invocation.method.num_args {
|
||||||
|
args.insert(0, self.local_stack().pop()?);
|
||||||
|
}
|
||||||
|
args.insert(0, self.local_stack().pop()?);
|
||||||
|
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
||||||
|
match *returnvalue.get() {
|
||||||
|
Void => {}
|
||||||
|
_ => { self.local_stack().push_arc(returnvalue.clone()); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -363,6 +376,15 @@ impl Vm {
|
||||||
}
|
}
|
||||||
panic!("should not happen")
|
panic!("should not happen")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn store(&mut self, local_params: &mut Vec<Option<Arc<UnsafeCell<Value>>>>, index: usize) -> Result<(), Error> {
|
||||||
|
let value = self.local_stack().pop()?;
|
||||||
|
while local_params.len() < index + 1 {
|
||||||
|
local_params.push(None);
|
||||||
|
}
|
||||||
|
local_params[index] = Some(value.clone());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue