Optimize imports, remove println/debug statements, update type handling, and format code

This commit is contained in:
james 2025-12-18 17:01:01 +10:30
parent a6f6507a85
commit 025e6633be
No known key found for this signature in database
GPG Key ID: E1FFBA228F4CAD87
14 changed files with 57 additions and 96 deletions

View File

@ -33,7 +33,6 @@
<option name="SOFT_MARGINS" value="100" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TOML">

View File

@ -1,6 +1,6 @@
[workspace]
members = [
"crates/*"
"crates/*"
]
resolver = "3"
@ -10,13 +10,17 @@ deku_derive = "0.20.0"
log = "0.4.28"
env_logger = "0.11.8"
itertools = "0.14.0"
indexmap = "2.12.1"
sevenz-rust2 = { version = "0.19.3", features = ["brotli", "zstd"] }
dashmap = "7.0.0-rc2"
libloading = "0.8.9"
libffi = "5.0.0"
jni = "0.21.1"
roast-vm-sys = { path = "crates/roast-vm-sys", version = "0.1.0" }
roast-vm-core = { path = "crates/core", version = "0.1.0" }
roast-vm-sys = { path = "crates/roast-vm-sys" }
roast-vm-core = { path = "crates/core" }
colored = "3.0.0"
parking_lot = "0.12"
cesu8 = "1.1.0"
[profile.dev-opt]
inherits = "dev"

View File

@ -1,6 +1,6 @@
[package]
name = "roast-vm-core"
version = "0.1.0"
version = "0.1.5"
edition = "2024"
publish = ["nexus"]
@ -15,16 +15,12 @@ libloading = { workspace = true }
libffi = { workspace = true }
jni = { workspace = true }
itertools = { workspace = true }
colored = "3.0.0"
parking_lot = "0.12"
cesu8 = "1.1.0"
colored = { workspace = true }
parking_lot = { workspace = true }
cesu8 = { workspace = true }
[build-dependencies]
bindgen = "0.72.1"
[lints.rust]
#missing_docs = "warn"
[[bin]]
name = "roast"
path = "src/main.rs"
path = "src/main.rs"

View File

