Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Dec 15, 2024
1 parent 98a637f commit c525405
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 36 deletions.
4 changes: 2 additions & 2 deletions runtime/src/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::java_call;
use crate::native::jni::invocation_api::main_java_vm;
use crate::reference::Reference;
use crate::string_interner::StringInterner;
use crate::thread::JavaThread;
use crate::thread::{java_lang_Thread, JavaThread};

use classfile::accessflags::MethodAccessFlags;
use classfile::FieldType;
Expand Down Expand Up @@ -58,7 +58,7 @@ fn initialize_thread(thread: &JavaThread) {
}

// Grab the java.lang.Thread field offsets
JavaThread::set_field_offsets();
java_lang_Thread::set_field_offsets();

// Init some important classes
initialize_global_classes(thread);
Expand Down
18 changes: 15 additions & 3 deletions runtime/src/native/java/lang/Thread.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::class_instance::Instance;
use crate::reference::Reference;
use crate::thread::java_lang_Thread;
use crate::JavaThread;

use std::ptr::NonNull;
use std::sync::atomic::AtomicUsize;

use ::jni::env::JniEnv;
use ::jni::sys::{jboolean, jint, jlong};
use common::traits::PtrType;

include_generated!("native/java/lang/def/Thread.registerNatives.rs");
include_generated!("native/java/lang/def/Thread.definitions.rs");
Expand Down Expand Up @@ -87,10 +90,19 @@ pub fn getThreads(_env: NonNull<JniEnv>) -> Reference /* []java.lang.Thread */ {

pub fn setPriority0(
_env: NonNull<JniEnv>,
_this: Reference, // java.lang.Thread
_new_priority: jint,
this: Reference, // java.lang.Thread
new_priority: jint,
) {
unimplemented!("java.lang.Thread#setPriority0");
java_lang_Thread::set_priority(this.clone(), new_priority);

let java_thread = unsafe { JavaThread::for_obj(this.extract_class()) };
let Some(thread) = java_thread else {
return;
};

// Thread is alive...
let _thread_ref = unsafe { &*thread };
todo!("Set priority on JavaThread?")
}

pub fn interrupt0(_env: NonNull<JniEnv>, _this: Reference /* java.lang.Thread */) {
Expand Down
8 changes: 4 additions & 4 deletions runtime/src/objects/class_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ pub trait Instance {
fn get_field_value0(&self, field_idx: usize) -> Operand<Reference>;
fn put_field_value(&mut self, field: &Field, value: Operand<Reference>);
fn put_field_value0(&mut self, field_idx: usize, value: Operand<Reference>);
unsafe fn get_field_value_raw(&mut self, field_idx: usize) -> NonNull<Operand<Reference>>;
unsafe fn get_field_value_raw(&self, field_idx: usize) -> NonNull<Operand<Reference>>;
}

#[derive(Debug)]
pub struct ClassInstance {
super_class: Option<ClassInstanceRef>,
class: &'static Class,
fields: Box<[Operand<Reference>]>,
pub fields: Box<[Operand<Reference>]>,
}

impl Clone for ClassInstance {
Expand Down Expand Up @@ -147,9 +147,9 @@ impl Instance for ClassInstance {
);
}

unsafe fn get_field_value_raw(&mut self, field_idx: usize) -> NonNull<Operand<Reference>> {
unsafe fn get_field_value_raw(&self, field_idx: usize) -> NonNull<Operand<Reference>> {
assert!(field_idx < self.fields.len());
NonNull::new_unchecked(self.fields.as_mut_ptr().offset(field_idx as isize))
NonNull::new_unchecked(self.fields.as_ptr().offset(field_idx as isize) as _)
}
}

Expand Down
4 changes: 2 additions & 2 deletions runtime/src/objects/mirror.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ impl Instance for MirrorInstance {
self.fields[field_idx] = value;
}

unsafe fn get_field_value_raw(&mut self, field_idx: usize) -> NonNull<Operand<Reference>> {
unsafe fn get_field_value_raw(&self, field_idx: usize) -> NonNull<Operand<Reference>> {
assert!(field_idx < self.fields.len());
NonNull::new_unchecked(self.fields.as_mut_ptr().offset(field_idx as isize))
NonNull::new_unchecked(self.fields.as_ptr().offset(field_idx as isize) as _)
}
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/src/objects/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl Instance for Reference {
}
}

unsafe fn get_field_value_raw(&mut self, field_idx: usize) -> NonNull<Operand<Reference>> {
unsafe fn get_field_value_raw(&self, field_idx: usize) -> NonNull<Operand<Reference>> {
match &self.instance {
ReferenceInstance::Class(class) => class.get_mut().get_field_value_raw(field_idx),
ReferenceInstance::Mirror(mirror) => mirror.get_mut().get_field_value_raw(field_idx),
Expand Down
73 changes: 49 additions & 24 deletions runtime/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,16 @@ pub enum ThreadStatus {
}

/// `java.lang.Thread$FieldHolder` accessors
impl JavaThread {
pub mod java_lang_Thread {
use crate::class_instance::Instance;
use crate::reference::Reference;
use crate::thread::ThreadStatus;
use crate::JavaThread;
use common::int_types::s4;
use common::traits::PtrType;
use instructions::Operand;
use symbols::sym;

pub fn set_field_offsets() {
// java.lang.Thread fields
{
Expand Down Expand Up @@ -255,7 +264,7 @@ impl JavaThread {
);
}

Self::set_field_holder_offsets();
set_field_holder_offsets();
}

// java.lang.Thread$FieldHolder fields
Expand Down Expand Up @@ -289,8 +298,16 @@ impl JavaThread {
);
}

fn set_field_holder_field(&self, offset: usize, value: Operand<Reference>) {
let obj = self.obj().unwrap();
pub(super) fn set_eetop(obj: Reference, eetop: jni::sys::jlong) {
let offset = crate::globals::field_offsets::thread_eetop_field_offset();

let instance = obj.extract_class();
instance
.get_mut()
.put_field_value0(offset, Operand::Long(eetop));
}

fn set_field_holder_field(obj: Reference, offset: usize, value: Operand<Reference>) {
let class_instance = obj.extract_class();

let field_holder_offset = crate::globals::field_offsets::thread_holder_field_offset();
Expand All @@ -304,25 +321,41 @@ impl JavaThread {
.put_field_value0(offset, value);
}

fn set_priority(&self, _priority: s4) {
assert!(self.obj().is_some());
todo!()
pub fn set_priority(obj: Reference, priority: s4) {
let offset = crate::globals::field_offsets::field_holder_priority_field_offset();
set_field_holder_field(obj, offset, Operand::Int(priority));
}

fn set_daemon(&self, _daemon: bool) {
assert!(self.obj().is_some());
fn set_daemon(_obj: Reference, _daemon: bool) {
todo!()
}

fn set_thread_status(&self, thread_status: ThreadStatus) {
assert!(self.obj().is_some());
pub(super) fn set_thread_status(obj: Reference, thread_status: ThreadStatus) {
let offset = crate::globals::field_offsets::field_holder_thread_status_field_offset();
self.set_field_holder_field(offset, Operand::Int(thread_status as s4));
set_field_holder_field(obj, offset, Operand::Int(thread_status as s4));
}
}

// Actions for the related `java.lang.Thread` instance
impl JavaThread {
/// Get the `JavaThread` associated with `obj`
///
/// # Safety
///
/// The caller must ensure that `obj` is a `java.lang.Thread` object obtained from [`Self::obj()`]
pub unsafe fn for_obj(obj: ClassInstanceRef) -> Option<*mut JavaThread> {
let eetop_offset = crate::globals::field_offsets::thread_eetop_field_offset();
let field_value_ptr = unsafe { obj.get().get_field_value_raw(eetop_offset) };
let field_value = unsafe { field_value_ptr.as_ref() };
let eetop = field_value.expect_long();
if eetop == 0 {
// Thread is not alive
return None;
}

Some(eetop as *mut JavaThread)
}

/// Allocates a new `java.lang.Thread` for this `JavaThread`
///
/// This is called from the JNI `AttachCurrentThread`/`AttachCurrentThreadAsDaemon`.
Expand Down Expand Up @@ -380,7 +413,9 @@ impl JavaThread {

// Set the obj early, since the java.lang.Thread constructor calls Thread#current.
self.set_obj(Reference::class(ClassInstanceRef::clone(&thread_instance)));
self.set_eetop();
let obj = self.obj().unwrap();

java_lang_Thread::set_eetop(obj.clone(), JavaThread::current_ptr() as jni::sys::jlong);

let init_method = thread_class
.vtable()
Expand All @@ -401,7 +436,7 @@ impl JavaThread {
Operand::Reference(Reference::class(thread_name)),
);

self.set_thread_status(ThreadStatus::Runnable);
java_lang_Thread::set_thread_status(obj, ThreadStatus::Runnable);
}

pub fn set_obj(&self, obj: Reference) {
Expand All @@ -423,16 +458,6 @@ impl JavaThread {
let obj_opt = unsafe { &*obj_ptr };
obj_opt.as_ref().map(Reference::clone)
}

fn set_eetop(&self) {
let offset = crate::globals::field_offsets::thread_eetop_field_offset();

let obj = self.obj().unwrap();
obj.extract_class().get_mut().put_field_value0(
offset,
Operand::Long(JavaThread::current_ptr() as jni::sys::jlong),
);
}
}

impl JavaThread {
Expand Down

0 comments on commit c525405

Please sign in to comment.