mirror of
https://github.com/Noratrieb/coldsquare.git
synced 2026-01-17 01:45:09 +01:00
.class models
This commit is contained in:
parent
e9a7716843
commit
9d8a01b864
5 changed files with 358 additions and 9 deletions
1
src/execute/mod.rs
Normal file
1
src/execute/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
mod model;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
pub struct OperandStack {
|
pub struct OperandStack {
|
||||||
vec: Vec<i32>,
|
vec: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OperandStack {
|
impl OperandStack {
|
||||||
|
|
@ -9,11 +9,11 @@ impl OperandStack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) -> i32 {
|
pub fn pop(&mut self) -> u32 {
|
||||||
self.vec.pop().unwrap()
|
self.vec.pop().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, n: i32) {
|
pub fn push(&mut self, n: u32) {
|
||||||
self.vec.push(n);
|
self.vec.push(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -24,7 +24,7 @@ impl OperandStack {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LocalVariables {
|
pub struct LocalVariables {
|
||||||
vec: Vec<i32>
|
vec: Vec<u32>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalVariables {
|
impl LocalVariables {
|
||||||
|
|
@ -34,19 +34,19 @@ impl LocalVariables {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store(&mut self, address: u16, value: i32) {
|
pub fn store(&mut self, address: u8, value: u32) {
|
||||||
self.vec.insert(address as usize, value);
|
self.vec.insert(address as usize, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store2(&mut self, address: u16, value1: i32, value2: i32) {
|
pub fn store2(&mut self, address: u8, value1: u32, value2: u32) {
|
||||||
self.vec.insert(address as usize, value1);
|
self.vec.insert(address as usize, value1);
|
||||||
self.vec.insert(address as usize + 1, value2);
|
self.vec.insert(address as usize + 1, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(&self, address: u16) -> i32 {
|
pub fn load(&self, address: u8) -> u32 {
|
||||||
self.vec[address as usize]
|
self.vec[address as usize]
|
||||||
}
|
}
|
||||||
pub fn load2(&self, address: u16) -> (i32, i32) {
|
pub fn load2(&self, address: u8) -> (u32, u32) {
|
||||||
(self.vec[address as usize], self.vec[address as usize + 1])
|
(self.vec[address as usize], self.vec[address as usize + 1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
mod model;
|
mod parse;
|
||||||
|
mod execute;
|
||||||
3
src/parse/mod.rs
Normal file
3
src/parse/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod model;
|
||||||
|
|
||||||
|
pub fn parse_class_file(data: &[u8]) {}
|
||||||
344
src/parse/model.rs
Normal file
344
src/parse/model.rs
Normal file
|
|
@ -0,0 +1,344 @@
|
||||||
|
//!
|
||||||
|
//! The models for a .class file
|
||||||
|
//!
|
||||||
|
//! [The .class specs](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html)
|
||||||
|
|
||||||
|
// The types used in the specs
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type u1 = u8;
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type u2 = u16;
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type u4 = u32;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// # Represents a .class file
|
||||||
|
///
|
||||||
|
pub struct ClassFile {
|
||||||
|
/// Magic number identifying the format (= 0xCAFEBABE)
|
||||||
|
magic: u4,
|
||||||
|
/// The version of the class file (.X)
|
||||||
|
minor_version: u2,
|
||||||
|
/// The version of the class file (X.)
|
||||||
|
major_version: u2,
|
||||||
|
/// Number of entries in the constant pool + 1
|
||||||
|
constant_pool_count: u2,
|
||||||
|
/// The constant pool. Indexed from 1 to constant_pool_count - 1
|
||||||
|
constant_pool: Vec<CpInfo>,
|
||||||
|
/// Mask of `ClassAccessFlag` used to denote access permissions
|
||||||
|
access_flags: u2,
|
||||||
|
/// A valid index into the `constant_pool` table. The entry must be a `ConstantClassInfo`
|
||||||
|
this_class: u2,
|
||||||
|
/// Zero or a valid index into the `constant_pool` table
|
||||||
|
super_class: u2,
|
||||||
|
/// The number if direct superinterfaces of this class or interface type
|
||||||
|
interfaces_count: u2,
|
||||||
|
/// Each entry must be a valid index into the `constant_pool` table. The entry must be a `ConstantClassInfo`
|
||||||
|
interfaces: Vec<u2>,
|
||||||
|
/// The number of fields in the `fields` table
|
||||||
|
fields_count: u2,
|
||||||
|
/// All fields of the class. Contains only fields of the class itself
|
||||||
|
fields: Vec<FieldInfo>,
|
||||||
|
/// The number of methods in `methods`
|
||||||
|
method_count: u2,
|
||||||
|
/// All methods of the class. If it's neither Native nor Abstract, the implementation has to be provided too
|
||||||
|
methods: Vec<MethodInfo>,
|
||||||
|
/// The number of attributes in `attributes`
|
||||||
|
attributes_count: u2,
|
||||||
|
/// All attributes of the class
|
||||||
|
attributes: Vec<AttributeInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access Flags of a class
|
||||||
|
#[repr(u16)]
|
||||||
|
enum ClassAccessFlag {
|
||||||
|
/// Declared public; may be accessed from outside its package.
|
||||||
|
Public = 0x0001,
|
||||||
|
/// Declared final; no subclasses allowed.
|
||||||
|
Final = 0x0010,
|
||||||
|
/// Treat superclass methods specially when invoked by the invokespecial instruction.
|
||||||
|
Super = 0x0020,
|
||||||
|
/// Is an interface, not a class.
|
||||||
|
Interface = 0x0200,
|
||||||
|
/// Declared abstract; must not be instantiated.
|
||||||
|
Abstract = 0x0400,
|
||||||
|
/// Declared synthetic; not present in the source code.
|
||||||
|
Synthetic = 0x1000,
|
||||||
|
/// Declared as an annotation type.
|
||||||
|
Annotation = 0x2000,
|
||||||
|
/// Declared as an enum type.
|
||||||
|
Enum = 0x4000,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access Flags of a method
|
||||||
|
#[repr(u16)]
|
||||||
|
enum MethodAccessFlag {
|
||||||
|
// Declared public; may be accessed from outside its package.
|
||||||
|
PUBLIC = 0x0001,
|
||||||
|
// Declared private; accessible only within the defining class.
|
||||||
|
PRIVATE = 0x0002,
|
||||||
|
// Declared protected; may be accessed within subclasses.
|
||||||
|
PROTECTED = 0x0004,
|
||||||
|
// Declared static.
|
||||||
|
STATIC = 0x0008,
|
||||||
|
// Declared final; must not be overridden.
|
||||||
|
FINAL = 0x0010,
|
||||||
|
// Declared synchronized; invocation is wrapped by a monitor use.
|
||||||
|
SYNCHRONIZED = 0x0020,
|
||||||
|
// A bridge method, generated by the compiler.
|
||||||
|
BRIDGE = 0x0040,
|
||||||
|
// Declared with variable number of arguments.
|
||||||
|
VARARGS = 0x0080,
|
||||||
|
// Declared native; implemented in a language other than Java.
|
||||||
|
NATIVE = 0x0100,
|
||||||
|
// Declared abstract; no implementation is provided.
|
||||||
|
ABSTRACT = 0x0400,
|
||||||
|
// Declared strictfp; floating-point mode is FP-strict.
|
||||||
|
STRICT = 0x0800,
|
||||||
|
// Declared synthetic; not present in the source code.
|
||||||
|
SYNTHETIC = 0x1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
enum CpInfo {
|
||||||
|
Class {
|
||||||
|
tag: u1, // 7
|
||||||
|
/// Entry must be `Utf8`
|
||||||
|
name_index: u2,
|
||||||
|
},
|
||||||
|
Fieldref {
|
||||||
|
tag: u1, // 9
|
||||||
|
/// May be a class or interface type
|
||||||
|
class_index: u2,
|
||||||
|
/// Entry must be `NameAndType`
|
||||||
|
name_and_type_index: u2,
|
||||||
|
},
|
||||||
|
Methodref {
|
||||||
|
tag: u1, // 10
|
||||||
|
/// Must be a class type
|
||||||
|
class_index: u2,
|
||||||
|
/// Entry must be `NameAndType`
|
||||||
|
name_and_type_index: u2,
|
||||||
|
},
|
||||||
|
InterfaceMethodref {
|
||||||
|
tag: u1, // 11
|
||||||
|
/// Must be an interface type
|
||||||
|
class_index: u2,
|
||||||
|
/// Entry must be `NameAndType`
|
||||||
|
name_and_type_index: u2,
|
||||||
|
},
|
||||||
|
String {
|
||||||
|
tag: u1, // 8
|
||||||
|
/// Entry must be `Utf8`
|
||||||
|
string_index: u2,
|
||||||
|
},
|
||||||
|
Integer {
|
||||||
|
tag: u1, // 3
|
||||||
|
// Big endian
|
||||||
|
bytes: u4,
|
||||||
|
},
|
||||||
|
Float {
|
||||||
|
tag: u1, // 4
|
||||||
|
/// IEEE 754 floating-point single format, big endian
|
||||||
|
bytes: u4,
|
||||||
|
},
|
||||||
|
/// 8 byte constants take up two spaces in the constant pool
|
||||||
|
Long {
|
||||||
|
tag: u1, // 5
|
||||||
|
/// Big endian
|
||||||
|
high_bytes: u4,
|
||||||
|
/// Big endian
|
||||||
|
low_bytes: u4,
|
||||||
|
},
|
||||||
|
/// 8 byte constants take up two spaces in the constant pool
|
||||||
|
Double {
|
||||||
|
tag: u1, // 6
|
||||||
|
/// IEEE 754 floating-point double format, big endian
|
||||||
|
high_bytes: u4,
|
||||||
|
/// IEEE 754 floating-point double format, big endian
|
||||||
|
low_bytes: u4,
|
||||||
|
},
|
||||||
|
/// Any field or method, without the class it belongs to
|
||||||
|
NameAndType {
|
||||||
|
tag: u1, // 12
|
||||||
|
/// Entry must be `Utf8`
|
||||||
|
name_index: u2,
|
||||||
|
/// Entry must be `Utf8`
|
||||||
|
descriptor_index: u2,
|
||||||
|
},
|
||||||
|
Utf8 {
|
||||||
|
tag: u1, // 1
|
||||||
|
/// The length of the String. Not null-terminated.
|
||||||
|
length: u2,
|
||||||
|
/// Contains modified UTF-8
|
||||||
|
bytes: Vec<u1>,
|
||||||
|
},
|
||||||
|
MethodHandle {
|
||||||
|
tag: u1, // 15
|
||||||
|
/// The kind of method handle (0-9)
|
||||||
|
reference_kind: u1,
|
||||||
|
/// If the kind is 1-4, the entry must be `FieldRef`. If the kind is 5-8, the entry must be `MethodRef`
|
||||||
|
/// If the kind is 9, the entry must be `InterfaceMethodRef`
|
||||||
|
reference_index: u2,
|
||||||
|
},
|
||||||
|
MethodType {
|
||||||
|
tag: u1, // 16
|
||||||
|
/// Entry must be `Utf8`
|
||||||
|
descriptor_index: u2,
|
||||||
|
},
|
||||||
|
InvokeDynamic {
|
||||||
|
tag: u1,
|
||||||
|
/// 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`
|
||||||
|
name_and_type_index: u2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information about a method
|
||||||
|
struct MethodInfo {
|
||||||
|
/// Mask of `MethodAccessFlag` used to denote access permissions
|
||||||
|
access_flags: u2,
|
||||||
|
/// Index to the `constant_pool` of the method name, must be `Utf8`
|
||||||
|
name_index: u2,
|
||||||
|
/// Index to the `constant_pool` of the method descriptor, must be `Utf8`
|
||||||
|
descriptor_index: u2,
|
||||||
|
/// The amount of attributes for this method
|
||||||
|
attributes_count: u2,
|
||||||
|
/// The attributes for this method
|
||||||
|
attributes: Vec<AttributeInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information about an attribute
|
||||||
|
///
|
||||||
|
/// `attribute_name_index`: Index to the `constant_pool`, must be `Utf8`
|
||||||
|
/// `attribute_length`: The length of the subsequent bytes, does not include the first 6
|
||||||
|
///
|
||||||
|
/// _index: Index to the `constant_pool` table of any type
|
||||||
|
enum AttributeInfo {
|
||||||
|
/// Only on fields, the constant value of that field
|
||||||
|
ConstantValue {
|
||||||
|
attribute_name_index: u2, // "ConstantValue"
|
||||||
|
attribute_length: u4,
|
||||||
|
/// Must be of type `Long`/`Float`/`Double`/`Integer`/`String`
|
||||||
|
constantvalue_index: u2,
|
||||||
|
},
|
||||||
|
/// Only on methods, contains JVM instructions and auxiliary information for a single method
|
||||||
|
Code {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
/// The maximum depth of the operand stack for this method
|
||||||
|
max_stack: u2,
|
||||||
|
/// The number of the local variables array, including the parameters
|
||||||
|
max_locals: u2,
|
||||||
|
/// The length of the JVM bytecode in bytes
|
||||||
|
code_length: u4,
|
||||||
|
/// The JVM bytecode of this method
|
||||||
|
code: Vec<u1>,
|
||||||
|
/// The number of entries in the exception table
|
||||||
|
exception_table_length: u2,
|
||||||
|
/// The exception handlers for this method
|
||||||
|
exception_table: Vec<AttributeCodeException>,
|
||||||
|
attributes_count: u2,
|
||||||
|
/// The attributes of the code
|
||||||
|
attributes: Vec<AttributeInfo>,
|
||||||
|
},
|
||||||
|
/// Only on the `Code` attribute, used for verification
|
||||||
|
/// May be implicit on version >= 50.0, with no entries
|
||||||
|
StackMapTable {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
number_of_entries: u2,
|
||||||
|
entries: Vec<StackMapFrame>,
|
||||||
|
},
|
||||||
|
Exceptions {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
InnerClasses {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
EnclosingMethod {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
Synthetic {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
Signature {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
SourceFile {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
SourceDebugExtension {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
LineNumberTable {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
LocalVariableTable {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
LocalVariableTypeTable {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
Deprecated {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
RuntimeVisibleAnnotations {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
RuntimeInvisibleAnnotations {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
RuntimeVisibleParameterAnnotations {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
RuntimeInvisibleParameterAnnotations {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
AnnotationDefault {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
BootstrapMethods {
|
||||||
|
attribute_name_index: u2,
|
||||||
|
attribute_length: u4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An exception handler in the JVM bytecode array
|
||||||
|
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,
|
||||||
|
/// 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,
|
||||||
|
/// The start of the exception handler, must be a valid index into the code array at an opcode instruction
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
type StackMapFrame = u8;
|
||||||
|
|
||||||
|
/// Information about a field
|
||||||
|
type FieldInfo = u8;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue