diff --git a/.gitignore b/.gitignore
index ea8c4bf..023c447 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
+.idea
+*.iml
+
/target
+
+*.class
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index d4e3fca..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Datasource local storage ignored files
-/../../../../../../../:\Users\nilsh\CLionProjects\rust\coldsquare\.idea/dataSources/
-/dataSources.local.xml
-# Editor-based HTTP Client requests
-/httpRequests/
diff --git a/.idea/coldsquare.iml b/.idea/coldsquare.iml
deleted file mode 100644
index c254557..0000000
--- a/.idea/coldsquare.iml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/discord.xml b/.idea/discord.xml
deleted file mode 100644
index cd711a0..0000000
--- a/.idea/discord.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 461fec0..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 5f77177..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/execute/model.rs b/src/execute/model.rs
index 5a5990e..66606be 100644
--- a/src/execute/model.rs
+++ b/src/execute/model.rs
@@ -4,9 +4,7 @@ pub struct OperandStack {
impl OperandStack {
pub fn new() -> OperandStack {
- OperandStack {
- vec: vec![],
- }
+ OperandStack { vec: vec![] }
}
pub fn pop(&mut self) -> u32 {
@@ -19,19 +17,17 @@ impl OperandStack {
pub fn swap(&mut self) {
let len = self.vec.len();
- self.vec.swap(len- 1, len - 2);
+ self.vec.swap(len - 1, len - 2);
}
}
pub struct LocalVariables {
- vec: Vec
+ vec: Vec,
}
impl LocalVariables {
pub fn new(size: usize) -> LocalVariables {
- LocalVariables {
- vec: vec![0; size]
- }
+ LocalVariables { vec: vec![0; size] }
}
pub fn store(&mut self, address: u8, value: u32) {
@@ -49,12 +45,11 @@ impl LocalVariables {
pub fn load2(&self, address: u8) -> (u32, u32) {
(self.vec[address as usize], self.vec[address as usize + 1])
}
-
}
#[cfg(test)]
mod tests {
- use crate::model::{LocalVariables, OperandStack};
+ use crate::execute::model::{LocalVariables, OperandStack};
#[test]
fn operand_stack() {
@@ -84,4 +79,4 @@ mod tests {
assert_eq!(vars.load(3), 100);
assert_eq!(vars.load(4), 466);
}
-}
\ No newline at end of file
+}
diff --git a/src/lib.rs b/src/lib.rs
index 14367f3..7948beb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,2 +1,8 @@
+use crate::parse::{ClassFile, ParseErr};
+
+mod execute;
mod parse;
-mod execute;
\ No newline at end of file
+
+pub fn parse_class_file(file: Vec) -> Result {
+ parse::parse_class_file(file)
+}
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..18be829 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,10 @@
+use coldsquare::parse_class_file;
+
fn main() {
- println!("Hello, world!");
+ let file = "primeNumberChecker.class";
+ let file = std::fs::read(file).unwrap();
+
+ let class_file = parse_class_file(file).unwrap();
+
+ println!("{:?}", class_file);
}
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 3ced475..7ce4d69 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -1,14 +1,22 @@
-use crate::parse::model::{u1, u2, u4, ClassFile, CpInfo};
-
mod model;
+pub use model::*;
+use std::path::Prefix::Verbatim;
-struct ParseErr;
+#[derive(Debug)]
+pub struct ParseErr;
+
+pub type Result = std::result::Result;
struct Data {
data: Vec,
pointer: usize,
}
+pub fn parse_class_file(data: Vec) -> Result {
+ let mut data = Data { data, pointer: 0 };
+ ClassFile::parse(&mut data)
+}
+
impl From> for Data {
fn from(data: Vec) -> Self {
Self { data, pointer: 0 }
@@ -16,67 +24,422 @@ impl From> for Data {
}
impl Data {
- fn u1(&mut self) -> Result {
+ fn u1(&mut self) -> Result {
let item = self.data.get(self.pointer).cloned();
self.pointer += 1;
item.ok_or(ParseErr)
}
- fn u2(&mut self) -> Result {
- Ok(((self.u1()? as u2) << 8) | self.u1() as u2)
+ fn u2(&mut self) -> Result {
+ Ok(((self.u1()? as u2) << 8) | self.u1()? as u2)
}
- fn u4(&mut self) -> Result {
- Ok(((self.u2()? as u4) << 16) | self.u2() as u4)
+ fn u4(&mut self) -> Result {
+ Ok(((self.u2()? as u4) << 16) | self.u2()? as u4)
}
- fn last_u1(&mut self) -> Result {
+ fn last_u1(&self) -> Result {
self.data.get(self.pointer - 1).cloned().ok_or(ParseErr)
}
- fn last_u2(&mut self) -> Result {
- let last2u1 = self.data.get(self.pointer - 2).cloned().ok_or(ParseErr);
- Ok(((self.last_u1()? as u2) << 8) | last2u1 as u2)
+ fn last_u2(&self) -> Result {
+ let last2u1 = self.data.get(self.pointer - 2).cloned().ok_or(ParseErr)?;
+ Ok(((last2u1 as u2) << 8) | self.last_u1()? as u2)
+ }
+
+ fn last_u4(&self) -> Result {
+ let last2u1 = self.data.get(self.pointer - 3).cloned().ok_or(ParseErr)?;
+ let last3u1 = self.data.get(self.pointer - 4).cloned().ok_or(ParseErr)?;
+ Ok(((last3u1 as u4) << 24) | ((last2u1 as u4) << 16) | self.last_u2()? as u4)
}
}
pub trait Parse {
- fn parse(data: &mut Data) -> Result;
+ fn parse(data: &mut Data) -> Result
+ where
+ Self: Sized;
}
pub trait ParseVec {
- fn parse_vec(data: &mut Data, len: usize) -> Result;
-}
-
-impl Parse for ClassFile {
- fn parse(data: &mut Data) -> Result {
- Ok(Self {
- magic: data.u4()?,
- minor_version: data.u2()?,
- major_version: data.u2()?,
- constant_pool_count: data.u2()?,
- constant_pool: Vec::parse_vec::(data, data.last_u2() as usize)?,
- access_flags: data.u2()?,
- this_class: data.u2()?,
- super_class: data.u2()?,
- interfaces_count: data.u2()?,
- interfaces: vec![],
- fields_count: 0,
- fields: vec![],
- method_count: 0,
- methods: vec![],
- attributes_count: 0,
- attributes: vec![],
- })
- }
+ fn parse_vec(data: &mut Data, len: usize) -> Result
+ where
+ Self: Sized;
}
impl ParseVec for Vec {
- fn parse_vec(data: &mut Data, len: usize) -> Result {
+ fn parse_vec(data: &mut Data, len: usize) -> Result {
let mut vec = Vec::with_capacity(len);
- for i in 0..len {
+ for _ in 0..len {
vec.push(T::parse(data)?);
}
Ok(vec)
}
}
+
+macro_rules! parse_primitive {
+ ($value:ident) => {
+ impl Parse for $value {
+ fn parse(data: &mut Data) -> Result
+ where
+ Self: Sized,
+ {
+ data.$value()
+ }
+ }
+ };
+}
+
+parse_primitive!(u1);
+parse_primitive!(u2);
+parse_primitive!(u4);
+
+impl Parse for ClassFile {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ magic: data.u4()?,
+ minor_version: data.u2()?,
+ major_version: data.u2()?,
+ constant_pool_count: data.u2()?,
+ constant_pool: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ access_flags: data.u2()?,
+ this_class: data.u2()?,
+ super_class: data.u2()?,
+ interfaces_count: data.u2()?,
+ interfaces: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ fields_count: data.u2()?,
+ fields: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ method_count: data.u2()?,
+ methods: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ attributes_count: data.u2()?,
+ attributes: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ })
+ }
+}
+
+impl Parse for CpInfo {
+ fn parse(data: &mut Data) -> Result {
+ let tag = data.u1()?;
+
+ Ok(match tag {
+ 7 => Self::Class {
+ tag,
+ name_index: data.u2()?,
+ },
+ 9 => Self::Fieldref {
+ tag,
+ class_index: data.u2()?,
+ name_and_type_index: data.u2()?,
+ },
+ 10 => Self::Methodref {
+ tag,
+ class_index: data.u2()?,
+ name_and_type_index: data.u2()?,
+ },
+ 11 => Self::InterfaceMethodref {
+ tag,
+ class_index: data.u2()?,
+ name_and_type_index: data.u2()?,
+ },
+ 8 => Self::String {
+ tag,
+ string_index: data.u2()?,
+ },
+ 3 => Self::Integer {
+ tag,
+ bytes: data.u4()?,
+ },
+ 4 => Self::Float {
+ tag,
+ bytes: data.u4()?,
+ },
+ 5 => Self::Long {
+ tag,
+ high_bytes: data.u4()?,
+ low_bytes: data.u4()?,
+ },
+ 6 => Self::Double {
+ tag,
+ high_bytes: data.u4()?,
+ low_bytes: data.u4()?,
+ },
+ 12 => Self::NameAndType {
+ tag,
+ name_index: data.u2()?,
+ descriptor_index: data.u2()?,
+ },
+ 1 => Self::Utf8 {
+ tag,
+ length: data.u2()?,
+ bytes: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ },
+ 15 => Self::MethodHandle {
+ tag,
+ reference_kind: data.u1()?,
+ reference_index: data.u2()?,
+ },
+ 16 => Self::MethodType {
+ tag,
+ descriptor_index: data.u2()?,
+ },
+ 18 => Self::InvokeDynamic {
+ tag,
+ bootstrap_method_attr_index: data.u2()?,
+ name_and_type_index: data.u2()?,
+ },
+ _ => Err(ParseErr)?,
+ })
+ }
+}
+
+impl Parse for FieldInfo {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ access_flags: data.u2()?,
+ name_index: data.u2()?,
+ descriptor_index: data.u2()?,
+ attributes_count: data.u2()?,
+ attributes: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ })
+ }
+}
+
+impl Parse for MethodInfo {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ access_flags: data.u2()?,
+ name_index: data.u2()?,
+ descriptor_index: data.u2()?,
+ attributes_count: data.u2()?,
+ attributes: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ })
+ }
+}
+
+impl Parse for Attribute {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ attribute_name_index: data.u2()?,
+ attribute_length: data.u4()?,
+ attribute_content: Vec::parse_vec(data, data.last_u4()? as usize)?,
+ })
+ }
+}
+
+impl Parse for AttributeCodeException {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ start_pc: data.last_u2()?,
+ end_pc: data.last_u2()?,
+ handler_pc: data.last_u2()?,
+ catch_type: data.last_u2()?,
+ })
+ }
+}
+
+impl Parse for StackMapFrame {
+ fn parse(data: &mut Data) -> Result {
+ let frame_type = data.u1()?;
+
+ Ok(match frame_type {
+ 0..=63 => Self::SameFrame { frame_type },
+ 64..=127 => Self::SameLocals1StackItemFrame {
+ frame_type,
+ stack: VerificationTypeInfo::parse(data)?,
+ },
+ 247 => Self::SameLocals1StackItemFrameExtended {
+ frame_type,
+ offset_delta: data.u2()?,
+ stack: VerificationTypeInfo::parse(data)?,
+ },
+ 246..=250 => Self::ChopFrame {
+ frame_type,
+ offset_delta: data.u2()?,
+ },
+ 251 => Self::SameFrameExtended {
+ frame_type,
+ offset_delta: data.u2()?,
+ },
+ 252..=254 => Self::AppendFrame {
+ frame_type,
+ offset_delta: data.u2()?,
+ locals: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ },
+ 255 => Self::FullFrame {
+ frame_type,
+ offset_delta: data.u2()?,
+ number_of_locals: data.u2()?,
+ locals: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ number_of_stack_items: data.u2()?,
+ stack: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ },
+ _ => Err(ParseErr)?,
+ })
+ }
+}
+
+impl Parse for VerificationTypeInfo {
+ fn parse(data: &mut Data) -> Result
+ where
+ Self: Sized,
+ {
+ let tag = data.u1()?;
+ Ok(match tag {
+ 0 => Self::Top { tag },
+ 1 => Self::Integer { tag },
+ 2 => Self::Float { tag },
+ 4 => Self::Long { tag },
+ 3 => Self::Double { tag },
+ 5 => Self::Null { tag },
+ 6 => Self::UninitializedThis { tag },
+ 7 => Self::Object {
+ tag,
+ cpool_index: data.u2()?,
+ },
+ 8 => Self::Uninitialized {
+ tag,
+ offset: data.u2()?,
+ },
+ _ => Err(ParseErr)?,
+ })
+ }
+}
+
+impl Parse for AttributeInnerClass {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ inner_class_info_index: data.u2()?,
+ outer_class_info_index: data.u2()?,
+ inner_class_name_index: data.u2()?,
+ inner_class_access_flags: data.u2()?,
+ })
+ }
+}
+
+impl Parse for AttributeLineNumber {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ start_pc: data.u2()?,
+ line_number: data.u2()?,
+ })
+ }
+}
+
+impl Parse for AttributeLocalVariableTable {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ start_pc: data.u2()?,
+ length: data.u2()?,
+ name_index: data.u2()?,
+ descriptor_or_signature_index: data.u2()?,
+ index: data.u2()?,
+ })
+ }
+}
+
+impl Parse for Annotation {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ type_index: data.u2()?,
+ num_element_value_pairs: data.u2()?,
+ element_value_pairs: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ })
+ }
+}
+
+impl Parse for AnnotationElementValuePair {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ element_name_index: data.u2()?,
+ element_name_name: AnnotationElementValue::parse(data)?,
+ })
+ }
+}
+
+impl Parse for AnnotationElementValue {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ tag: data.u1()?,
+ value: AnnotationElementValueValue::parse(data)?,
+ })
+ }
+}
+
+impl Parse for AnnotationElementValueValue {
+ fn parse(data: &mut Data) -> Result {
+ let tag = data.last_u1()? as char;
+ Ok(match tag {
+ 'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z' | 's' => {
+ Self::ConstValueIndex { index: data.u2()? }
+ }
+ 'e' => Self::EnumConstValue {
+ type_name_index: data.u2()?,
+ const_name_index: data.u2()?,
+ },
+ 'c' => Self::ClassInfoIndex { index: data.u2()? },
+ '@' => Self::AnnotationValue {
+ annotation: Box::new(Annotation::parse(data)?),
+ },
+ '[' => Self::ArrayValue {
+ num_values: data.u2()?,
+ values: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ },
+ _ => Err(ParseErr)?,
+ })
+ }
+}
+
+impl Parse for ParameterAnnotation {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ num_annotations: data.u2()?,
+ annotations: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ })
+ }
+}
+
+impl Parse for BootstrapMethod {
+ fn parse(data: &mut Data) -> Result {
+ Ok(Self {
+ bootstrap_method_ref: data.u2()?,
+ num_bootstrap_arguments: data.u2()?,
+ bootstrap_arguments: Vec::parse_vec(data, data.last_u2()? as usize)?,
+ })
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::parse::Data;
+
+ #[test]
+ fn data_u1() {
+ let mut data = Data {
+ data: vec![0xff, 0x00],
+ pointer: 0,
+ };
+ assert_eq!(data.u1().unwrap(), 0xff);
+ assert_eq!(data.u1().unwrap(), 0x00);
+ assert_eq!(data.last_u1().unwrap(), 0x00);
+ }
+
+ #[test]
+ fn data_u2() {
+ let mut data = Data {
+ data: vec![0xff, 0x33, 0x11, 0x00],
+ pointer: 0,
+ };
+ assert_eq!(data.u2().unwrap(), 0xff33);
+ assert_eq!(data.u2().unwrap(), 0x1100);
+ assert_eq!(data.last_u2().unwrap(), 0x1100);
+ }
+
+ #[test]
+ fn data_u4() {
+ let mut data = Data {
+ data: vec![0xff, 0x33, 0x11, 0x00],
+ pointer: 0,
+ };
+ assert_eq!(data.u4().unwrap(), 0xff331100);
+ assert_eq!(data.last_u4().unwrap(), 0xff331100);
+ }
+}
diff --git a/src/parse/model.rs b/src/parse/model.rs
index e52e30d..12666a5 100644
--- a/src/parse/model.rs
+++ b/src/parse/model.rs
@@ -14,44 +14,46 @@ pub type u4 = u32;
///
/// # Represents a .class file
///
+#[derive(Debug, Clone, Hash)]
pub struct ClassFile {
/// Magic number identifying the format (= 0xCAFEBABE)
- pub(crate) magic: u4,
+ pub magic: u4,
/// The version of the class file (.X)
- pub(crate) minor_version: u2,
+ pub minor_version: u2,
/// The version of the class file (X.)
- pub(crate) major_version: u2,
+ pub major_version: u2,
/// Number of entries in the constant pool + 1
- pub(crate) constant_pool_count: u2,
+ pub constant_pool_count: u2,
/// The constant pool. Indexed from 1 to constant_pool_count - 1
- pub(crate) constant_pool: Vec,
+ pub constant_pool: Vec,
/// Mask of `ClassAccessFlag` used to denote access permissions
- pub(crate) access_flags: u2,
+ pub access_flags: u2,
/// A valid index into the `constant_pool` table. The entry must be a `ConstantClassInfo`
- pub(crate) this_class: u2,
+ pub this_class: u2,
/// Zero or a valid index into the `constant_pool` table
- pub(crate) super_class: u2,
+ pub super_class: u2,
/// The number if direct superinterfaces of this class or interface type
- pub(crate) interfaces_count: u2,
+ pub interfaces_count: u2,
/// Each entry must be a valid index into the `constant_pool` table. The entry must be a `ConstantClassInfo`
- pub(crate) interfaces: Vec,
+ pub interfaces: Vec,
/// The number of fields in the `fields` table
- pub(crate) fields_count: u2,
+ pub fields_count: u2,
/// All fields of the class. Contains only fields of the class itself
- pub(crate) fields: Vec,
+ pub fields: Vec,
/// The number of methods in `methods`
- pub(crate) method_count: u2,
+ pub method_count: u2,
/// All methods of the class. If it's neither Native nor Abstract, the implementation has to be provided too
- pub(crate) methods: Vec,
+ pub methods: Vec,
/// The number of attributes in `attributes`
- pub(crate) attributes_count: u2,
+ pub attributes_count: u2,
/// All attributes of the class
- pub(crate) attributes: Vec,
+ pub attributes: Vec,
}
/// A constant from the constant pool
/// May have indices back to the constant pool, with expected types
/// _index: A valid index into the `constant_pool` table.
+#[derive(Debug, Clone, Hash)]
pub enum CpInfo {
Class {
tag: u1, // 7
@@ -139,7 +141,7 @@ pub enum CpInfo {
descriptor_index: u2,
},
InvokeDynamic {
- tag: u1,
+ tag: u1, // 18
/// Must be a valid index into the `bootstrap_methods` array of the bootstrap method table of this class fiel
bootstrap_method_attr_index: u2,
/// Entry must `NameAndType`
@@ -148,26 +150,36 @@ pub enum CpInfo {
}
/// Information about a field
+#[derive(Debug, Clone, Hash)]
pub struct FieldInfo {
- access_flags: u2,
- name_index: u2,
- descriptor_index: u2,
- attributes_count: u2,
- attributes: Vec,
+ pub access_flags: u2,
+ pub name_index: u2,
+ pub descriptor_index: u2,
+ pub attributes_count: u2,
+ pub attributes: Vec,
}
/// Information about a method
+#[derive(Debug, Clone, Hash)]
pub struct MethodInfo {
/// Mask of `MethodAccessFlag` used to denote access permissions
- access_flags: u2,
+ pub access_flags: u2,
/// Index to the `constant_pool` of the method name, must be `Utf8`
- name_index: u2,
+ pub name_index: u2,
/// Index to the `constant_pool` of the method descriptor, must be `Utf8`
- descriptor_index: u2,
+ pub descriptor_index: u2,
/// The amount of attributes for this method
- attributes_count: u2,
+ pub attributes_count: u2,
/// The attributes for this method
- attributes: Vec,
+ pub attributes: Vec,
+}
+
+/// See `AttributeInfo`
+#[derive(Debug, Clone, Hash)]
+pub struct Attribute {
+ pub attribute_name_index: u2,
+ pub attribute_length: u4,
+ pub attribute_content: Vec,
}
/// Information about an attribute
@@ -176,6 +188,8 @@ pub struct MethodInfo {
/// `attribute_length`: The length of the subsequent bytes, does not include the first 6
///
/// _index: Index to the `constant_pool` table of any type
+#[derive(Debug, Clone, Hash)]
+#[allow(dead_code)] // todo yeah lol
pub enum AttributeInfo {
/// Only on fields, the constant value of that field
ConstantValue {
@@ -202,7 +216,7 @@ pub enum AttributeInfo {
exception_table: Vec,
attributes_count: u2,
/// The attributes of the code
- attributes: Vec,
+ attributes: Vec,
},
/// Only on the `Code` attribute, used for verification
/// May be implicit on version >= 50.0, with no entries
@@ -336,22 +350,24 @@ pub enum AttributeInfo {
}
/// An exception handler in the JVM bytecode array
+#[derive(Debug, Clone, Hash)]
pub struct AttributeCodeException {
/// The ranges in the code in which the handler is active. Must be a valid index into the code array.
/// The `start_pc` is inclusive
- start_pc: u2,
+ pub start_pc: u2,
/// The ranges in the code in which the handler is active. Must be a valid index into the code array or the length.
/// The `end_pc` is exclusive
- end_pc: u2,
+ pub end_pc: u2,
/// The start of the exception handler, must be a valid index into the code array at an opcode instruction
- handler_pc: u2,
+ pub handler_pc: u2,
/// If the catch type is nonzero, it must be a valid index into the `constant_pool`, must be a `Class`
/// Zero means it catches all Exceptions, this is usually for `finally`
- catch_type: u2,
+ pub catch_type: u2,
}
/// Specifies the type state at a particular bytecode offset
/// Has a offset_delta, the offset is calculated by adding offset_delta + 1 to the previous offset
+#[derive(Debug, Clone, Hash)]
pub enum StackMapFrame {
/// Exactly the same locals as the previous frame and zero stack items, offset_delta is frame_type
SameFrame {
@@ -364,7 +380,7 @@ pub enum StackMapFrame {
},
/// Exactly the same locals as the previous frame and 1 stack item, offset_delta is given explicitly
SameLocals1StackItemFrameExtended {
- frame_type: u1, // 257
+ frame_type: u1, // 247
offset_delta: u2,
stack: VerificationTypeInfo,
},
@@ -397,6 +413,7 @@ pub enum StackMapFrame {
}
/// A stack value/local variable type `StackMapFrame`
+#[derive(Debug, Clone, Hash)]
pub enum VerificationTypeInfo {
Top {
tag: u1, // 0
@@ -431,64 +448,71 @@ pub enum VerificationTypeInfo {
}
/// A struct for the `AttributeInfo::InnerClasses`
+#[derive(Debug, Clone, Hash)]
pub struct AttributeInnerClass {
/// Must be a `Class`
- inner_class_info_index: u2,
+ pub inner_class_info_index: u2,
/// Must be 0 or a `Class`
- outer_class_info_index: u2,
+ pub outer_class_info_index: u2,
/// Must be 0 or `Utf8`
- inner_class_name_index: u2,
+ pub inner_class_name_index: u2,
/// Must be a mask of `InnerClassAccessFlags`
- inner_class_access_flags: u2,
+ pub inner_class_access_flags: u2,
}
/// Line number information for `AttributeInfo::LineNumberTable`
+#[derive(Debug, Clone, Hash)]
pub struct AttributeLineNumber {
/// Index into the code array where a new line in the source begins
- start_pc: u2,
+ pub start_pc: u2,
/// The line number in the source file
- line_number: u2,
+ pub line_number: u2,
}
/// Local variable information for `AttributeInfo::LocalVariableTable` and `AttributeInfo::LocalVariableTypeTable`
+#[derive(Debug, Clone, Hash)]
pub struct AttributeLocalVariableTable {
/// The local variable must have a value between `start_pc` and `start_pc + length`. Must be a valid opcode
- start_pc: u2,
+ pub start_pc: u2,
/// The local variable must have a value between `start_pc` and `start_pc + length`
- length: u2,
+ pub length: u2,
/// Must be `Utf8`
- name_index: u2,
+ pub name_index: u2,
/// Must be `Utf8`, field descriptor or field signature encoding the type
- descriptor_or_signature_index: u2,
+ pub descriptor_or_signature_index: u2,
/// The variable must be at `index` in the local variable array
- index: u2,
+ pub index: u2,
}
/// A runtime-visible annotation to the program
+#[derive(Debug, Clone, Hash)]
pub struct Annotation {
/// Must be `Utf8`
- type_index: u2,
- num_element_value_pairs: u2,
- element_value_pairs: Vec,
+ pub type_index: u2,
+ pub num_element_value_pairs: u2,
+ pub element_value_pairs: Vec,
}
// these type names have just become java at this point. no shame.
/// A element-value pair in the `Annotation`
+#[derive(Debug, Clone, Hash)]
pub struct AnnotationElementValuePair {
/// Must be `Utf8`
- element_name_index: u2,
- element_name_name: AnnotationElementValue,
+ pub element_name_index: u2,
+ pub element_name_name: AnnotationElementValue,
}
/// The value of an `AnnotationElementValuePair`
+#[derive(Debug, Clone, Hash)]
pub struct AnnotationElementValue {
/// B, C, D, F, I, J, S, Z or s, e, c, @,
- tag: u1,
- value: AnnotationElementValueValue,
+ pub tag: u1,
+ pub value: AnnotationElementValueValue,
}
/// The value of a `AnnotationElementValue`
+#[derive(Debug, Clone, Hash)]
pub enum AnnotationElementValueValue {
/// If the tag is B, C, D, F, I, J, S, Z, or s.
ConstValueIndex {
@@ -520,24 +544,27 @@ pub enum AnnotationElementValueValue {
}
/// Used in `AttributeInfo::RuntimeVisibleParameterAnnotations`
+#[derive(Debug, Clone, Hash)]
pub struct ParameterAnnotation {
- num_annotations: u2,
- annotations: Vec,
+ pub num_annotations: u2,
+ pub annotations: Vec,
}
/// Used in `AttributeInfo::BootstrapMethods `
+#[derive(Debug, Clone, Hash)]
pub struct BootstrapMethod {
/// Must be a `MethodHandle`
- bootstrap_method_ref: u2,
- num_bootstrap_arguments: u2,
+ pub bootstrap_method_ref: u2,
+ pub num_bootstrap_arguments: u2,
/// Each argument is a cpool entry. The constants must be `String, Class, Integer, Long, Float, Double, MethodHandle, or MethodType`
- bootstrap_arguments: Vec,
+ pub bootstrap_arguments: Vec,
}
/////// Access Flags
/// Access Flags of a class
#[repr(u16)]
+#[derive(Debug, Clone, Hash)]
pub enum ClassAccessFlag {
/// Declared public; may be accessed from outside its package.
Public = 0x0001,
@@ -559,6 +586,7 @@ pub enum ClassAccessFlag {
/// Access Flags of a method
#[repr(u16)]
+#[derive(Debug, Clone, Hash)]
pub enum MethodAccessFlag {
// Declared public; may be accessed from outside its package.
PUBLIC = 0x0001,
@@ -588,6 +616,7 @@ pub enum MethodAccessFlag {
/// Access flags for an inner class
#[repr(u16)]
+#[derive(Debug, Clone, Hash)]
pub enum InnerClassAccessFlags {
/// Marked or implicitly public in source.
PUBLIC = 0x0001,
@@ -613,6 +642,7 @@ pub enum InnerClassAccessFlags {
/// Access flags for a field
#[repr(u16)]
+#[derive(Debug, Clone, Hash)]
pub enum FieldAccessFlags {
/// Declared public; may be accessed from outside its package.
PUBLIC = 0x0001,