mirror of
https://github.com/Noratrieb/coldsquare.git
synced 2026-01-14 08:30:13 +01:00
restructure structure
This commit is contained in:
parent
1a920ab9af
commit
1186e70e69
22 changed files with 196 additions and 24 deletions
16
Cargo.toml
16
Cargo.toml
|
|
@ -1,2 +1,16 @@
|
|||
[workspace]
|
||||
members = ["crates/*"]
|
||||
members = [
|
||||
"cs_class_printer",
|
||||
"cs_model",
|
||||
"cs_parser",
|
||||
"cs_vm",
|
||||
]
|
||||
|
||||
[package]
|
||||
name = "coldsquare"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cs_class_printer = { path = "cs_class_printer" }
|
||||
cs_parser = { path = "cs_parser" }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "file-info"
|
||||
name = "cs_class_printer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
file-parser = { path = "../file-parser" }
|
||||
cs_parser = { path = "../cs_parser" }
|
||||
13
cs_class_printer/src/lib.rs
Normal file
13
cs_class_printer/src/lib.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use crate::ui::display_class;
|
||||
use cs_parser::ClassFile;
|
||||
|
||||
mod ui;
|
||||
|
||||
/// Pretty-prints a class file
|
||||
pub fn print(class_file: &ClassFile) {
|
||||
let stdout = std::io::stdout();
|
||||
|
||||
if let Err(why) = display_class(stdout.lock(), class_file) {
|
||||
eprintln!("{}", why);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use file_parser::ClassFile;
|
||||
use cs_parser::ClassFile;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "file-parser"
|
||||
name = "cs_model"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "class-struct"
|
||||
name = "cs_parser"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
@ -25,6 +25,7 @@ struct Data<'a> {
|
|||
pointer: usize,
|
||||
}
|
||||
|
||||
/// Parses the class file into a `ClassFile` structure
|
||||
pub fn parse_class_file(data: &[u1]) -> Result<ClassFile> {
|
||||
let mut data = Data::new(data);
|
||||
ClassFile::parse(&mut data, &[])
|
||||
|
|
@ -125,6 +125,10 @@ macro_rules! impl_try_from_cp {
|
|||
if index == 0 {
|
||||
return Err(ParseErr("Index must not be 0".to_string()));
|
||||
}
|
||||
|
||||
if info.len() == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
// todo this here might actually be an empty constant pool depending on whether is is still parsing the constant pool
|
||||
// it needs to be checked after testing
|
||||
// not now
|
||||
|
|
@ -302,6 +306,9 @@ impl ValidateCpInfo for Utf8 {
|
|||
if index == 0 {
|
||||
return Err(ParseErr("Index must not be 0".to_string()));
|
||||
}
|
||||
if info.len() == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
match &info[index as usize - 1].inner {
|
||||
CpInfoInner::Utf8(_) => Ok(()),
|
||||
kind => Err(ParseErr(format!(
|
||||
|
|
@ -37,7 +37,7 @@ fn data_u4() {
|
|||
|
||||
#[test]
|
||||
fn parse_empty_class() {
|
||||
let class = include_bytes!("../../../testdata/Test.class");
|
||||
let class = include_bytes!("../testdata/Test.class");
|
||||
let parsed = parse_class_file(class).unwrap();
|
||||
|
||||
assert_eq!(parsed.minor_version, 0);
|
||||
|
|
@ -139,7 +139,7 @@ fn parse_empty_class() {
|
|||
|
||||
#[test]
|
||||
fn more_complex_file() {
|
||||
let class = include_bytes!("../../../testdata/Test2.class");
|
||||
let class = include_bytes!("../testdata/Test2.class");
|
||||
let parsed = parse_class_file(class).unwrap();
|
||||
assert_eq!(parsed.magic, 0xCAFEBABE);
|
||||
}
|
||||
BIN
cs_parser/testdata/Test.class
vendored
Normal file
BIN
cs_parser/testdata/Test.class
vendored
Normal file
Binary file not shown.
133
cs_parser/testdata/Test.class.txt
vendored
Normal file
133
cs_parser/testdata/Test.class.txt
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
Manually parsed by hand
|
||||
|
||||
hexdump -C Test.class
|
||||
|
||||
00000000 |ca fe ba be|00 00|00 3b |00 0d|0a.00 02.00 03|07. |.......;........|
|
||||
00000010 00 04|0c.00 05.00 06|01 .00 10.6a 61 76 61 2f 6c |..........java/l|
|
||||
00000020 61 6e 67 2f 4f 62 6a 65 63 74|01.00 06.3c 69 6e |ang/Object...<in|
|
||||
00000030 69 74 3e|01.00 03.28 29 56|07.00 08|01.00 04.54 |it>...()V......T|
|
||||
00000040 65 73 74|01.00 04.43 6f 64 65|01.00 0f.4c 69 6e |est...Code...Lin|
|
||||
00000050 65 4e 75 6d 62 65 72 54 61 62 6c 65|01.00 0a.53 |eNumberTable...S|
|
||||
00000060 6f 75 72 63 65 46 69 6c 65|01.00 09.54 65 73 74 |ourceFile...Test|
|
||||
00000070 2e 6a 61 76 61|00 21|00 07|00 02|00 00|00 00|00 |.java.!.........|
|
||||
00000080 01|00 01.00 05.00 06.00 01:00 09.00 00 00 1d.00 |................|
|
||||
00000090 01.00 01.00 00 00 05.2a b7 00 01 b1.00 00.00 01: |.......*........|
|
||||
000000a0 00 0a.00 00 00 06.00 01 :00 00.00 01|00 01|00 0b. |................|
|
||||
000000b0 00 00 00 02.00 0c |......|
|
||||
000000b6
|
||||
|
||||
|
||||
Magic: ca fe ba be
|
||||
Minor: 00 00
|
||||
Major: 00 3b
|
||||
CpCount: 00 0d (13) (13 - 1 = 12)
|
||||
Cp: [
|
||||
1: {
|
||||
tag: 0a (10, MethodRef)
|
||||
class_index: 00 02 (2)
|
||||
name_and_type_index: 00 03
|
||||
}
|
||||
2: {
|
||||
tag: 07 (7, Class)
|
||||
name_index: 00 04 (4) (java/lang/Object)
|
||||
}
|
||||
3: {
|
||||
tag: 0c (12, NameAndType)
|
||||
name_index: 00 05 (05)
|
||||
descriptor_index: 00 06
|
||||
}
|
||||
4: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 10 (16)
|
||||
string: 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 (java/lang/Object)
|
||||
}
|
||||
5: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 06 (6)
|
||||
string: 3c 69 6e 69 74 3e (<init>)
|
||||
}
|
||||
6: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 03 (3)
|
||||
bytes: 28 29 56 (()V)
|
||||
}
|
||||
7: {
|
||||
tag: 07 (7, Class)
|
||||
name_index: 00 08 (8) (Test)
|
||||
}
|
||||
8: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 04 (4)
|
||||
bytes: 54 65 73 74 (Test)
|
||||
}
|
||||
9: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 04 (4)
|
||||
bytes: 43 6f 64 65 (Code)
|
||||
}
|
||||
10: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 0f (15)
|
||||
bytes: 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 (LineNumberTable)
|
||||
}
|
||||
11: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 0a (10)
|
||||
bytes: 53 6f 75 72 63 65 46 69 6c 65 (SourceFile)
|
||||
}
|
||||
12: {
|
||||
tag: 01 (1, Utf8)
|
||||
length: 00 09 (9)
|
||||
bytes: 54 65 73 74 2e 6a 61 76 61 (Test.java)
|
||||
}
|
||||
]
|
||||
access_flags: 00 21
|
||||
this_class: 00 07 (Test)
|
||||
super_class: 00 02 (java/lang/Object)
|
||||
interfaces_count: 00 00
|
||||
interfaces: []
|
||||
fields_count: 00 00
|
||||
fields: []
|
||||
methods_count: 00 01
|
||||
methods: [
|
||||
{
|
||||
access_flags: 00 01
|
||||
name_index: 00 05
|
||||
descriptor_index: 00 06
|
||||
attributes_count: 00 01
|
||||
attributes: [
|
||||
{
|
||||
name_index: 00 09 (Code)
|
||||
attribute_length: 00 00 00 1d (29)
|
||||
max_stack: 00 01
|
||||
max_locals: 00 01
|
||||
code_length: 00 00 00 05
|
||||
code: 2a b7 00 01 b1
|
||||
exception_table_length: 00 00
|
||||
exception_table: []
|
||||
attributes_count: 00 01
|
||||
attributes: [
|
||||
{
|
||||
attribute_name_index: 00 0a (LineNumberTable)
|
||||
attribute_length: 00 00 00 06
|
||||
line_number_table_length: 00 01
|
||||
line_number_table: [
|
||||
{
|
||||
start_pc: 00 00
|
||||
line_number: 00 01
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
attributes_count: 00 01
|
||||
attributes: [
|
||||
{
|
||||
attribute_name_index: 00 0b (SourceFile)
|
||||
attribute_length: 00 00 00 02
|
||||
sourcefile_index: 00 0c
|
||||
}
|
||||
]
|
||||
1
cs_parser/testdata/Test.java
vendored
Normal file
1
cs_parser/testdata/Test.java
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
public class Test {}
|
||||
BIN
cs_parser/testdata/Test2.class
vendored
Normal file
BIN
cs_parser/testdata/Test2.class
vendored
Normal file
Binary file not shown.
13
cs_parser/testdata/Test2.java
vendored
Normal file
13
cs_parser/testdata/Test2.java
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class Test2 {
|
||||
int myField;
|
||||
|
||||
public static void main(String[] args) {
|
||||
int i = 0;
|
||||
i++;
|
||||
new Test2().print(i);
|
||||
}
|
||||
|
||||
void print(int i) {
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "machine"
|
||||
name = "cs_vm"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ mod tests {
|
|||
use super::{LocalVariables, OperandStack};
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn operand_stack() {
|
||||
let mut stack = OperandStack::new();
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd crates/file-info
|
||||
cargo run ../../"$1"
|
||||
|
|
@ -1,28 +1,21 @@
|
|||
use crate::ui::display_class;
|
||||
use file_parser::parse_class_file;
|
||||
|
||||
mod ui;
|
||||
|
||||
fn main() {
|
||||
let file = std::env::args().nth(1).unwrap_or_else(|| {
|
||||
eprintln!("No file provided");
|
||||
std::process::exit(1);
|
||||
});
|
||||
let file = std::fs::read(file).unwrap_or_else(|_| {
|
||||
|
||||
let contents = std::fs::read(file).unwrap_or_else(|_| {
|
||||
eprintln!("Could not read file");
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
||||
let class_file = match parse_class_file(&file) {
|
||||
let class_file = match cs_parser::parse_class_file(&contents) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let stdout = std::io::stdout();
|
||||
|
||||
if let Err(why) = display_class(stdout.lock(), &class_file) {
|
||||
eprintln!("{}", why);
|
||||
}
|
||||
cs_class_printer::print(&class_file);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue