Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Jan 15, 2025
1 parent b0cb046 commit 82ffc25
Show file tree
Hide file tree
Showing 32 changed files with 359 additions and 221 deletions.
5 changes: 3 additions & 2 deletions generators/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
[workspace]
resolver = "2"
members = [
"native_methods",
"vm_symbols",
"native_methods",
"vm_symbols",
]

[workspace.dependencies]
common = { path = "../common" }

combine = "4.6.7"
bitflags = "2.6.0"
indexmap = "2.7.0"
proc-macro2 = "1"
quote = "1"
syn = { version = "2", default-features = false }
Expand Down
3 changes: 2 additions & 1 deletion generators/native_methods/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ edition = "2021"
bitflags.workspace = true
combine.workspace = true
common.workspace = true
walkdir.workspace = true
walkdir.workspace = true
indexmap.workspace = true
5 changes: 2 additions & 3 deletions generators/native_methods/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,17 @@ pub fn generate_definitions_for_class(def_path: &Path, class: &Class) {
macro_rules! non_static_signature {
() => {
"\tpub fn _{}(env: std::ptr::NonNull<::jni::env::JniEnv>, locals: \
crate::stack::local_stack::LocalStack) -> crate::native::NativeReturn {{"
crate::stack::local_stack::LocalStack) -> crate::native::method::NativeReturn {{"
};
}

macro_rules! static_signature {
() => {
"\tpub fn _{}(env: std::ptr::NonNull<::jni::env::JniEnv>, class: &'static \
crate::objects::class::Class, locals: crate::stack::local_stack::LocalStack) -> \
crate::native::NativeReturn {{"
crate::native::method::NativeReturn {{"
};
}
const STATIC_SIGNATURE: &str = "pub fn ";

fn generate_methods_for_class(class: &Class, definitions_file: &mut File) {
for method in class.methods().filter(|method| {
Expand Down
8 changes: 8 additions & 0 deletions generators/native_methods/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
Io(std::io::Error),
Fmt(std::fmt::Error),
}

impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::Io(e) => e.fmt(f),
Error::Fmt(e) => e.fmt(f),
}
}
}
Expand All @@ -19,4 +21,10 @@ impl From<std::io::Error> for Error {
}
}

impl From<std::fmt::Error> for Error {
fn from(err: std::fmt::Error) -> Self {
Error::Fmt(err)
}
}

impl core::error::Error for Error {}
4 changes: 2 additions & 2 deletions generators/native_methods/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ impl IntrinsicId {
macro_rules! intrinsics_id3 {
($class:expr, $method_name:expr, $method_signature:expr) => {
(($method_signature.as_u32() as u64) +
(($method_name.as_u32() as u64) << symbols::Symbol::LOG2_LIMIT) +
(($class .as_u32() as u64) << (2*symbols::Symbol::LOG2_LIMIT)))
(($method_name.as_u32() as u64) << symbols::Symbol::PRE_INTERNED_LIMIT_LOG2) +
(($class .as_u32() as u64) << (2*symbols::Symbol::PRE_INTERNED_LIMIT_LOG2)))
};
}
Expand Down
11 changes: 8 additions & 3 deletions generators/native_methods/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,17 @@ fn generate_modules(native_directory: &Path, modules: &[Module]) -> Result<()> {
.expect("Can't find module marker comment");

// Remove anything trailing the comment
let mut root_mod_file_content_bytes = root_mod_file_content.into_bytes();
root_mod_file_content_bytes
.drain(marker_comment_start_pos + MODULE_MARKER_START_COMMENT.len()..);
let mut root_mod_file_content_bytes = root_mod_file_content;

let existing_modules = root_mod_file_content_bytes
.split_off(marker_comment_start_pos + MODULE_MARKER_START_COMMENT.len());
let generated_modules = create_modules_string(modules)?;

// Don't update the modules so the build script won't run again
if existing_modules.trim() == generated_modules.trim() {
return Ok(());
}

write!(
&mut root_mod_file_content_bytes,
"\n{}\n",
Expand Down
8 changes: 5 additions & 3 deletions generators/native_methods/src/modules.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::parse::{Class, Member};
use crate::{definitions, field, parse, registernatives, util, SymbolCollector};
use std::collections::HashMap;

use indexmap::IndexMap;
use std::path::{Path, PathBuf};

use walkdir::WalkDir;

static METHOD_DEFINITION_DIR_NAME: &str = "def";
Expand Down Expand Up @@ -204,7 +203,7 @@ pub(crate) fn get_modules_from(
))
}

let mut modules_by_root: HashMap<String, Vec<Module>> = HashMap::new();
let mut modules_by_root: IndexMap<String, Vec<Module>> = IndexMap::new();
for module in modules {
let entry = modules_by_root
.entry(module.components[0].name.clone())
Expand Down Expand Up @@ -238,6 +237,9 @@ pub(crate) fn get_modules_from(
}
}

// Need to make sure the roots are sorted so we aren't constantly making unnecessary module updates
modules_by_root.sort_keys();

// Flatten back to a Vec, sorted by root
let mut modules = Vec::new();
for (_, mods) in modules_by_root {
Expand Down
5 changes: 3 additions & 2 deletions generators/native_methods/src/registernatives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::Path;

macro_rules! native_method_table_file_header {
() => {
r#"use crate::native::{{NativeMethodDef, NativeMethodPtr}};
r#"use crate::native::method::{{NativeMethodDef, NativeMethodPtr}};
static NATIVES_REGISTERED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
Expand Down Expand Up @@ -79,7 +79,8 @@ pub(crate) fn generate_register_natives_table(

write!(
native_method_table_file,
"\t];\n\n\tfor method in natives {{\n\t\tcrate::native::insert_method(method);\n\t}}\n}}"
"\t];\n\n\tfor method in natives \
{{\n\t\tcrate::native::method::insert_method(method);\n\t}}\n}}"
)
.unwrap();
}
1 change: 0 additions & 1 deletion runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ libc.workspace = true
num_cpus = "1.16.0"
paste = { workspace = true }
platform = { path = "../platform" }
seq-macro = "0.3.5"
symbols = { path = "../symbols" }
zip = { workspace = true }

Expand Down
3 changes: 2 additions & 1 deletion runtime/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
fn main() {
println!("cargo:rerun-if-changed=generators/native_methods");
println!("cargo:rerun-if-changed=../generators/native_methods");
println!("cargo:rerun-if-changed=src/native/mod.rs");

if let Err(e) = native_methods::generate() {
panic!("Failed to generate native methods: {}", e);
Expand Down
49 changes: 36 additions & 13 deletions runtime/src/classpath/classloader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::error::{Result, RuntimeError};
use crate::modules::{Module, ModuleLockGuard, Package};
use crate::objects::class::Class;
use crate::objects::reference::Reference;
Expand All @@ -7,7 +6,7 @@ use std::cell::SyncUnsafeCell;
use std::collections::HashMap;
use std::fmt::Debug;
use std::ops::RangeInclusive;
use std::sync::{LazyLock, Mutex};
use std::sync::{Arc, LazyLock, Mutex};

use classfile::{ClassFile, FieldType};
use common::int_types::u1;
Expand All @@ -28,17 +27,19 @@ pub struct ClassLoader {
flags: ClassLoaderFlags,
obj: Reference,

unnamed_module: SyncUnsafeCell<Option<Module>>,
name: Symbol,

unnamed_module: SyncUnsafeCell<Option<Arc<Module>>>,

classes: Mutex<HashMap<Symbol, &'static Class>>,

// TODO: Is there a better way to do this?
// Keep the java.base module separate from the other modules for bootstrapping. This field is only
// valid for the bootstrap loader.
java_base: SyncUnsafeCell<Option<Module>>,
java_base: SyncUnsafeCell<Option<Arc<Module>>>,

// Access to these fields is manually synchronized with the global module mutex
modules: SyncUnsafeCell<HashMap<Symbol, Module>>,
modules: SyncUnsafeCell<HashMap<Symbol, Arc<Module>>>,
packages: SyncUnsafeCell<HashMap<Symbol, Package>>,
}

Expand All @@ -57,6 +58,16 @@ impl Debug for ClassLoader {
}
}

impl ClassLoader {
pub fn from_obj(obj: Reference) -> Option<&'static Self> {
if obj.is_null() {
return Some(Self::bootstrap());
}

todo!("Non-bootstrap classloaders")
}
}

// Module locked methods
impl ClassLoader {
pub fn insert_package_if_absent(&self, _guard: &ModuleLockGuard, package: Package) {
Expand All @@ -69,18 +80,22 @@ impl ClassLoader {
packages.get(&name)
}

pub fn insert_module(&self, _guard: &ModuleLockGuard, module: Module) {
pub fn insert_module(&self, _guard: &ModuleLockGuard, module: Module) -> Arc<Module> {
let Some(module_name) = module.name() else {
panic!("Attempted to insert an unnamed module using `insert_module`")
};

let modules = unsafe { &mut *self.modules.get() };
modules.entry(module_name).or_insert(module);
Arc::clone(
modules
.entry(module_name)
.or_insert_with(|| Arc::new(module)),
)
}

pub fn lookup_module(&self, _guard: &ModuleLockGuard, name: Symbol) -> Option<&Module> {
pub fn lookup_module(&self, _guard: &ModuleLockGuard, name: Symbol) -> Option<Arc<Module>> {
let modules = unsafe { &*self.modules.get() };
modules.get(&name)
modules.get(&name).map(Arc::clone)
}
}

Expand All @@ -92,6 +107,8 @@ impl ClassLoader {
flags: ClassLoaderFlags { is_bootstrap: true },
obj: Reference::null(),

name: Symbol::intern("bootstrap"),

unnamed_module: SyncUnsafeCell::new(None),
classes: Mutex::new(HashMap::new()),

Expand All @@ -106,10 +123,11 @@ impl ClassLoader {
unsafe { &*BOOTSTRAP_LOADER.get() }
}

pub fn java_base(&self) -> &Module {
pub fn java_base(&self) -> Arc<Module> {
assert!(self.is_bootstrap());
unsafe { &*self.java_base.get() }
.as_ref()
.map(Arc::clone)
.expect("java.base should be set")
}

Expand All @@ -120,7 +138,7 @@ impl ClassLoader {
"java.base cannot be set more than once"
);

unsafe { *ptr = Some(java_base) }
unsafe { *ptr = Some(Arc::new(java_base)) }
}

pub fn is_bootstrap(&self) -> bool {
Expand All @@ -141,7 +159,7 @@ impl ClassLoader {
);

unsafe {
*ptr = Some(entry);
*ptr = Some(Arc::new(entry));
}
}
}
Expand All @@ -152,14 +170,19 @@ impl ClassLoader {
loaded_classes.get(&name).map(|&class| class)
}

pub fn unnamed_module(&self) -> &Module {
pub fn unnamed_module(&self) -> Arc<Module> {
unsafe { &*self.unnamed_module.get() }
.as_ref()
.map(Arc::clone)
.expect("unnamed module should be set")
}
}

impl ClassLoader {
pub fn name(&self) -> Symbol {
self.name
}

pub fn obj(&self) -> Reference {
self.obj.clone()
}
Expand Down
1 change: 0 additions & 1 deletion runtime/src/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::objects::reference::Reference;
use crate::string_interner::StringInterner;
use crate::thread::{JavaThread, JavaThreadBuilder};

use crate::modules::Module;
use classfile::accessflags::MethodAccessFlags;
use common::int_types::s4;
use instructions::Operand;
Expand Down
Loading

0 comments on commit 82ffc25

Please sign in to comment.