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)]
|
||||
pub enum Value {
|
||||
Void,
|
||||
Null,
|
||||
// the $1_000_000 mistake
|
||||
Void, // variant returned for void methods
|
||||
Null, // 'pointer' to nothing
|
||||
I32(i32),
|
||||
I64(i64),
|
||||
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 SALOAD: u8 = 53; // (0x34) Load short from array
|
||||
pub const ISTORE: u8 = 54; // (0x36) Store int 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 astore:u8 = 58; // (0x3a)
|
||||
//
|
||||
// pub const dstore_0: u8 = 71; // (0x47) store double 0 in local variable
|
||||
// pub const dstore_1: u8 = 72; // (0x48) store double 1 in local variable
|
||||
// pub const dstore_2: u8 = 73; // (0x49) store double 2 in local variable
|
||||
// pub const dstore_3: u8 = 74; // (0x4a) store double 3 in local variable
|
||||
// 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 LSTORE: u8 = 55; // (0x37) Store long 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 ASTORE :u8 = 58; // (0x3a)
|
||||
pub const ISTORE_0:u8 = 59; // (0x3b) Store int into local variable 0
|
||||
pub const ISTORE_1:u8 = 60; // (0x3c) Store int into local variable 1
|
||||
pub const ISTORE_2:u8 = 61; // (0x3d) Store int into local variable 2
|
||||
pub const ISTORE_3:u8 = 62; // (0x3e) Store int into local variable 3
|
||||
pub const LSTORE_0:u8 = 63; // (0x3f) Store long into local variable 0
|
||||
pub const LSTORE_1:u8 = 64; // (0x40) Store long into local variable 1
|
||||
pub const LSTORE_2:u8 = 65; // (0x41) Store long into local variable 2
|
||||
pub const LSTORE_3:u8 = 66; // (0x42) Store long into local variable 3
|
||||
pub const FSTORE_0:u8 = 67; // (0x43) Store float into local variable 0
|
||||
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 aastore: u8 = 83; // (0x53)
|
||||
//
|
||||
|
|
|
|||
130
src/vm.rs
130
src/vm.rs
|
|
@ -111,6 +111,7 @@ impl Vm {
|
|||
method_name: &str,
|
||||
args: Vec<Arc<UnsafeCell<Value>>>,
|
||||
) -> 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);
|
||||
let class = self.get_class(class_name)?;
|
||||
let method = class.get_method(method_name)?;
|
||||
|
|
@ -237,20 +238,38 @@ impl Vm {
|
|||
// let index = self.local_stack().pop()?;
|
||||
// let array_ref = self.local_stack().pop()?;
|
||||
}
|
||||
ISTORE => {
|
||||
unsafe {
|
||||
let index = read_u8(&code.opcodes, pc);
|
||||
let value = self.local_stack().pop()?;
|
||||
if let Value::I32(int) = *value.get() {
|
||||
// TODO local vars
|
||||
ISTORE | LSTORE | FSTORE | DSTORE | ASTORE => {
|
||||
let index = read_u8(&code.opcodes, pc) as usize;
|
||||
self.store(&mut local_params, index)?;
|
||||
}
|
||||
ISTORE_0 | LSTORE_0 | DSTORE_0 | ASTORE_0 | FSTORE_0 => {
|
||||
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 => {
|
||||
self.local_stack().pop().expect("Stack empty");
|
||||
self.local_stack().pop()?;
|
||||
}
|
||||
DUP => {
|
||||
let value = self.local_stack().pop().expect("Stack empty");
|
||||
let value = self.local_stack().pop()?;
|
||||
println!("{:?}", value);
|
||||
self.local_stack().push_arc(value.clone());
|
||||
self.local_stack().push_arc(value);
|
||||
|
|
@ -282,57 +301,51 @@ impl Vm {
|
|||
}
|
||||
}
|
||||
}
|
||||
PUTFIELD => {
|
||||
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 => {
|
||||
PUTFIELD => unsafe {
|
||||
let cp_index = read_u16(&code.opcodes, pc);
|
||||
unsafe {
|
||||
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()); }
|
||||
}
|
||||
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");
|
||||
}
|
||||
} // else?
|
||||
}
|
||||
}
|
||||
}
|
||||
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()?);
|
||||
}
|
||||
INVOKEVIRTUAL => 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()?);
|
||||
let mut returnvalue = self.execute(&invocation.class_name, &invocation.method.name, args)?;
|
||||
match *returnvalue.get() {
|
||||
Void => {}
|
||||
_ => { self.local_stack().push_arc(returnvalue.clone()); }
|
||||
}
|
||||
}
|
||||
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()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
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")
|
||||
}
|
||||
|
||||
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