@ -196,15 +196,7 @@ impl ClassLoader {
.bimage
.get_class(module, class_fqn)
.or_else(|e| Self::load_class_from_disk(what))
.map_err(|e1| {
let classes = self
.classes
.iter()
.map(|x| x.this_class.clone())
.collect::<Vec<_>>();
// println!("{:#?}", classes);
VmError::LoaderError(format!("failed to find class: {:?}\n{:#?}", what, classes))
})?;
.map_err(|e1| VmError::LoaderError(format!("failed to find class: {}", what)))?;
let (_, cf) =
ClassFile::from_bytes((bytes.as_ref(), 0)).map_err(|e| VmError::DekuError(e))?;
let runtime = self.runtime_class(cf);

View File

@ -4,15 +4,15 @@ use crate::class_file::constant_pool::{ConstantPoolExt, ConstantPoolGet};
use crate::class_file::{Bytecode, ConstantPoolEntry, MethodRef};
use crate::error::{StackTraceElement, VmError};
use crate::instructions::{Ops, WideData};
use crate::objects::array::ArrayReference;
use crate::objects::ReferenceKind;
use crate::objects::array::ArrayReference;
use crate::prim::*;
use crate::value::{LocalVariables, OperandStack, Primitive, Value};
use crate::vm::Vm;
use crate::{
array_store, array_store_cast, binary_op, convert_float_to_int, convert_int_narrow,
convert_simple, error, float_cmp, if_int_cmp, if_int_zero, int_div_rem, load, shift_op, store,
unary_op, BaseType, FieldType, VmThread,
BaseType, FieldType, VmThread, array_store, array_store_cast, binary_op, convert_float_to_int,
convert_int_narrow, convert_simple, error, float_cmp, if_int_cmp, if_int_zero, int_div_rem,
load, shift_op, store, unary_op,
};
use deku::DekuContainerRead;
use log::{info, trace, warn};
@ -134,19 +134,10 @@ impl Frame {
line_number_table,
}
}
pub(crate) fn execute(&mut self) -> Result<Option<Value>, error::VmError> {
// todo remove
if self.method_ref.name.eq("<clinit>") {
if self.class.this_class.contains("IBM437") {
println!("[DEBUG] START");
}
}
let binding = self.bytecode.code.clone();
pub(crate) fn execute(&mut self) -> Result<Option<Value>, VmError> {
loop {
let (offset, op) = self.next().expect("No ops :(");
// trace!("pre set: {}", self.pc);
let (offset, op) = self.next().unwrap();
self.pc = offset as i64;
// trace!("post set: {}", self.pc);
trace!("Executing Op: {:?}", op);
let result = self.execute_instruction(op.clone());
match result {
@ -988,7 +979,7 @@ impl Frame {
_ => {
return Err(VmError::InvariantError(
"ireturn requires integer-compatible value".to_owned(),
))
));
}
};
@ -1346,7 +1337,6 @@ impl Frame {
Ops::wide(data) => match data {
WideData::iinc(idx, increment) => {
println!("index: {idx}, inc: {increment}");
let int = self.vars.get(idx as usize).clone().try_into_jint()?;
let new_val = int + increment as i32;
self.vars.set(idx as usize, new_val.into());

View File

@ -24,7 +24,7 @@ fn run() {
// .filter_module("roast_vm_core::instructions", LevelFilter::Info)
// .init();
stack_used();
let vm = Vm::new();
let mut vm = Vm::new();
vm.load_native_library("roast_vm.dll", load("roast_vm.dll").into());
vm.load_native_library("jvm.dll", load("jvm.dll").into());
vm.load_native_library("java.dll", load("java.dll").into());

View File

@ -10,10 +10,10 @@ use crate::value::{Primitive, Value};
use crate::{BaseType, FieldType, MethodDescriptor};
use itertools::Itertools;
use jni::sys::*;
use jni::sys::{jclass, jint, jobject, JNINativeInterface_};
use jni::sys::{jstring, JNIEnv};
use jni::sys::{JNIEnv, jstring};
use jni::sys::{JNINativeInterface_, jclass, jint, jobject};
use log::{error, info, trace, warn};
use std::ffi::{c_char, CStr, CString};
use std::ffi::{CStr, CString, c_char};
use std::ptr;
use std::sync::Arc;
@ -318,7 +318,7 @@ unsafe extern "system" fn get_string_utfchars(
_ => return ptr::null(),
};
let obj = obj_ref.lock();
let mut obj = obj_ref.lock();
let field_ref = FieldRef {
class: "java/lang/String".to_string(),
name: "value".to_string(),
@ -1076,11 +1076,7 @@ unsafe extern "system" fn get_boolean_field(
};
let val = object.lock().get_field(&field_ref);
if let Value::Primitive(Primitive::Boolean(bool)) = val {
if bool {
JNI_TRUE
} else {
JNI_FALSE
}
if bool { JNI_TRUE } else { JNI_FALSE }
} else {
JNI_FALSE
}
@ -1457,11 +1453,7 @@ unsafe extern "system" fn get_static_boolean_field(
let field_again = class.find_field(&field_ref.name, &field_ref.desc).unwrap();
let val = field_again.value.lock().clone();
if let Some(Value::Primitive(Primitive::Boolean(bool))) = val {
if bool {
JNI_TRUE
} else {
JNI_FALSE
}
if bool { JNI_TRUE } else { JNI_FALSE }
} else {
JNI_FALSE
}
@ -2147,9 +2139,7 @@ unsafe extern "system" fn get_string_utf_region(
) {
trace!(
"get_string_utf_region: start={}, len={}, buf={:?}",
start,
len,
buf
start, len, buf
);
let thread = &*get_thread(env);
let string_obj = resolve_object(thread, str).unwrap();

View File

@ -1,5 +1,4 @@
use crate::class_file::ConstantPoolEntry;
use dashmap::DashMap;
use libloading::Library;
use std::collections::HashMap;

View File

@ -6,17 +6,17 @@ use crate::objects::array::{
Array, ArrayReference, ArrayValue, ObjectArrayReference, PrimitiveArrayReference,
};
use crate::objects::object::{
string_from_bytes, Object, ObjectReference, Reference, ReferenceKind,
Object, ObjectReference, Reference, ReferenceKind, string_from_bytes,
};
use crate::value::{Primitive, Value};
use crate::{objects, rng, ThreadId};
use crate::{ThreadId, objects, rng};
use dashmap::DashMap;
use jni::sys::{jboolean, jbyte, jchar, jdouble, jfloat, jint, jlong, jshort};
use log::warn;
use parking_lot::{Condvar, Mutex};
use std::collections::HashMap;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};
#[derive(Default)]
pub struct ObjectManager {
@ -63,7 +63,7 @@ impl ObjectManager {
.iter()
.map(|(id, obj)| format!("id: {id} obj: {}", obj.class().this_class))
.collect::<Vec<_>>();
println!("next: {} all: \n{:#?}", next, key_pairs)
eprintln!("next: {} all: \n{:#?}", next, key_pairs)
}
assert!(
!self.objects.contains_key(&id),
@ -265,7 +265,7 @@ impl ObjectManager {
_ => {
return Err(VmError::InvariantError(
"String value field must be a byte array".to_string(),
))
));
}
};
@ -277,7 +277,7 @@ impl ObjectManager {
_ => {
return Err(VmError::InvariantError(
"String value must be a byte array".to_string(),
))
));
}
};
Ok(string_from_bytes(&bytes))

View File

@ -8,13 +8,13 @@ use crate::objects::object::{ObjectReference, ReferenceKind};
use crate::objects::object_manager::ObjectManager;
use crate::value::{Primitive, Value};
use crate::vm::Vm;
use crate::{stack_used, BaseType, FieldType, MethodDescriptor, ThreadId};
use crate::{BaseType, FieldType, MethodDescriptor, ThreadId, stack_used};
use deku::DekuError::Incomplete;
use itertools::Itertools;
use jni::sys::{jboolean, jbyte, jchar, jdouble, jfloat, jint, jlong, jobject, jshort, JNIEnv};
use jni::sys::{JNIEnv, jboolean, jbyte, jchar, jdouble, jfloat, jint, jlong, jobject, jshort};
use libffi::low::call;
use libffi::middle::*;
use log::{info, trace, warn, LevelFilter};
use log::{LevelFilter, info, trace, warn};
use parking_lot::{Mutex, Once, ReentrantMutex, RwLock};
use std::any::Any;
@ -22,8 +22,8 @@ use std::cell::RefCell;
use std::collections::VecDeque;
use std::ops::{Add, Deref};
use std::ptr::null_mut;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use std::thread;
use std::vec::IntoIter;
@ -286,7 +286,7 @@ impl VmThread {
}
pub fn invoke(&self, method_reference: MethodRef, args: Vec<Value>) -> MethodCallResult {
if self.gc.read().objects.len() > 2210 {
if self.gc.read().objects.len() > 2230 {
INIT_LOGGER.call_once(|| {
env_logger::Builder::from_default_env()
.filter_level(LevelFilter::Trace)
@ -319,7 +319,6 @@ impl VmThread {
pub fn invoke_native(&self, method: &MethodRef, mut args: Vec<Value>) -> MethodCallResult {
let symbol_name = generate_jni_method_name(method, false);
println!("Invoke native for native symbol: {:?}", &symbol_name);
// if symbol_name.contains("Java_jdk_internal_reflect_Reflection_getClassAccessFlags") {
// return Err(VmError::Debug(

View File

@ -1,5 +1,6 @@
#[cfg(libloading_docs)]
use super::os::unix as imp;
use std::collections::HashMap;
use std::ffi::c_void;
// the implementation used here doesn't matter particularly much...
#[cfg(all(not(libloading_docs), unix))]
@ -21,6 +22,8 @@ use log::trace;
use parking_lot::{Mutex, RwLock};
use std::sync::Arc;
type NativeLibraries = Arc<RwLock<Vec<(String, Library)>>>;
// struct AbstractObject<'a> {}
pub struct Vm {
// Thread registry - maps ThreadId to VmThread
@ -28,7 +31,7 @@ pub struct Vm {
pub main_thread_id: ThreadId,
pub loader: Arc<Mutex<ClassLoader>>,
pub native_methods: DashMap<String, *const c_void>,
pub native_libraries: DashMap<String, Library>,
pub native_libraries: NativeLibraries,
pub gc: Arc<RwLock<ObjectManager>>,
pub safent: RwLock<UnsafeSupport>,
}
@ -41,7 +44,7 @@ impl Vm {
main_thread_id: ThreadId(0),
loader: Arc::new(Mutex::from(ClassLoader::default())),
native_methods: DashMap::new(),
native_libraries: DashMap::new(),
native_libraries: Arc::new(RwLock::new(Vec::new())),
gc: Default::default(),
safent: Default::default(),
});
@ -59,7 +62,7 @@ impl Vm {
}
pub fn load_native_library(&self, name: &str, lib: Library) {
self.native_libraries.insert(name.to_string(), lib);
self.native_libraries.write().push((name.to_string(), lib));
}
pub fn find_native_method(&self, name: &str) -> Option<*const c_void> {
@ -68,22 +71,13 @@ impl Vm {
return Some(registered.clone());
}
{
let lib = self.native_libraries.get("roast_vm.dll").unwrap();
let res = unsafe { lib.get::<unsafe extern "system" fn()>(name.as_bytes()) };
if res.is_ok() {
let symbol = res.unwrap();
let ptr = *symbol as *const c_void;
self.native_methods.insert(name.to_string(), ptr);
return Some(ptr);
}
}
for entry in self.native_libraries.iter() {
let (_lib_name, lib) = entry.pair();
for (lib_name, lib) in self.native_libraries.read().iter() {
let res = unsafe { lib.get::<unsafe extern "system" fn()>(name.as_bytes()) };
if res.is_ok() {
println!(
"Invoke native for native symbol: {} out of: {}",
&name, lib_name
);
let symbol = res.unwrap();
let ptr = *symbol as *const c_void;
self.native_methods.insert(name.to_string(), ptr);

View File

@ -1,13 +1,13 @@
[package]
name = "roast-vm-sys"
version = "0.1.0"
version = "0.1.5"
edition = "2024"
publish = ["nexus"]
[dependencies]
jni = { workspace = true }
roast-vm-core = { workspace = true }
log = "0.4.28"
log = { workspace = true }
[lib]
name = "roast_vm"

View File

@ -1,6 +1,6 @@
use crate::{get_thread, resolve_object};
use jni::sys::{jboolean, jclass, jobject, JNI_TRUE};
use jni::sys::{jint, JNIEnv};
use jni::sys::{JNI_TRUE, jboolean, jclass, jobject};
use jni::sys::{JNIEnv, jint};
use jni::sys::{jobjectArray, jstring};
use log::trace;
use roast_vm_core::class_file::FieldRef;
@ -78,7 +78,6 @@ pub unsafe extern "system" fn Java_java_lang_Class_forName0(
// Convert "java.lang.String" -> "java/lang/String"
let class_name = class_name.replace('.', "/");
println!("forName0: class name is : {}", class_name);
// Load the class
let rtc = match thread.get_class(&class_name) {
@ -93,7 +92,6 @@ pub unsafe extern "system" fn Java_java_lang_Class_forName0(
thread.ensure_initialised(&rtc).unwrap();
}
println!("returning");
// Return the mirror
*rtc.mirror.get().unwrap() as jclass
}

View File

@ -1,10 +1,10 @@
use crate::{get_thread, resolve_array, resolve_object};
use jni::sys::{jboolean, jclass, jint, jlong, jobject, jstring, JNIEnv, JNI_FALSE, JNI_TRUE};
use jni::sys::{JNI_FALSE, JNI_TRUE, JNIEnv, jboolean, jclass, jint, jlong, jobject, jstring};
use log::warn;
use roast_vm_core::native::r#unsafe::OffsetKind;
use roast_vm_core::objects::ReferenceKind;
use roast_vm_core::objects::array::ArrayReference;
use roast_vm_core::objects::object::string_from_bytes;
use roast_vm_core::objects::ReferenceKind;
use roast_vm_core::value::Value;
#[unsafe(no_mangle)]
@ -13,7 +13,7 @@ pub unsafe extern "system" fn Java_jdk_internal_misc_Unsafe_registerNatives(
obj: jclass,
) {
//no op
println!("Unsafe_registerNatives is NO OP")
warn!("Unsafe_registerNatives is NO OP")
}
#[unsafe(no_mangle)]