From 1186e70e69f30a6442f6ab5c755951f1b0235be7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 15 Dec 2021 21:36:37 +0100 Subject: [PATCH] restructure structure --- Cargo.toml | 16 ++- .../file-info => cs_class_printer}/Cargo.toml | 4 +- cs_class_printer/src/lib.rs | 13 ++ .../file-info => cs_class_printer}/src/ui.rs | 2 +- {crates/file-parser => cs_model}/Cargo.toml | 2 +- {crates/class-struct => cs_model}/src/lib.rs | 0 {crates/class-struct => cs_model}/src/test.rs | 0 {crates/class-struct => cs_parser}/Cargo.toml | 2 +- {crates/file-parser => cs_parser}/src/lib.rs | 1 + .../src/model/cp_info.rs | 7 + .../src/model/mod.rs | 0 {crates/file-parser => cs_parser}/src/test.rs | 4 +- cs_parser/testdata/Test.class | Bin 0 -> 182 bytes cs_parser/testdata/Test.class.txt | 133 ++++++++++++++++++ cs_parser/testdata/Test.java | 1 + cs_parser/testdata/Test2.class | Bin 0 -> 492 bytes cs_parser/testdata/Test2.java | 13 ++ {crates/machine => cs_vm}/Cargo.toml | 2 +- {crates/machine => cs_vm}/src/lib.rs | 0 {crates/machine => cs_vm}/src/model.rs | 1 + file-info.sh | 4 - {crates/file-info/src => src}/main.rs | 15 +- 22 files changed, 196 insertions(+), 24 deletions(-) rename {crates/file-info => cs_class_printer}/Cargo.toml (71%) create mode 100644 cs_class_printer/src/lib.rs rename {crates/file-info => cs_class_printer}/src/ui.rs (98%) rename {crates/file-parser => cs_model}/Cargo.toml (88%) rename {crates/class-struct => cs_model}/src/lib.rs (100%) rename {crates/class-struct => cs_model}/src/test.rs (100%) rename {crates/class-struct => cs_parser}/Cargo.toml (87%) rename {crates/file-parser => cs_parser}/src/lib.rs (99%) rename {crates/file-parser => cs_parser}/src/model/cp_info.rs (98%) rename {crates/file-parser => cs_parser}/src/model/mod.rs (100%) rename {crates/file-parser => cs_parser}/src/test.rs (97%) create mode 100644 cs_parser/testdata/Test.class create mode 100644 cs_parser/testdata/Test.class.txt create mode 100644 cs_parser/testdata/Test.java create mode 100644 cs_parser/testdata/Test2.class create mode 100644 cs_parser/testdata/Test2.java rename {crates/machine => cs_vm}/Cargo.toml (90%) rename {crates/machine => cs_vm}/src/lib.rs (100%) rename {crates/machine => cs_vm}/src/model.rs (99%) delete mode 100644 file-info.sh rename {crates/file-info/src => src}/main.rs (52%) diff --git a/Cargo.toml b/Cargo.toml index 4df366c..3b7d99f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,16 @@ [workspace] -members = ["crates/*"] \ No newline at end of file +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" } diff --git a/crates/file-info/Cargo.toml b/cs_class_printer/Cargo.toml similarity index 71% rename from crates/file-info/Cargo.toml rename to cs_class_printer/Cargo.toml index 94102bd..822d723 100644 --- a/crates/file-info/Cargo.toml +++ b/cs_class_printer/Cargo.toml @@ -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" } \ No newline at end of file +cs_parser = { path = "../cs_parser" } \ No newline at end of file diff --git a/cs_class_printer/src/lib.rs b/cs_class_printer/src/lib.rs new file mode 100644 index 0000000..bfa4e47 --- /dev/null +++ b/cs_class_printer/src/lib.rs @@ -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); + } +} diff --git a/crates/file-info/src/ui.rs b/cs_class_printer/src/ui.rs similarity index 98% rename from crates/file-info/src/ui.rs rename to cs_class_printer/src/ui.rs index 158e210..9cbb08b 100644 --- a/crates/file-info/src/ui.rs +++ b/cs_class_printer/src/ui.rs @@ -1,4 +1,4 @@ -use file_parser::ClassFile; +use cs_parser::ClassFile; use std::io; use std::io::Write; diff --git a/crates/file-parser/Cargo.toml b/cs_model/Cargo.toml similarity index 88% rename from crates/file-parser/Cargo.toml rename to cs_model/Cargo.toml index ad85e8a..4d0c181 100644 --- a/crates/file-parser/Cargo.toml +++ b/cs_model/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "file-parser" +name = "cs_model" version = "0.1.0" edition = "2021" diff --git a/crates/class-struct/src/lib.rs b/cs_model/src/lib.rs similarity index 100% rename from crates/class-struct/src/lib.rs rename to cs_model/src/lib.rs diff --git a/crates/class-struct/src/test.rs b/cs_model/src/test.rs similarity index 100% rename from crates/class-struct/src/test.rs rename to cs_model/src/test.rs diff --git a/crates/class-struct/Cargo.toml b/cs_parser/Cargo.toml similarity index 87% rename from crates/class-struct/Cargo.toml rename to cs_parser/Cargo.toml index ffbf29b..7a5e7f2 100644 --- a/crates/class-struct/Cargo.toml +++ b/cs_parser/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "class-struct" +name = "cs_parser" version = "0.1.0" edition = "2021" diff --git a/crates/file-parser/src/lib.rs b/cs_parser/src/lib.rs similarity index 99% rename from crates/file-parser/src/lib.rs rename to cs_parser/src/lib.rs index 3ca621f..19564e8 100644 --- a/crates/file-parser/src/lib.rs +++ b/cs_parser/src/lib.rs @@ -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 { let mut data = Data::new(data); ClassFile::parse(&mut data, &[]) diff --git a/crates/file-parser/src/model/cp_info.rs b/cs_parser/src/model/cp_info.rs similarity index 98% rename from crates/file-parser/src/model/cp_info.rs rename to cs_parser/src/model/cp_info.rs index 8221eae..ee8d273 100644 --- a/crates/file-parser/src/model/cp_info.rs +++ b/cs_parser/src/model/cp_info.rs @@ -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!( diff --git a/crates/file-parser/src/model/mod.rs b/cs_parser/src/model/mod.rs similarity index 100% rename from crates/file-parser/src/model/mod.rs rename to cs_parser/src/model/mod.rs diff --git a/crates/file-parser/src/test.rs b/cs_parser/src/test.rs similarity index 97% rename from crates/file-parser/src/test.rs rename to cs_parser/src/test.rs index 4b1f625..1e329a2 100644 --- a/crates/file-parser/src/test.rs +++ b/cs_parser/src/test.rs @@ -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); } diff --git a/cs_parser/testdata/Test.class b/cs_parser/testdata/Test.class new file mode 100644 index 0000000000000000000000000000000000000000..2c9e5b01147fd4239136dac3ca8dd65d82b56c0f GIT binary patch literal 182 zcmX^0Z`VEs1_o;eUM>bE24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk- z5<5l)W)00Sb_Nbc29}W2;u1y%7U%qwR7M7VpUk{eztY^K)S{5Yq?}Yn2Cm@z(xT*4 zw@eU+6Qo!VWGsUs13Lo~0|+oOFoNu3U}WHAU|^7C0Pz_ZShcn@Fm7aEU|?k6Vqjok RV_*cc85y`47#NrscmT|>A6x(c literal 0 HcmV?d00001 diff --git a/cs_parser/testdata/Test.class.txt b/cs_parser/testdata/Test.class.txt new file mode 100644 index 0000000..a0170df --- /dev/null +++ b/cs_parser/testdata/Test.class.txt @@ -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......()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 () + } + 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 + } +] \ No newline at end of file diff --git a/cs_parser/testdata/Test.java b/cs_parser/testdata/Test.java new file mode 100644 index 0000000..099aac2 --- /dev/null +++ b/cs_parser/testdata/Test.java @@ -0,0 +1 @@ +public class Test {} \ No newline at end of file diff --git a/cs_parser/testdata/Test2.class b/cs_parser/testdata/Test2.class new file mode 100644 index 0000000000000000000000000000000000000000..63cac3b7b6000072f992139b142d392866c151d6 GIT binary patch literal 492 zcmX^0Z`VEs1_o;eMJ@&=24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk- z5<5l)W)00Sb_Nbc2G)?&;u0e+26hH!5W&sEz{9}H$iP}ql$lq;$iSlEsTsz}z|SDS z&LGIcAjBYyVs3C{aY 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); }