Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Dec 3, 2024
1 parent 1258f39 commit 9261849
Show file tree
Hide file tree
Showing 18 changed files with 426 additions and 170 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ libc = "0.2"
libloading = "0.8.5"
tracing = "0.1.41"
paste = "1.0.15"
zip = "2.2.1"
zip = { version = "2.2.1", default-features = false }

# Nested workspace members
tools = { path = "tools" }
Expand Down
33 changes: 32 additions & 1 deletion common/src/endian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,51 @@ pub enum Endian {
}

impl Endian {
pub fn native() -> Self {
/// Get the native `Endian` for this target
///
/// # Examples
///
/// ```rust
/// use common::endian::Endian;
///
/// let endian = Endian::native();
/// assert_eq!(endian, Endian::Little);
/// ```
pub const fn native() -> Self {
#[cfg(target_endian = "little")]
return Endian::Little;
#[cfg(target_endian = "big")]
return Endian::Big;
}

/// Convert this `Endian` to the opposite value
///
/// # Examples
///
/// ```rust
/// use common::endian::Endian;
///
/// let endian = Endian::Little;
/// assert_eq!(endian.invert(), Endian::Big);
/// ```
pub fn invert(self) -> Self {
match self {
Self::Little => Self::Big,
Self::Big => Self::Little,
}
}

/// Whether this `Endian` is this target's endianness
///
/// # Examples
///
/// ```rust
/// use common::endian::Endian;
///
/// let endian = Endian::Little;
/// assert!(endian.is_target());
/// assert!(!Endian::Big.is_target());
/// ```
pub fn is_target(self) -> bool {
match self {
Self::Little => cfg!(target_endian = "little"),
Expand Down
8 changes: 8 additions & 0 deletions common/src/int_types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
//! Java specification integer types
//!
//! The Java specification uses integers specified by their size in **bytes** rather than **bits**.
//! For example [`u1`] is a [`u8`](core::primitive::u8).
//!
//! These types names are used throughout the various parsers (ex. [`JavaReadExt`](crate::traits::JavaReadExt))
//! as well as in the runtime.
#![allow(non_camel_case_types)]

pub type u1 = ::core::primitive::u8;
Expand Down
8 changes: 8 additions & 0 deletions common/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use std::io::Read;

use byteorder::{BigEndian, LittleEndian, ReadBytesExt};

/// Big endian read operations for Java integer types
///
/// Java's specification uses big endian, so this is the default "Java" reader extension trait.
/// See [`JavaLittleEndianRead`] for the little endian equivalents.
pub trait JavaReadExt: Read {
fn read_u1(&mut self) -> Result<u1> {
let mut buf = [0u8; 1];
Expand Down Expand Up @@ -47,6 +51,9 @@ pub trait JavaReadExt: Read {

impl<R: Read> JavaReadExt for R {}

/// Little endian read operations for Java integer types
///
/// See [`JavaReadExt`] for the big endian counterpart.
pub trait JavaLittleEndianRead: Read {
fn read_u4(&mut self) -> Result<u4> {
let mut buf = [0u8; 4];
Expand Down Expand Up @@ -77,6 +84,7 @@ pub trait JavaLittleEndianRead: Read {

impl<R: Read> JavaLittleEndianRead for R {}

/// An extension trait for [`Endian`](crate::endian::Endian) for reading Java integer types
pub trait JavaEndianAwareRead<R: Read> {
fn read_u1(self, reader: &mut R) -> Result<u1>;
fn read_u4(self, reader: &mut R) -> Result<u4>;
Expand Down
22 changes: 22 additions & 0 deletions generators/native_methods/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub enum Error {
Io(std::io::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),
}
}
}

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

impl core::error::Error for Error {}
38 changes: 18 additions & 20 deletions generators/native_methods/src/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::error::Result;
use crate::modules::Module;
use crate::parse::{AccessFlags, Method};
use crate::SymbolCollector;
Expand Down Expand Up @@ -50,7 +51,7 @@ pub(crate) fn generate_intrinsics<'a>(
generated_directory: &Path,
modules: &[Module],
symbol_collector: &mut SymbolCollector,
) {
) -> Result<()> {
let mut intrinsic_methods = HashMap::new();
for module in modules {
module.for_each_class(|class| {
Expand Down Expand Up @@ -79,8 +80,7 @@ pub(crate) fn generate_intrinsics<'a>(
.write(true)
.truncate(true)
.create(true)
.open(generated_file_path)
.unwrap();
.open(generated_file_path)?;

// + 1 to account for the null ID
let total_ids = intrinsic_methods.len() + 1;
Expand All @@ -89,8 +89,7 @@ pub(crate) fn generate_intrinsics<'a>(
&mut generated_file,
"{}",
format_args!(generated_file_header!(), total_ids)
)
.unwrap();
)?;

writeln!(
&mut generated_file,
Expand All @@ -99,31 +98,30 @@ pub(crate) fn generate_intrinsics<'a>(
create_intrinsic_name_table(
std::iter::once("None").chain(intrinsic_methods.keys().map(String::as_str)),
total_ids
)
)
.unwrap();
)?
)?;

writeln!(
&mut generated_file,
"{}",
create_intrinsic_id_enum(
std::iter::once("None").chain(intrinsic_methods.keys().map(String::as_str))
)
)
.unwrap();
)?
)?;

writeln!(
&mut generated_file,
"{}",
create_method_mappings(intrinsic_methods.iter())
)
.unwrap();
create_method_mappings(intrinsic_methods.iter())?
)?;

Ok(())
}

fn create_intrinsic_name_table<'a>(
intrinsic_ids: impl Iterator<Item = &'a str>,
total_ids: usize,
) -> String {
) -> Result<String> {
let mut intrinsic_name_table = format!(
"pub(in crate::native) static INTRINSIC_NAME_TABLE: [&[u1]; {}] = [\n",
total_ids
Expand All @@ -133,11 +131,11 @@ fn create_intrinsic_name_table<'a>(
}

writeln!(intrinsic_name_table, "];").unwrap();
intrinsic_name_table
Ok(intrinsic_name_table)
}

/// Creates the `IntrinsicId` enum
fn create_intrinsic_id_enum<'a>(intrinsic_ids: impl Iterator<Item = &'a str>) -> String {
fn create_intrinsic_id_enum<'a>(intrinsic_ids: impl Iterator<Item = &'a str>) -> Result<String> {
let mut intrinsic_name_enum = String::from(
"#[allow(non_camel_case_types)]\n#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, \
Debug)]\npub enum IntrinsicId {\n",
Expand All @@ -147,13 +145,13 @@ fn create_intrinsic_id_enum<'a>(intrinsic_ids: impl Iterator<Item = &'a str>) ->
}

intrinsic_name_enum.push('}');
intrinsic_name_enum
Ok(intrinsic_name_enum)
}

/// Creates the `IntrinsicId::for_method` method
fn create_method_mappings<'a>(
intrinsic_ids: impl Iterator<Item = (&'a String, &'a (String, IntrinsicMethodDefinition))>,
) -> String {
) -> Result<String> {
let mut intrinsic_id_method_mapping = String::from(
r#"
impl IntrinsicId {
Expand Down Expand Up @@ -193,5 +191,5 @@ impl IntrinsicId {
"\t\t\t_ => return IntrinsicId::None,\n\t\t}}\n\n\t\treturn IntrinsicId::None;\n\t}}\n}}"
)
.unwrap();
intrinsic_id_method_mapping
Ok(intrinsic_id_method_mapping)
}
Loading

0 comments on commit 9261849

Please sign in to comment.