mirror of
https://github.com/Noratrieb/coldsquare.git
synced 2026-01-14 16:35:10 +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]
|
[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]
|
[package]
|
||||||
name = "file-info"
|
name = "cs_class_printer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[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;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "file-parser"
|
name = "cs_model"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "class-struct"
|
name = "cs_parser"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
@ -25,6 +25,7 @@ struct Data<'a> {
|
||||||
pointer: usize,
|
pointer: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses the class file into a `ClassFile` structure
|
||||||
pub fn parse_class_file(data: &[u1]) -> Result<ClassFile> {
|
pub fn parse_class_file(data: &[u1]) -> Result<ClassFile> {
|
||||||
let mut data = Data::new(data);
|
let mut data = Data::new(data);
|
||||||
ClassFile::parse(&mut data, &[])
|
ClassFile::parse(&mut data, &[])
|
||||||
|
|
@ -125,6 +125,10 @@ macro_rules! impl_try_from_cp {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
return Err(ParseErr("Index must not be 0".to_string()));
|
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
|
// 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
|
// it needs to be checked after testing
|
||||||
// not now
|
// not now
|
||||||
|
|
@ -302,6 +306,9 @@ impl ValidateCpInfo for Utf8 {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
return Err(ParseErr("Index must not be 0".to_string()));
|
return Err(ParseErr("Index must not be 0".to_string()));
|
||||||
}
|
}
|
||||||
|
if info.len() == 0 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
match &info[index as usize - 1].inner {
|
match &info[index as usize - 1].inner {
|
||||||
CpInfoInner::Utf8(_) => Ok(()),
|
CpInfoInner::Utf8(_) => Ok(()),
|
||||||
kind => Err(ParseErr(format!(
|
kind => Err(ParseErr(format!(
|
||||||
|
|
@ -37,7 +37,7 @@ fn data_u4() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_empty_class() {
|
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();
|
let parsed = parse_class_file(class).unwrap();
|
||||||
|
|
||||||
assert_eq!(parsed.minor_version, 0);
|
assert_eq!(parsed.minor_version, 0);
|
||||||
|
|
@ -139,7 +139,7 @@ fn parse_empty_class() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn more_complex_file() {
|
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();
|
let parsed = parse_class_file(class).unwrap();
|
||||||
assert_eq!(parsed.magic, 0xCAFEBABE);
|
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]
|
[package]
|
||||||
name = "machine"
|
name = "cs_vm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
@ -58,6 +58,7 @@ mod tests {
|
||||||
use super::{LocalVariables, OperandStack};
|
use super::{LocalVariables, OperandStack};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn operand_stack() {
|
fn operand_stack() {
|
||||||
let mut stack = OperandStack::new();
|
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() {
|
fn main() {
|
||||||
let file = std::env::args().nth(1).unwrap_or_else(|| {
|
let file = std::env::args().nth(1).unwrap_or_else(|| {
|
||||||
eprintln!("No file provided");
|
eprintln!("No file provided");
|
||||||
std::process::exit(1);
|
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");
|
eprintln!("Could not read file");
|
||||||
std::process::exit(1);
|
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,
|
Ok(file) => file,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let stdout = std::io::stdout();
|
|
||||||
|
|
||||||
if let Err(why) = display_class(stdout.lock(), &class_file) {
|
cs_class_printer::print(&class_file);
|
||||||
eprintln!("{}", why);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue