use std::collections::BTreeMap;
pub const MAGIC: &[u8] = &[0xCA, 0xFE, 0xBA, 0xBE];
#[derive(Debug)]
pub struct Class {
pub minor_version: u16,
pub major_version: u16,
pub access_flags: AccessFlags,
pub name: u16,
pub super_name: u16,
pub interfaces: Vec<u16>,
pub fields: Vec<Field>,
pub methods: Vec<Method>,
pub attributes: Vec<Attribute>,
}
#[derive(Debug)]
pub struct Field {
pub access_flags: AccessFlags,
pub name: u16,
pub desc: u16,
pub attributes: Vec<Attribute>,
}
#[derive(Debug)]
pub struct Method {
pub access_flags: AccessFlags,
pub name: u16,
pub desc: u16,
pub attributes: Vec<Attribute>,
}
#[derive(Debug)]
pub enum Attribute {
AnnotationDefault(ElementValue),
BootstrapMethods(Vec<BootstrapMethod>),
Code {
max_stack: u16,
max_locals: u16,
instructions: Vec<Option<Instruction>>,
exceptions: Vec<Exception>,
attributes: Vec<Attribute>,
},
ConstantValue(u16),
Deprecated,
EnclosingMethod {
class_index: u16,
method_index: u16,
},
Exceptions(Vec<u16>),
InnerClasses(Vec<InnerClass>),
LineNumberTable(Vec<LineNumber>),
LocalVariableTable(Vec<LocalVariable>),
LocalVariableTypeTable(Vec<LocalVariableType>),
MethodParameters(Vec<MethodParameter>),
Module {
name: u16,
flags: AccessFlags,
version: u16,
requires: Vec<Requirement>,
exports: Vec<Export>,
opens: Vec<Opening>,
uses: Vec<u16>,
provides: Vec<Provider>,
},
ModuleMainClass(u16),
ModulePackages(Vec<u16>),
RuntimeVisibleAnnotations(Vec<Annotation>),
RuntimeInvisibleAnnotations(Vec<Annotation>),
RuntimeVisibleParameterAnnotations(Vec<Vec<Annotation>>),
RuntimeInvisibleParameterAnnotations(Vec<Vec<Annotation>>),
RuntimeVisibleTypeAnnotations(Vec<TypeAnnotation>),
RuntimeInvisibleTypeAnnotations(Vec<TypeAnnotation>),
Signature(u16),
Synthetic,
SourceFile(u16),
SourceDebugExtension(String),
StackMapTable(Vec<StackMapFrame>),
Unknown(u16, Vec<u8>),
}
bitflags! {
pub struct AccessFlags: u16 {
const PUBLIC = 0b0000_0000_0000_0001;
const PRIVATE = 0b0000_0000_0000_0010;
const PROTECTED = 0b0000_0000_0000_0100;
const STATIC = 0b0000_0000_0000_1000;
const FINAL = 0b0000_0000_0001_0000;
const SUPER = 0b0000_0000_0010_0000;
const SYNCHRONIZED = 0b0000_0000_0010_0000;
const VOLATILE = 0b0000_0000_0100_0000;
const BRIDGE = 0b0000_0000_0100_0000;
const STATIC_PHASE = 0b0000_0000_0100_0000;
const TRANSIENT = 0b0000_0000_1000_0000;
const VARARGS = 0b0000_0000_1000_0000;
const NATIVE = 0b0000_0001_0000_0000;
const INTERFACE = 0b0000_0010_0000_0000;
const ABSTRACT = 0b0000_0100_0000_0000;
const STRICT = 0b0000_1000_0000_0000;
const SYNTHETIC = 0b0001_0000_0000_0000;
const ANNOTATION = 0b0010_0000_0000_0000;
const ENUM = 0b0100_0000_0000_0000;
const MODULE = 0b1000_0000_0000_0001;
const MANDATED = 0b1000_0000_0000_0001;
}
}
#[derive(Debug)]
pub struct Exception {
pub start: u16,
pub end: u16,
pub handler: u16,
pub catch_type: u16,
}
#[derive(Debug)]
pub struct BootstrapMethod {
pub method_ref: u16,
pub arguments: Vec<u16>,
}
#[derive(Debug)]
pub struct LineNumber {
pub start: u16,
pub line_number: u16,
}
#[derive(Debug)]
pub enum Instruction {
NOP,
AConstNull,
IConstM1,
IConst0,
IConst1,
IConst2,
IConst3,
IConst4,
IConst5,
LConst0,
LConst1,
FConst0,
FConst1,
FConst2,
DConst0,
DConst1,
BIPush(i8),
SIPush(i16),
LDC(u16),
ILoad(u16),
LLoad(u16),
FLoad(u16),
DLoad(u16),
ALoad(u16),
ILoad0,
ILoad1,
ILoad2,
ILoad3,
LLoad0,
LLoad1,
LLoad2,
LLoad3,
FLoad0,
FLoad1,
FLoad2,
FLoad3,
DLoad0,
DLoad1,
DLoad2,
DLoad3,
ALoad0,
ALoad1,
ALoad2,
ALoad3,
IALoad,
LALoad,
FALoad,
DALoad,
AALoad,
BALoad,
CALoad,
SALoad,
IStore(u16),
LStore(u16),
FStore(u16),
DStore(u16),
AStore(u16),
IStore0,
IStore1,
IStore2,
IStore3,
LStore0,
LStore1,
LStore2,
LStore3,
FStore0,
FStore1,
FStore2,
FStore3,
DStore0,
DStore1,
DStore2,
DStore3,
AStore0,
AStore1,
AStore2,
AStore3,
IAStore,
LAStore,
FAStore,
DAStore,
AAStore,
BAStore,
CAStore,
SAStore,
Pop,
Pop2,
Dup,
DupX1,
DupX2,
Dup2,
Dup2X1,
Dup2X2,
Swap,
IAdd,
LAdd,
FAdd,
DAdd,
ISub,
LSub,
FSub,
DSub,
IMul,
LMul,
FMul,
DMul,
IDiv,
LDiv,
FDiv,
DDiv,
IRem,
LRem,
FRem,
DRem,
INeg,
LNeg,
FNeg,
DNeg,
IShL,
LShL,
IShR,
LShR,
IUShR,
LUShR,
IAnd,
LAnd,
IOr,
LOr,
IXOr,
LXOr,
IInc(u16, i16),
I2L,
I2F,
I2D,
L2I,
L2F,
L2D,
F2I,
F2L,
F2D,
D2I,
D2L,
D2F,
I2B,
I2C,
I2S,
LCmp,
FCmpL,
FCmpG,
DCmpL,
DCmpG,
IfEq(i16),
IfNE(i16),
IfLT(i16),
IfGE(i16),
IfGT(i16),
IfLE(i16),
IfICmpEq(i16),
IfICmpNE(i16),
IfICmpLT(i16),
IfICmpGE(i16),
IfICmpGT(i16),
IfICmpLE(i16),
IfACmpEq(i16),
IfACmpNE(i16),
GoTo(i32),
JSR(i32),
Ret(u16),
TableSwitch {
default: i32,
low: i32,
high: i32,
offsets: Vec<i32>,
},
LookupSwitch {
default: i32,
offsets: BTreeMap<i32, i32>,
},
IReturn,
LReturn,
FReturn,
DReturn,
AReturn,
Return,
GetStatic(u16),
PutStatic(u16),
GetField(u16),
PutField(u16),
InvokeVirtual(u16),
InvokeSpecial(u16),
InvokeStatic(u16),
InvokeInterface(u16, u8),
InvokeDynamic(u16),
New(u16),
NewArray(ArrayType),
ANewArray(u16),
ArrayLength,
AThrow,
CheckCast(u16),
InstanceOf(u16),
MonitorEnter,
MonitorExit,
MultiANewArray(u16, u8),
IfNull(i16),
IfNonNull(i16),
BreakPoint,
ImpDep1,
ImpDep2,
}
#[derive(Debug)]
pub enum ArrayType {
Boolean,
Char,
Float,
Double,
Byte,
Short,
Int,
Long,
}
#[derive(Debug)]
pub struct InnerClass {
pub inner_class_info: u16,
pub outer_class_info: u16,
pub inner_name: u16,
pub inner_class_access_flags: AccessFlags,
}
#[derive(Debug)]
pub enum StackMapFrame {
Same {
offset_delta: u16,
},
Same1 {
offset_delta: u16,
stack: VerificationType,
},
Chop {
offset_delta: u16,
count: u8,
},
Append {
offset_delta: u16,
locals: Vec<VerificationType>,
},
Full {
offset_delta: u16,
locals: Vec<VerificationType>,
stack: Vec<VerificationType>,
},
}
#[derive(Debug)]
pub enum VerificationType {
Top,
Integer,
Float,
Double,
Long,
Null,
UninitializedThis,
Object(u16),
Uninitialized(u16),
}
#[derive(Debug)]
pub struct Annotation {
pub type_index: u16,
pub element_value_pairs: Vec<(u16, ElementValue)>,
}
#[derive(Debug)]
pub enum ElementValue {
Byte(u16),
Short(u16),
Char(u16),
Int(u16),
Long(u16),
Float(u16),
Double(u16),
Boolean(u16),
String(u16),
Enum {
type_name: u16,
const_name: u16,
},
Class(u16),
Annotation(Box<Annotation>),
Array(Vec<ElementValue>),
}
#[derive(Debug)]
pub struct TypeAnnotation {
pub target_type: TargetType,
pub target_path: Vec<TypePathElement>,
pub annotation: Annotation,
}
#[derive(Debug)]
pub enum TargetType {
TypeParameterClass(u8),
TypeParameterMethod(u8),
SuperType(u16),
TypeParameterBoundClass {
type_parameter: u8,
bound_index: u8,
},
TypeParameterBoundMethod {
type_parameter: u8,
bound_index: u8,
},
EmptyField,
EmptyReturn,
EmptyReceiver,
FormalParameter(u8),
Throws(u16),
LocalVariable(Vec<LocalVariableTarget>),
ResourceVariable(Vec<LocalVariableTarget>),
Catch(u16),
OffsetInstanceOf(u16),
OffsetNew(u16),
OffsetNewRef(u16),
OffsetRef(u16),
TypeArgumentCast { offset: u16, type_argument: u8 },
TypeArgumentMethod { offset: u16, type_argument: u8 },
TypeArgumentConstructor { offset: u16, type_argument: u8 },
TypeArgumentNewRef { offset: u16, type_argument: u8 },
TypeArgumentRef { offset: u16, type_argument: u8 },
}
#[derive(Debug)]
pub struct TypePathElement {
pub path_kind: TypePathKind,
pub argument_index: u8,
}
#[derive(Debug)]
pub enum TypePathKind {
ArrayType,
NestedType,
WildcardType,
Type,
}
#[derive(Debug)]
pub struct LocalVariableTarget {
pub start: u16,
pub length: u16,
pub index: u16,
}
#[derive(Debug)]
pub struct LocalVariable {
pub start: u16,
pub length: u16,
pub name: u16,
pub descriptor: u16,
pub index: u16,
}
#[derive(Debug)]
pub struct LocalVariableType {
pub start: u16,
pub length: u16,
pub name: u16,
pub signature: u16,
pub index: u16,
}
#[derive(Debug)]
pub struct MethodParameter {
pub name: u16,
pub access_flags: AccessFlags,
}
#[derive(Debug)]
pub struct Requirement {
pub index: u16,
pub flags: AccessFlags,
pub version: u16,
}
#[derive(Debug)]
pub struct Export {
pub index: u16,
pub flags: AccessFlags,
pub to: Vec<u16>,
}
#[derive(Debug)]
pub struct Opening {
pub index: u16,
pub flags: AccessFlags,
pub to: Vec<u16>,
}
#[derive(Debug)]
pub struct Provider {
pub index: u16,
pub with: Vec<u16>,
}