diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 4d4560b..9afd53a 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -15,6 +15,19 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 - run: cargo test + # Check lints with clippy + clippy: + name: cargo clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # Ensure clippy is installed + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: clippy + - name: Clippy Check + uses: clechasseur/rs-clippy-check@v4 + # Check formatting with rustfmt formatting: name: cargo fmt diff --git a/.gitignore b/.gitignore index 91d28ce..a14798d 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,11 @@ generated/ **/out *.vsix -*.deb \ No newline at end of file +*.deb + +# cargo-mutants +mutants* + +*.warp +*.sbin +!fixtures/*.warp \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 353de04..fdca113 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,28 +1,13 @@ -[package] -name = "warp" -version = "0.1.0" -edition = "2021" -license = "Apache-2.0" +[workspace] +resolver = "2" +members = [ + "rust", + "rust/fuzz", + "warp_cli" +] -[lib] -path = "rust/lib.rs" - -[dependencies] -flatbuffers = "24.3.25" -bon = "2.3.0" -uuid = { version = "1.11.0", features = ["v5"]} -rand = "0.8.5" -flate2 = "1.0.34" - -[features] -default = [] -gen_flatbuffers = ["dep:flatbuffers-build"] - -[dev-dependencies] -criterion = "0.5.1" - -[build-dependencies] -flatbuffers-build = { git = "https://github.com/emesare/flatbuffers-build", features = ["vendored"], optional = true } +[workspace.dependencies] +warp = { path = "rust" } [profile.release] panic = "abort" @@ -31,12 +16,3 @@ debug = "full" [profile.bench] lto = true - -[[example]] -name = "simple" -path = "rust/examples/simple.rs" - -[[bench]] -name = "void" -path = "rust/benches/void.rs" -harness = false \ No newline at end of file diff --git a/LICENSE b/LICENSE index 8d2dadd..83a66a3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020-2024 Vector 35 Inc. +Copyright 2020-2025 Vector 35 Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 86d0d59..6da6ad4 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,16 @@ common functions within any binary efficiently and accurately. ### Integration Requirements -To integrate with **WARP** function matching you must be able to: +To integrate with **WARP** function matching, you must be able to: 1. Disassemble instructions 2. Identify basic blocks that make up a function 3. Identify register groups with implicit extend operation -4. Identify relocatable instructions (see [What is considered a relocatable operand?](#what-is-considered-a-relocatable-operand)) +4. Identify relocatable instructions (see [What is considered a relocatable instruction?](#what-is-considered-a-relocatable-instruction)) ### Creating a Function GUID -The function GUID is the UUIDv5 of the basic block GUID's (sorted highest to lowest start address) that make up the function. +The function GUID is the UUIDv5 of the basic block GUIDs (sorted highest to lowest start address) that make up the function. #### Example @@ -56,44 +56,66 @@ function = uuid5(function_namespace, bb1.bytes + bb2.bytes + bb3.bytes) #### What is the UUIDv5 namespace? -The namespace for Function GUID's is `0192a179-61ac-7cef-88ed-012296e9492f`. +The namespace for Function GUIDs is `0192a179-61ac-7cef-88ed-012296e9492f`. ### Creating a Basic Block GUID The basic block GUID is the UUIDv5 of the byte sequence of the instructions (sorted in execution order) with the following properties: -1. Zero out all instructions containing a relocatable operand. +1. Zero out all relocatable instructions. 2. Exclude all NOP instructions. 3. Exclude all instructions that set a register to itself if they are effectively NOPs. #### When are instructions that set a register to itself removed? -To support hot-patching we must remove them as they can be injected by the compiler at the start of a function (see: [1] and [2]). +To support hot-patching, we must remove them as they can be injected by the compiler at the start of a function (see: [1] and [2]). This does not affect the accuracy of the function GUID as they are only removed when the instruction is a NOP: - Register groups with no implicit extension will be removed (see: [3] (under 3.4.1.1)) For the `x86_64` architecture this means `mov edi, edi` will _not_ be removed, but it _will_ be removed for the `x86` architecture. -#### What is considered a relocatable operand? +#### What is considered a relocatable instruction? -An operand that is used as a pointer to a mapped region. +An instruction with an operand that is used as a _constant_ pointer to a mapped region. -For the `x86` architecture the instruction `e8b55b0100` (or `call 0x15bba`) would be zeroed. + - For the `x86` architecture the instruction `e8b55b0100` (or `call 0x15bba`) would be zeroed. + +An instruction which is used to calculate a _constant_ pointer to a mapped region, with a _constant_ offset. + +- For the `aarch64` architecture the instruction `21403c91` (or `add x1, x1, #0xf10`) would be zeroed if the incoming `x1` was a pointer into a mapped region. #### What is the UUIDv5 namespace? -The namespace for Basic Block GUID's is `0192a178-7a5f-7936-8653-3cbaa7d6afe7`. +The namespace for Basic Block GUIDs is `0192a178-7a5f-7936-8653-3cbaa7d6afe7`. -### Function Constraints +### Constraints -Function constraints allow us to further disambiguate between functions with the same GUID, when creating the functions we store information about the following: +Constraints allow us to further disambiguate between functions with the same GUID; when creating the functions, we retrieve extra information +that is consistent between versions of the same function, some examples are: - Called functions - Caller functions - Adjacent functions -Each entry in the lists above is referred to as a "constraint" that can be used to further reduce the number of matches for a given function GUID. +Each extra piece of information is referred to as a "constraint" that can be used to further reduce the number of matches for a given function GUID. + +#### Creating a Constraint + +Constraints are made up of a GUID and optionally, a matching offset. Adding a matching offset is preferred to give locality to the constraints, +for example, if you have a function `A` which calls into function `B` that is one constraint, but if the function `B` is also adjacent to function `A` +without a matching offset the two constraints may be merged into a single one, reducing the number of matching constraints. + +- The adjacent function `B` as a constraint: `(9F188A12-3EA1-477D-B368-361936EEA213, -30)` +- The call to function `B` as a constraint: `(9F188A12-3EA1-477D-B368-361936EEA213, 48)` + +#### Creating a Constraint GUID + +The constraint GUID is the UUIDv5 of the relevant bytes that would be computable at creation time and lookup time. + +##### What is the UUIDv5 namespace? + +The namespace for Constraint GUIDs is `019701f3-e89c-7afa-9181-371a5e98a576`. ##### Why don't we require matching on constraints for trivial functions? @@ -111,12 +133,46 @@ The main difference between **WARP** and **FLIRT** is the approach to identifica #### Function Identification - **WARP** the function identification is described [here](#function-identification). -- **FLIRT** uses incomplete function byte sequence with a mask where there is a single function entry (see: [IDA FLIRT Documentation] for a full description). +- **FLIRT** uses an incomplete function byte sequence with a mask where there is a single function entry (see: [IDA FLIRT Documentation] for a full description). -What this means in practice is **WARP** will have less false positives based solely off the initial function identification. +What this means in practice is **WARP** will have fewer false positives based solely off the initial function identification. When the returned set of functions is greater than one, we can use the list of [Function Constraints](#function-constraints) to select the best possible match. However, that comes at the cost of requiring a computed GUID to be created whenever the lookup is requested and that the function GUID is _**always**_ the same. +### WARP vs SigKit + +Because WARP is a replacement for SigKit it makes sense to not only talk about the function identification approach, but also the integration with [Binary Ninja]. + +#### SigKit Function Identification + +SigKit's function identification is similar to FLIRT so to not repeat what is said above, see [here](#function-identification). + +One difference to point out is SigKit relies on relocations during signature generation. Because of this, firmware or other types of binaries lacking relocations will likely fail to mask off the required instructions. + +#### Binary Ninja Integration + +The two main processes that exist for both SigKit and WARP integration with Binary Ninja are the function lookup process and the signature generation process. + +##### Function lookup + +SigKit's function lookup process is integrated as a core component to Binary Ninja as such it is not open source, however, the process is described [here](https://binary.ninja/2020/03/11/signature-libraries.html). + +What this means is **WARP** unlike SigKit can identify a greater number of smaller functions, ones which would be required to be pruned in the generation process. +After looking up a function and successfully matching **WARP** will also be able to apply type information. + +##### Signature generation + +SigKit's signature generation is provided through user python scripts located [here](https://github.com/Vector35/sigkit/tree/master). + +Because of the separation of the signature generation and the core integration, the process becomes very cumbersome, specifically the process is too convoluted for smaller samples, and too slow for bigger samples. + +#### What does this mean? + +WARP can match on a greater number of functions which otherwise would be pruned at the generation process, this is not without its tradeoffs, we generate this function UUID on both ends, meaning that the algorithm must be carefully upgraded to ensure that previously generated UUID's are no longer valid. + +Aside from just the matching of functions, we _never_ prune functions when added to the dataset this means we actually can store multiple functions for any given UUID. This is a major advantage for users who can now identify exactly what causes a collision and override, or otherwise understand more about the function. + +After matching on a function successfully, we can reconstruct the function signature, not just the symbol name. SigKit has no information about the function calling convention or the function type. [1]: https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583 [2]: https://devblogs.microsoft.com/oldnewthing/20221109-00/?p=107373 diff --git a/about.toml b/about.toml index afd187c..9f2bbd3 100644 --- a/about.toml +++ b/about.toml @@ -3,6 +3,7 @@ accepted = [ "Apache-2.0", "MIT", "Unicode-DFS-2016", + "Unicode-3.0", "OFL-1.1", "BSL-1.0", "BSD-3-Clause", @@ -11,5 +12,6 @@ accepted = [ "NOASSERTION", "ISC", "Zlib", - "OpenSSL" + "OpenSSL", + "NCSA" ] \ No newline at end of file diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..d428fed --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "warp" +version = "1.0.0" +edition = "2021" +license = "Apache-2.0" + +[dependencies] +flatbuffers = "25.2.10" +bon = "3.6.4" +uuid = { version = "1.17.0", features = ["v5"]} +flate2 = "1.1.2" +itertools = "0.14" + +[features] +default = [] +gen_flatbuffers = ["dep:flatbuffers-build"] + +[dev-dependencies] +criterion = "0.6.0" +insta = { version = "1.43.1", features = ["yaml"] } + +[build-dependencies] +flatbuffers-build = { git = "https://github.com/emesare/flatbuffers-build", rev = "44410b9", features = ["vendored"], optional = true } + +[[bench]] +name = "type" +harness = false + +[[bench]] +name = "chunk" +harness = false \ No newline at end of file diff --git a/rust/benches/chunk.rs b/rust/benches/chunk.rs new file mode 100644 index 0000000..d5d8019 --- /dev/null +++ b/rust/benches/chunk.rs @@ -0,0 +1,64 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use std::str::FromStr; +use warp::chunk::{Chunk, ChunkKind, CompressionType}; +use warp::mock::{mock_function, mock_function_type_class, mock_type}; +use warp::r#type::chunk::TypeChunk; +use warp::signature::chunk::SignatureChunk; +use warp::signature::function::FunctionGUID; +use warp::{WarpFile, WarpFileHeader}; + +pub fn chunk_benchmark(c: &mut Criterion) { + let count = 10000; + // Fill out a signature chunk with functions. + let mut functions = Vec::new(); + for i in 0..count { + functions.push(mock_function(&format!("function_{}", i))); + } + let mut _signature_chunk = SignatureChunk::new(&functions).expect("Failed to create chunk"); + let signature_chunk = Chunk::new( + ChunkKind::Signature(_signature_chunk.clone()), + CompressionType::None, + ); + + // Fill out a type chunk with types. + let mut types = Vec::new(); + for i in 0..count { + types.push(mock_type( + &format!("type_{}", i), + mock_function_type_class(), + )); + } + let _type_chunk = TypeChunk::new(&types).expect("Failed to create chunk"); + let type_chunk = Chunk::new(ChunkKind::Type(_type_chunk), CompressionType::Zstd); + let file = WarpFile::new( + WarpFileHeader::new(), + vec![signature_chunk.clone(), type_chunk], + ); + c.bench_function("file to bytes", |b| { + b.iter(|| { + file.to_bytes(); + }) + }); + + let known_function = functions.get(326).expect("Failed to get function 326").guid; + c.bench_function("find known function", |b| { + b.iter(|| { + _signature_chunk + .raw_functions_with_guid(&known_function) + .count() + }) + }); + + let unknown_function = FunctionGUID::from_str("467aae0d-84d4-4804-90d2-a62159502367") + .expect("Failed to get unknown function GUID"); + c.bench_function("find unknown function", |b| { + b.iter(|| { + _signature_chunk + .raw_functions_with_guid(&unknown_function) + .count() + }) + }); +} + +criterion_group!(benches, chunk_benchmark); +criterion_main!(benches); diff --git a/rust/benches/type.rs b/rust/benches/type.rs new file mode 100644 index 0000000..473f5ce --- /dev/null +++ b/rust/benches/type.rs @@ -0,0 +1,45 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use warp::mock::{mock_int_type_class, mock_type}; +use warp::r#type::class::{StructureClass, StructureMember, TypeClass}; +use warp::r#type::guid::TypeGUID; +use warp::r#type::Type; + +pub fn void_benchmark(c: &mut Criterion) { + let void_type = Type::builder() + .name("my_void".to_owned()) + .class(TypeClass::Void) + .build(); + + c.bench_function("uuid void", |b| { + b.iter(|| { + let _ = TypeGUID::from(&void_type); + }) + }); + + c.bench_function("computed void", |b| b.iter(|| void_type.to_bytes())); +} + +pub fn struct_benchmark(c: &mut Criterion) { + let int_type = mock_type("my_int", mock_int_type_class(None, false)); + let structure_member = StructureMember::builder() + .name("member") + .ty(int_type) + .offset(0) + .build(); + let struct_class = StructureClass::new(vec![structure_member]); + let struct_type = Type::builder() + .name("my_struct".to_owned()) + .class(TypeClass::Structure(struct_class)) + .build(); + + c.bench_function("uuid struct", |b| { + b.iter(|| { + let _ = TypeGUID::from(&struct_type); + }) + }); + + c.bench_function("computed struct", |b| b.iter(|| struct_type.to_bytes())); +} + +criterion_group!(benches, void_benchmark, struct_benchmark); +criterion_main!(benches); diff --git a/rust/benches/void.rs b/rust/benches/void.rs deleted file mode 100644 index 6e2af22..0000000 --- a/rust/benches/void.rs +++ /dev/null @@ -1,22 +0,0 @@ -use criterion::{criterion_group, criterion_main, Criterion}; -use warp::r#type::class::TypeClass; -use warp::r#type::guid::TypeGUID; -use warp::r#type::Type; - -pub fn void_benchmark(c: &mut Criterion) { - let void_type = Type::builder() - .name("my_void".to_owned()) - .class(TypeClass::Void) - .build(); - - c.bench_function("uuid void", |b| { - b.iter(|| { - let _ = TypeGUID::from(&void_type); - }) - }); - - c.bench_function("computed void", |b| b.iter(|| void_type.to_bytes())); -} - -criterion_group!(benches, void_benchmark); -criterion_main!(benches); diff --git a/build.rs b/rust/build.rs similarity index 63% rename from build.rs rename to rust/build.rs index 1998d4b..8a9e11e 100644 --- a/build.rs +++ b/rust/build.rs @@ -10,11 +10,13 @@ pub fn main() { let _ = std::fs::remove_dir_all("rust/gen_flatbuffers"); let workspace_dir: PathBuf = std::env::var("CARGO_MANIFEST_DIR").unwrap().into(); BuilderOptions::new_with_files([ - workspace_dir.join("type.fbs"), - workspace_dir.join("symbol.fbs"), - workspace_dir.join("signature.fbs"), + workspace_dir.join("../type.fbs"), + workspace_dir.join("../symbol.fbs"), + workspace_dir.join("../signature.fbs"), + workspace_dir.join("../target.fbs"), + workspace_dir.join("../warp.fbs"), ]) - .set_output_path("rust/gen_flatbuffers") + .set_output_path("src/gen_flatbuffers") .compile() .expect("flatbuffer compilation failed"); } diff --git a/rust/examples/dumper.rs b/rust/examples/dumper.rs new file mode 100644 index 0000000..c1f4fb7 --- /dev/null +++ b/rust/examples/dumper.rs @@ -0,0 +1,43 @@ +use std::env; +use std::fs::File; +use std::io::Read; +use std::path::Path; +use warp::chunk::ChunkKind; + +fn main() -> Result<(), Box> { + let args: Vec = env::args().collect(); + if args.len() < 2 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + + let path = Path::new(&args[1]); + let mut file = File::open(path)?; + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer)?; + + let file = warp::WarpFile::from_bytes(&buffer).expect("Failed to parse file"); + + for chunk in file.chunks { + match chunk.kind { + ChunkKind::Signature(sc) => { + println!("=== Signature chunk ==="); + for func in sc.functions() { + println!("{} | {}", func.symbol.name, func.guid); + } + } + ChunkKind::Type(tc) => { + println!("=== Type chunk ==="); + for ty in tc.types() { + println!( + "{} | {}", + ty.ty.name.unwrap_or("ANONYMOUS".to_string()), + ty.guid + ); + } + } + } + } + + Ok(()) +} diff --git a/rust/examples/random.rs b/rust/examples/random.rs new file mode 100644 index 0000000..3006699 --- /dev/null +++ b/rust/examples/random.rs @@ -0,0 +1,44 @@ +use std::env; +use warp::chunk::{Chunk, ChunkKind, CompressionType}; +use warp::mock::{mock_function, mock_function_type_class, mock_type}; +use warp::r#type::chunk::TypeChunk; +use warp::signature::chunk::SignatureChunk; +use warp::WarpFileHeader; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() < 2 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + let count: u32 = args[1].parse().expect("Valid integer"); + + // Fill out a signature chunk with functions. + let mut functions = Vec::new(); + for i in 0..count { + functions.push(mock_function(&format!("function_{}", i))); + } + let _signature_chunk = SignatureChunk::new(&functions).expect("Failed to create chunk"); + let signature_chunk = Chunk::new( + ChunkKind::Signature(_signature_chunk), + CompressionType::Zstd, + ); + println!("Created signature chunk with {} functions...", count); + + // Fill out a type chunk with types. + let mut types = Vec::new(); + for i in 0..count { + types.push(mock_type( + &format!("type_{}", i), + mock_function_type_class(), + )); + } + let _type_chunk = TypeChunk::new(&types).expect("Failed to create chunk"); + let type_chunk = Chunk::new(ChunkKind::Type(_type_chunk), CompressionType::Zstd); + println!("Created type chunk with {} types...", types.len()); + + let file = warp::WarpFile::new(WarpFileHeader::new(), vec![signature_chunk, type_chunk]); + println!("Created file with {} chunks...", file.chunks.len()); + + std::fs::write("random.warp", file.to_bytes()).expect("Failed to write file"); +} diff --git a/rust/examples/simple.rs b/rust/examples/type_builder.rs similarity index 100% rename from rust/examples/simple.rs rename to rust/examples/type_builder.rs diff --git a/rust/fixtures/random.warp b/rust/fixtures/random.warp new file mode 100644 index 0000000..47c7367 Binary files /dev/null and b/rust/fixtures/random.warp differ diff --git a/rust/fuzz/.gitignore b/rust/fuzz/.gitignore new file mode 100644 index 0000000..1a45eee --- /dev/null +++ b/rust/fuzz/.gitignore @@ -0,0 +1,4 @@ +target +corpus +artifacts +coverage diff --git a/rust/fuzz/Cargo.toml b/rust/fuzz/Cargo.toml new file mode 100644 index 0000000..0b15367 --- /dev/null +++ b/rust/fuzz/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "warp-fuzz" +version = "0.0.0" +publish = false +edition = "2021" +license = "Apache-2.0" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.warp] +path = ".." + +[[bin]] +name = "type" +path = "fuzz_targets/type.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "function" +path = "fuzz_targets/function.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "file" +path = "fuzz_targets/file.rs" +test = false +doc = false +bench = false \ No newline at end of file diff --git a/rust/fuzz/fuzz_targets/file.rs b/rust/fuzz/fuzz_targets/file.rs new file mode 100644 index 0000000..20663e5 --- /dev/null +++ b/rust/fuzz/fuzz_targets/file.rs @@ -0,0 +1,13 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use warp::WarpFile; + +fuzz_target!(|data: &[u8]| { + if let Some(file) = WarpFile::from_bytes(data) { + let file_bytes = file.to_bytes(); + if WarpFile::from_bytes(&file_bytes).is_none() { + panic!("Failed to round-trip file"); + } + } +}); diff --git a/rust/fuzz/fuzz_targets/function.rs b/rust/fuzz/fuzz_targets/function.rs new file mode 100644 index 0000000..c53af68 --- /dev/null +++ b/rust/fuzz/fuzz_targets/function.rs @@ -0,0 +1,11 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use warp::signature::function::Function; + +fuzz_target!(|data: &[u8]| { + if let Some(func) = Function::from_bytes(data) { + let func_bytes = func.to_bytes(); + Function::from_bytes(&func_bytes).expect("Failed to round-trip function"); + } +}); diff --git a/rust/fuzz/fuzz_targets/type.rs b/rust/fuzz/fuzz_targets/type.rs new file mode 100644 index 0000000..2321c9a --- /dev/null +++ b/rust/fuzz/fuzz_targets/type.rs @@ -0,0 +1,10 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; +use warp::r#type::Type; + +fuzz_target!(|data: &[u8]| { + if let Some(ty) = Type::from_bytes(data) { + let ty_bytes = ty.to_bytes(); + Type::from_bytes(&ty_bytes).expect("Failed to round-trip type"); + } +}); diff --git a/rust/gen_flatbuffers/sig_bin/data_generated.rs b/rust/gen_flatbuffers/sig_bin/data_generated.rs deleted file mode 100644 index 94a761d..0000000 --- a/rust/gen_flatbuffers/sig_bin/data_generated.rs +++ /dev/null @@ -1,210 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum DataOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct Data<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for Data<'a> { - type Inner = Data<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> Data<'a> { - pub const VT_FUNCTIONS: flatbuffers::VOffsetT = 4; - pub const VT_TYPES: flatbuffers::VOffsetT = 6; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - Data { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args DataArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = DataBuilder::new(_fbb); - if let Some(x) = args.types { builder.add_types(x); } - if let Some(x) = args.functions { builder.add_functions(x); } - builder.finish() - } - - - #[inline] - pub fn functions(&self) -> Option>>> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>>(Data::VT_FUNCTIONS, None)} - } - #[inline] - pub fn types(&self) -> Option>>> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>>(Data::VT_TYPES, None)} - } -} - -impl flatbuffers::Verifiable for Data<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>>>("functions", Self::VT_FUNCTIONS, false)? - .visit_field::>>>("types", Self::VT_TYPES, false)? - .finish(); - Ok(()) - } -} -pub struct DataArgs<'a> { - pub functions: Option>>>>, - pub types: Option>>>>, -} -impl<'a> Default for DataArgs<'a> { - #[inline] - fn default() -> Self { - DataArgs { - functions: None, - types: None, - } - } -} - -pub struct DataBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DataBuilder<'a, 'b, A> { - #[inline] - pub fn add_functions(&mut self, functions: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(Data::VT_FUNCTIONS, functions); - } - #[inline] - pub fn add_types(&mut self, types: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(Data::VT_TYPES, types); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DataBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - DataBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for Data<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("Data"); - ds.field("functions", &self.functions()); - ds.field("types", &self.types()); - ds.finish() - } -} -#[inline] -/// Verifies that a buffer of bytes contains a `Data` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_data_unchecked`. -pub fn root_as_data(buf: &[u8]) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `Data` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_data_unchecked`. -pub fn size_prefixed_root_as_data(buf: &[u8]) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `Data` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_data_unchecked`. -pub fn root_as_data_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `Data` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_data_unchecked`. -pub fn size_prefixed_root_as_data_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a Data and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `Data`. -pub unsafe fn root_as_data_unchecked(buf: &[u8]) -> Data { - flatbuffers::root_unchecked::(buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed Data and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `Data`. -pub unsafe fn size_prefixed_root_as_data_unchecked(buf: &[u8]) -> Data { - flatbuffers::size_prefixed_root_unchecked::(buf) -} -pub const DATA_IDENTIFIER: &str = "SBIN"; - -#[inline] -pub fn data_buffer_has_identifier(buf: &[u8]) -> bool { - flatbuffers::buffer_has_identifier(buf, DATA_IDENTIFIER, false) -} - -#[inline] -pub fn data_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { - flatbuffers::buffer_has_identifier(buf, DATA_IDENTIFIER, true) -} - -pub const DATA_EXTENSION: &str = "sbin"; - -#[inline] -pub fn finish_data_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>) { - fbb.finish(root, Some(DATA_IDENTIFIER)); -} - -#[inline] -pub fn finish_size_prefixed_data_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { - fbb.finish_size_prefixed(root, Some(DATA_IDENTIFIER)); -} diff --git a/rust/gen_flatbuffers/sig_bin/function_constraint_generated.rs b/rust/gen_flatbuffers/sig_bin/function_constraint_generated.rs deleted file mode 100644 index 035a160..0000000 --- a/rust/gen_flatbuffers/sig_bin/function_constraint_generated.rs +++ /dev/null @@ -1,142 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum FunctionConstraintOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct FunctionConstraint<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for FunctionConstraint<'a> { - type Inner = FunctionConstraint<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> FunctionConstraint<'a> { - pub const VT_GUID: flatbuffers::VOffsetT = 4; - pub const VT_SYMBOL: flatbuffers::VOffsetT = 6; - pub const VT_OFFSET: flatbuffers::VOffsetT = 8; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - FunctionConstraint { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args FunctionConstraintArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = FunctionConstraintBuilder::new(_fbb); - builder.add_offset(args.offset); - if let Some(x) = args.symbol { builder.add_symbol(x); } - if let Some(x) = args.guid { builder.add_guid(x); } - builder.finish() - } - - - #[inline] - pub fn guid(&self) -> Option<&'a str> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(FunctionConstraint::VT_GUID, None)} - } - #[inline] - pub fn symbol(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(FunctionConstraint::VT_SYMBOL, None)} - } - #[inline] - pub fn offset(&self) -> i64 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(FunctionConstraint::VT_OFFSET, Some(0)).unwrap()} - } -} - -impl flatbuffers::Verifiable for FunctionConstraint<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>("guid", Self::VT_GUID, false)? - .visit_field::>("symbol", Self::VT_SYMBOL, false)? - .visit_field::("offset", Self::VT_OFFSET, false)? - .finish(); - Ok(()) - } -} -pub struct FunctionConstraintArgs<'a> { - pub guid: Option>, - pub symbol: Option>>, - pub offset: i64, -} -impl<'a> Default for FunctionConstraintArgs<'a> { - #[inline] - fn default() -> Self { - FunctionConstraintArgs { - guid: None, - symbol: None, - offset: 0, - } - } -} - -pub struct FunctionConstraintBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionConstraintBuilder<'a, 'b, A> { - #[inline] - pub fn add_guid(&mut self, guid: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(FunctionConstraint::VT_GUID, guid); - } - #[inline] - pub fn add_symbol(&mut self, symbol: flatbuffers::WIPOffset>) { - self.fbb_.push_slot_always::>(FunctionConstraint::VT_SYMBOL, symbol); - } - #[inline] - pub fn add_offset(&mut self, offset: i64) { - self.fbb_.push_slot::(FunctionConstraint::VT_OFFSET, offset, 0); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionConstraintBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - FunctionConstraintBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for FunctionConstraint<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("FunctionConstraint"); - ds.field("guid", &self.guid()); - ds.field("symbol", &self.symbol()); - ds.field("offset", &self.offset()); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/sig_bin/function_constraints_generated.rs b/rust/gen_flatbuffers/sig_bin/function_constraints_generated.rs deleted file mode 100644 index adf2637..0000000 --- a/rust/gen_flatbuffers/sig_bin/function_constraints_generated.rs +++ /dev/null @@ -1,142 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum FunctionConstraintsOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct FunctionConstraints<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for FunctionConstraints<'a> { - type Inner = FunctionConstraints<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> FunctionConstraints<'a> { - pub const VT_ADJACENT: flatbuffers::VOffsetT = 4; - pub const VT_CALL_SITES: flatbuffers::VOffsetT = 6; - pub const VT_CALLER_SITES: flatbuffers::VOffsetT = 8; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - FunctionConstraints { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args FunctionConstraintsArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = FunctionConstraintsBuilder::new(_fbb); - if let Some(x) = args.caller_sites { builder.add_caller_sites(x); } - if let Some(x) = args.call_sites { builder.add_call_sites(x); } - if let Some(x) = args.adjacent { builder.add_adjacent(x); } - builder.finish() - } - - - #[inline] - pub fn adjacent(&self) -> Option>>> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>>(FunctionConstraints::VT_ADJACENT, None)} - } - #[inline] - pub fn call_sites(&self) -> Option>>> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>>(FunctionConstraints::VT_CALL_SITES, None)} - } - #[inline] - pub fn caller_sites(&self) -> Option>>> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>>(FunctionConstraints::VT_CALLER_SITES, None)} - } -} - -impl flatbuffers::Verifiable for FunctionConstraints<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>>>("adjacent", Self::VT_ADJACENT, false)? - .visit_field::>>>("call_sites", Self::VT_CALL_SITES, false)? - .visit_field::>>>("caller_sites", Self::VT_CALLER_SITES, false)? - .finish(); - Ok(()) - } -} -pub struct FunctionConstraintsArgs<'a> { - pub adjacent: Option>>>>, - pub call_sites: Option>>>>, - pub caller_sites: Option>>>>, -} -impl<'a> Default for FunctionConstraintsArgs<'a> { - #[inline] - fn default() -> Self { - FunctionConstraintsArgs { - adjacent: None, - call_sites: None, - caller_sites: None, - } - } -} - -pub struct FunctionConstraintsBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionConstraintsBuilder<'a, 'b, A> { - #[inline] - pub fn add_adjacent(&mut self, adjacent: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(FunctionConstraints::VT_ADJACENT, adjacent); - } - #[inline] - pub fn add_call_sites(&mut self, call_sites: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(FunctionConstraints::VT_CALL_SITES, call_sites); - } - #[inline] - pub fn add_caller_sites(&mut self, caller_sites: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(FunctionConstraints::VT_CALLER_SITES, caller_sites); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionConstraintsBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - FunctionConstraintsBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for FunctionConstraints<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("FunctionConstraints"); - ds.field("adjacent", &self.adjacent()); - ds.field("call_sites", &self.call_sites()); - ds.field("caller_sites", &self.caller_sites()); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/symbol_bin/data_symbol_class_generated.rs b/rust/gen_flatbuffers/symbol_bin/data_symbol_class_generated.rs deleted file mode 100644 index 7f202ae..0000000 --- a/rust/gen_flatbuffers/symbol_bin/data_symbol_class_generated.rs +++ /dev/null @@ -1,90 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum DataSymbolClassOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct DataSymbolClass<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for DataSymbolClass<'a> { - type Inner = DataSymbolClass<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> DataSymbolClass<'a> { - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - DataSymbolClass { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - _args: &'args DataSymbolClassArgs - ) -> flatbuffers::WIPOffset> { - let mut builder = DataSymbolClassBuilder::new(_fbb); - builder.finish() - } - -} - -impl flatbuffers::Verifiable for DataSymbolClass<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .finish(); - Ok(()) - } -} -pub struct DataSymbolClassArgs { -} -impl<'a> Default for DataSymbolClassArgs { - #[inline] - fn default() -> Self { - DataSymbolClassArgs { - } - } -} - -pub struct DataSymbolClassBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DataSymbolClassBuilder<'a, 'b, A> { - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DataSymbolClassBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - DataSymbolClassBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for DataSymbolClass<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("DataSymbolClass"); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/symbol_bin/function_symbol_class_generated.rs b/rust/gen_flatbuffers/symbol_bin/function_symbol_class_generated.rs deleted file mode 100644 index 9a4e233..0000000 --- a/rust/gen_flatbuffers/symbol_bin/function_symbol_class_generated.rs +++ /dev/null @@ -1,90 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum FunctionSymbolClassOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct FunctionSymbolClass<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for FunctionSymbolClass<'a> { - type Inner = FunctionSymbolClass<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> FunctionSymbolClass<'a> { - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - FunctionSymbolClass { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - _args: &'args FunctionSymbolClassArgs - ) -> flatbuffers::WIPOffset> { - let mut builder = FunctionSymbolClassBuilder::new(_fbb); - builder.finish() - } - -} - -impl flatbuffers::Verifiable for FunctionSymbolClass<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .finish(); - Ok(()) - } -} -pub struct FunctionSymbolClassArgs { -} -impl<'a> Default for FunctionSymbolClassArgs { - #[inline] - fn default() -> Self { - FunctionSymbolClassArgs { - } - } -} - -pub struct FunctionSymbolClassBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionSymbolClassBuilder<'a, 'b, A> { - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionSymbolClassBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - FunctionSymbolClassBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for FunctionSymbolClass<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("FunctionSymbolClass"); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/type_bin/access_alignment_generated.rs b/rust/gen_flatbuffers/type_bin/access_alignment_generated.rs deleted file mode 100644 index cd433f2..0000000 --- a/rust/gen_flatbuffers/type_bin/access_alignment_generated.rs +++ /dev/null @@ -1,90 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum AccessAlignmentOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct AccessAlignment<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for AccessAlignment<'a> { - type Inner = AccessAlignment<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> AccessAlignment<'a> { - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - AccessAlignment { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - _args: &'args AccessAlignmentArgs - ) -> flatbuffers::WIPOffset> { - let mut builder = AccessAlignmentBuilder::new(_fbb); - builder.finish() - } - -} - -impl flatbuffers::Verifiable for AccessAlignment<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .finish(); - Ok(()) - } -} -pub struct AccessAlignmentArgs { -} -impl<'a> Default for AccessAlignmentArgs { - #[inline] - fn default() -> Self { - AccessAlignmentArgs { - } - } -} - -pub struct AccessAlignmentBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> AccessAlignmentBuilder<'a, 'b, A> { - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> AccessAlignmentBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - AccessAlignmentBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for AccessAlignment<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("AccessAlignment"); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/type_bin/constant_modifier_class_generated.rs b/rust/gen_flatbuffers/type_bin/constant_modifier_class_generated.rs deleted file mode 100644 index ca37311..0000000 --- a/rust/gen_flatbuffers/type_bin/constant_modifier_class_generated.rs +++ /dev/null @@ -1,90 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum ConstantModifierClassOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct ConstantModifierClass<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for ConstantModifierClass<'a> { - type Inner = ConstantModifierClass<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> ConstantModifierClass<'a> { - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - ConstantModifierClass { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - _args: &'args ConstantModifierClassArgs - ) -> flatbuffers::WIPOffset> { - let mut builder = ConstantModifierClassBuilder::new(_fbb); - builder.finish() - } - -} - -impl flatbuffers::Verifiable for ConstantModifierClass<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .finish(); - Ok(()) - } -} -pub struct ConstantModifierClassArgs { -} -impl<'a> Default for ConstantModifierClassArgs { - #[inline] - fn default() -> Self { - ConstantModifierClassArgs { - } - } -} - -pub struct ConstantModifierClassBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ConstantModifierClassBuilder<'a, 'b, A> { - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ConstantModifierClassBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - ConstantModifierClassBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for ConstantModifierClass<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("ConstantModifierClass"); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/type_bin/descriptor_modifier_class_generated.rs b/rust/gen_flatbuffers/type_bin/descriptor_modifier_class_generated.rs deleted file mode 100644 index 55b2ed8..0000000 --- a/rust/gen_flatbuffers/type_bin/descriptor_modifier_class_generated.rs +++ /dev/null @@ -1,108 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum DescriptorModifierClassOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct DescriptorModifierClass<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for DescriptorModifierClass<'a> { - type Inner = DescriptorModifierClass<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> DescriptorModifierClass<'a> { - pub const VT_DESCRIPTION: flatbuffers::VOffsetT = 4; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - DescriptorModifierClass { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args DescriptorModifierClassArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = DescriptorModifierClassBuilder::new(_fbb); - if let Some(x) = args.description { builder.add_description(x); } - builder.finish() - } - - - #[inline] - pub fn description(&self) -> Option<&'a str> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(DescriptorModifierClass::VT_DESCRIPTION, None)} - } -} - -impl flatbuffers::Verifiable for DescriptorModifierClass<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>("description", Self::VT_DESCRIPTION, false)? - .finish(); - Ok(()) - } -} -pub struct DescriptorModifierClassArgs<'a> { - pub description: Option>, -} -impl<'a> Default for DescriptorModifierClassArgs<'a> { - #[inline] - fn default() -> Self { - DescriptorModifierClassArgs { - description: None, - } - } -} - -pub struct DescriptorModifierClassBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DescriptorModifierClassBuilder<'a, 'b, A> { - #[inline] - pub fn add_description(&mut self, description: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(DescriptorModifierClass::VT_DESCRIPTION, description); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DescriptorModifierClassBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - DescriptorModifierClassBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for DescriptorModifierClass<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("DescriptorModifierClass"); - ds.field("description", &self.description()); - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/type_bin/type_modifier_generated.rs b/rust/gen_flatbuffers/type_bin/type_modifier_generated.rs deleted file mode 100644 index fdecfb1..0000000 --- a/rust/gen_flatbuffers/type_bin/type_modifier_generated.rs +++ /dev/null @@ -1,225 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum TypeModifierOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct TypeModifier<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for TypeModifier<'a> { - type Inner = TypeModifier<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> TypeModifier<'a> { - pub const VT_CLASS_TYPE: flatbuffers::VOffsetT = 4; - pub const VT_CLASS: flatbuffers::VOffsetT = 6; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - TypeModifier { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args TypeModifierArgs - ) -> flatbuffers::WIPOffset> { - let mut builder = TypeModifierBuilder::new(_fbb); - if let Some(x) = args.class { builder.add_class(x); } - builder.add_class_type(args.class_type); - builder.finish() - } - - - #[inline] - pub fn class_type(&self) -> TypeModifierClass { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(TypeModifier::VT_CLASS_TYPE, Some(TypeModifierClass::NONE)).unwrap()} - } - #[inline] - pub fn class(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(TypeModifier::VT_CLASS, None)} - } - #[inline] - #[allow(non_snake_case)] - pub fn class_as_constant_modifier_class(&self) -> Option> { - if self.class_type() == TypeModifierClass::ConstantModifierClass { - self.class().map(|t| { - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - unsafe { ConstantModifierClass::init_from_table(t) } - }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn class_as_volatile_modifier_class(&self) -> Option> { - if self.class_type() == TypeModifierClass::VolatileModifierClass { - self.class().map(|t| { - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - unsafe { VolatileModifierClass::init_from_table(t) } - }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn class_as_descriptor_modifier_class(&self) -> Option> { - if self.class_type() == TypeModifierClass::DescriptorModifierClass { - self.class().map(|t| { - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - unsafe { DescriptorModifierClass::init_from_table(t) } - }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn class_as_metadata_modifier_class(&self) -> Option> { - if self.class_type() == TypeModifierClass::MetadataModifierClass { - self.class().map(|t| { - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - unsafe { MetadataModifierClass::init_from_table(t) } - }) - } else { - None - } - } - -} - -impl flatbuffers::Verifiable for TypeModifier<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_union::("class_type", Self::VT_CLASS_TYPE, "class", Self::VT_CLASS, false, |key, v, pos| { - match key { - TypeModifierClass::ConstantModifierClass => v.verify_union_variant::>("TypeModifierClass::ConstantModifierClass", pos), - TypeModifierClass::VolatileModifierClass => v.verify_union_variant::>("TypeModifierClass::VolatileModifierClass", pos), - TypeModifierClass::DescriptorModifierClass => v.verify_union_variant::>("TypeModifierClass::DescriptorModifierClass", pos), - TypeModifierClass::MetadataModifierClass => v.verify_union_variant::>("TypeModifierClass::MetadataModifierClass", pos), - _ => Ok(()), - } - })? - .finish(); - Ok(()) - } -} -pub struct TypeModifierArgs { - pub class_type: TypeModifierClass, - pub class: Option>, -} -impl<'a> Default for TypeModifierArgs { - #[inline] - fn default() -> Self { - TypeModifierArgs { - class_type: TypeModifierClass::NONE, - class: None, - } - } -} - -pub struct TypeModifierBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TypeModifierBuilder<'a, 'b, A> { - #[inline] - pub fn add_class_type(&mut self, class_type: TypeModifierClass) { - self.fbb_.push_slot::(TypeModifier::VT_CLASS_TYPE, class_type, TypeModifierClass::NONE); - } - #[inline] - pub fn add_class(&mut self, class: flatbuffers::WIPOffset) { - self.fbb_.push_slot_always::>(TypeModifier::VT_CLASS, class); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TypeModifierBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - TypeModifierBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for TypeModifier<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("TypeModifier"); - ds.field("class_type", &self.class_type()); - match self.class_type() { - TypeModifierClass::ConstantModifierClass => { - if let Some(x) = self.class_as_constant_modifier_class() { - ds.field("class", &x) - } else { - ds.field("class", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - TypeModifierClass::VolatileModifierClass => { - if let Some(x) = self.class_as_volatile_modifier_class() { - ds.field("class", &x) - } else { - ds.field("class", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - TypeModifierClass::DescriptorModifierClass => { - if let Some(x) = self.class_as_descriptor_modifier_class() { - ds.field("class", &x) - } else { - ds.field("class", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - TypeModifierClass::MetadataModifierClass => { - if let Some(x) = self.class_as_metadata_modifier_class() { - ds.field("class", &x) - } else { - ds.field("class", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - _ => { - let x: Option<()> = None; - ds.field("class", &x) - }, - }; - ds.finish() - } -} diff --git a/rust/gen_flatbuffers/type_bin/volatile_modifier_class_generated.rs b/rust/gen_flatbuffers/type_bin/volatile_modifier_class_generated.rs deleted file mode 100644 index 5c13e10..0000000 --- a/rust/gen_flatbuffers/type_bin/volatile_modifier_class_generated.rs +++ /dev/null @@ -1,90 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::mem; -use core::cmp::Ordering; -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum VolatileModifierClassOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct VolatileModifierClass<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for VolatileModifierClass<'a> { - type Inner = VolatileModifierClass<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> VolatileModifierClass<'a> { - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - VolatileModifierClass { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - _args: &'args VolatileModifierClassArgs - ) -> flatbuffers::WIPOffset> { - let mut builder = VolatileModifierClassBuilder::new(_fbb); - builder.finish() - } - -} - -impl flatbuffers::Verifiable for VolatileModifierClass<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .finish(); - Ok(()) - } -} -pub struct VolatileModifierClassArgs { -} -impl<'a> Default for VolatileModifierClassArgs { - #[inline] - fn default() -> Self { - VolatileModifierClassArgs { - } - } -} - -pub struct VolatileModifierClassBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> VolatileModifierClassBuilder<'a, 'b, A> { - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> VolatileModifierClassBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - VolatileModifierClassBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for VolatileModifierClass<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("VolatileModifierClass"); - ds.finish() - } -} diff --git a/rust/lib.rs b/rust/lib.rs deleted file mode 100644 index bd8787e..0000000 --- a/rust/lib.rs +++ /dev/null @@ -1,71 +0,0 @@ -pub mod signature; -pub mod symbol; -pub mod r#type; - -#[allow(warnings)] -#[rustfmt::skip] -mod gen_flatbuffers; - -use gen_flatbuffers::sig_bin as fb_sig; -use gen_flatbuffers::symbol_bin as fb_symbol; -use gen_flatbuffers::type_bin as fb_type; - -impl From for gen_flatbuffers::type_bin::BitWidth { - fn from(value: u16) -> Self { - Self::new(value) - } -} - -impl From<&gen_flatbuffers::type_bin::BitWidth> for u16 { - fn from(value: &gen_flatbuffers::type_bin::BitWidth) -> Self { - value.value() - } -} - -impl From for gen_flatbuffers::type_bin::BitSize { - fn from(value: u64) -> Self { - Self::new(value) - } -} - -impl From<&gen_flatbuffers::type_bin::BitSize> for u64 { - fn from(value: &gen_flatbuffers::type_bin::BitSize) -> Self { - value.value() - } -} - -impl From for gen_flatbuffers::type_bin::UnsignedBitOffset { - fn from(value: u64) -> Self { - Self::new(value) - } -} - -impl From<&gen_flatbuffers::type_bin::UnsignedBitOffset> for u64 { - fn from(value: &gen_flatbuffers::type_bin::UnsignedBitOffset) -> Self { - value.value() - } -} - -impl From for gen_flatbuffers::type_bin::BitOffset { - fn from(value: i64) -> Self { - Self::new(value) - } -} - -impl From<&gen_flatbuffers::type_bin::BitOffset> for i64 { - fn from(value: &gen_flatbuffers::type_bin::BitOffset) -> Self { - value.value() - } -} - -impl From for gen_flatbuffers::type_bin::BitShift { - fn from(value: i64) -> Self { - Self::new(value) - } -} - -impl From<&gen_flatbuffers::type_bin::BitShift> for i64 { - fn from(value: &gen_flatbuffers::type_bin::BitShift) -> Self { - value.value() - } -} diff --git a/rust/signature.rs b/rust/signature.rs deleted file mode 100644 index 8454a1d..0000000 --- a/rust/signature.rs +++ /dev/null @@ -1,295 +0,0 @@ -use crate::fb_sig as fb; -use crate::r#type::ComputedType; -use crate::signature::function::constraints::FunctionConstraint; -use crate::signature::function::{Function, FunctionGUID}; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use flate2::Compression; -use std::collections::HashMap; -use std::io::Write; - -pub mod basic_block; -pub mod function; - -#[derive(Clone, Debug, Eq, PartialEq, Default)] -pub struct Data { - pub functions: Vec, - pub types: Vec, -} - -impl Data { - pub fn new(functions: Vec, types: Vec) -> Self { - Self { functions, types } - } - - pub fn from_bytes(buf: &[u8]) -> Option { - let mut decoder = flate2::read::GzDecoder::new(buf); - let mut decompressed_data = Vec::new(); - std::io::copy(&mut decoder, &mut decompressed_data).ok()?; - let opts = flatbuffers::VerifierOptions { - // Trust me bro. - max_tables: 100_000_000, - ..Default::default() - }; - flatbuffers::root_with_opts::(&opts, &decompressed_data) - .ok() - .map(Into::into) - } - - // Given all [Data::functions] link the constraints with no GUID to other functions. - pub fn link_constraints(&mut self) { - // TODO: if symbol name appears more than once, we should remove it from here. - let guid_map: HashMap = self - .functions - .iter() - .map(|f| (f.symbol.name.to_owned(), f.guid)) - .collect(); - - let resolve_constraint = |mut constraint: FunctionConstraint| { - // If we don't have a guid for the constraint grab it from the symbol name - if constraint.guid.is_none() { - if let Some(symbol) = &constraint.symbol { - constraint.guid = guid_map.get(&symbol.name).copied(); - } - } - constraint - }; - - self.functions.iter_mut().for_each(|f| { - f.constraints.call_sites = f - .constraints - .call_sites - .iter() - .cloned() - .map(resolve_constraint) - .collect(); - f.constraints.adjacent = f - .constraints - .adjacent - .iter() - .cloned() - .map(resolve_constraint) - .collect(); - }); - } - - pub fn deduplicate(&mut self) { - // Sort and remove types with the same guid. - self.types.sort_by_key(|ty| ty.guid); - self.types.dedup_by_key(|ty| ty.guid); - // Sort and remove functions with the same symbol and guid. - self.functions - .sort_by(|a, b| a.guid.cmp(&b.guid).then_with(|| a.symbol.cmp(&b.symbol))); - self.functions.dedup_by(|a, b| { - if a.guid == b.guid && a.symbol == b.symbol { - // Keep `a`s constraints. - b.constraints - .adjacent - .extend(a.constraints.adjacent.clone()); - b.constraints - .call_sites - .extend(a.constraints.call_sites.clone()); - b.constraints - .caller_sites - .extend(a.constraints.caller_sites.clone()); - true - } else { - false - } - }); - } - - pub fn merge(entries: Vec) -> Data { - let mut merged_data = Data::default(); - - for entry in entries { - merged_data.functions.extend(entry.functions); - merged_data.types.extend(entry.types); - } - - // Chances are we will have a bunch of duplicated data. - merged_data.deduplicate(); - // Chances are we will have a bunch of stuff to link. - merged_data.link_constraints(); - merged_data - } - - pub fn to_bytes(&self) -> Vec { - let mut builder = FlatBufferBuilder::new(); - let fb_data = self.create(&mut builder); - builder.finish_minimal(fb_data); - // Move this to Data spec enum or something so that in the future we can do uncompressed versions. - let mut encoder = flate2::write::GzEncoder::new(Vec::new(), Compression::default()); - encoder - .write_all(builder.finished_data()) - .expect("Failed to compress data"); - encoder.finish().expect("Failed to finish compression") - } - - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let _functions: Vec<_> = self.functions.iter().map(|f| f.create(builder)).collect(); - let functions = builder.create_vector(&_functions); - let _types: Vec<_> = self.types.iter().map(|f| f.create(builder)).collect(); - let types = builder.create_vector(&_types); - fb::Data::create( - builder, - &fb::DataArgs { - functions: Some(functions), - types: Some(types), - }, - ) - } -} - -impl From> for Data { - fn from(value: fb::Data<'_>) -> Self { - Self { - functions: value.functions().unwrap().iter().map(Into::into).collect(), - // TODO: I think we can make this look better... - types: value - .types() - .map(|types| types.iter().map(Into::into).collect()) - .unwrap_or_default(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::r#type::guid::TypeGUID; - use crate::r#type::ComputedType; - use crate::signature::function::{Function, FunctionGUID}; - use crate::symbol::class::SymbolClass; - use crate::symbol::Symbol; - use uuid::{uuid, Uuid}; - - const FUNC1_GUID: Uuid = uuid!("6b50fa09-c8c5-4e88-b317-5a96c01c52ee"); - const FUNC2_GUID: Uuid = uuid!("e0565a4e-d730-4073-916c-fa6cb8ad2407"); - const FUNC3_GUID: Uuid = uuid!("5a7eb124-b786-4aa8-af2f-ccffbb600d21"); - - const TYPE1_GUID: Uuid = uuid!("7aee6520-0443-4a91-910e-da068571fa7a"); - const TYPE2_GUID: Uuid = uuid!("9e8a58f0-757d-4fa6-8c41-a4da023c5a32"); - const TYPE3_GUID: Uuid = uuid!("f81a46df-ad7b-4d7b-a4a7-23ed22ab01ec"); - - // Used with `test_merge` test. - fn create_sample_function>(name: &str, guid: T) -> Function { - Function { - symbol: Symbol { - name: name.to_string(), - modifiers: Default::default(), - class: SymbolClass::Function, - }, - guid: guid.into(), - constraints: Default::default(), - ty: rand::random(), - } - } - - // Used with `test_merge` test. - fn create_sample_computed_type>(guid: T) -> ComputedType { - let mut comp_ty = ComputedType::new(rand::random()); - comp_ty.guid = guid.into(); // Adjust the guid for testing. - comp_ty - } - - // Used with `test_link_constraints` test. - fn create_sample_function_constraint>( - name: &str, - guid: Option, - ) -> FunctionConstraint { - FunctionConstraint { - guid: guid.map(Into::into), - symbol: Some(Symbol { - name: name.to_string(), - modifiers: Default::default(), - class: SymbolClass::Function, - }), - offset: 0, - } - } - - #[test] - fn test_merge() { - let first_data = Data::new( - vec![ - create_sample_function("func1", FUNC1_GUID), - create_sample_function("func2", FUNC2_GUID), - ], - vec![ - create_sample_computed_type(TYPE1_GUID), - create_sample_computed_type(TYPE2_GUID), - ], - ); - - let second_data = Data::new( - vec![ - create_sample_function("func2", FUNC2_GUID), - create_sample_function("func3", FUNC3_GUID), - ], - vec![ - create_sample_computed_type(TYPE1_GUID), - create_sample_computed_type(TYPE3_GUID), - ], - ); - - let third_data = Data::new( - vec![ - create_sample_function("func2", FUNC3_GUID), - create_sample_function("func3", FUNC2_GUID), - create_sample_function("func2", FUNC2_GUID), - ], - vec![ - create_sample_computed_type(TYPE1_GUID), - create_sample_computed_type(TYPE3_GUID), - ], - ); - - let merged_data = Data::merge(vec![first_data, second_data, third_data]); - assert_eq!( - merged_data.functions.len(), - 5, - "{:#?}", - merged_data.functions - ); - assert_eq!(merged_data.types.len(), 3, "{:#?}", merged_data.types); - } - - #[test] - fn test_link_constraints() { - let mut first_data = Data::new( - vec![ - create_sample_function("func1", FUNC1_GUID), - create_sample_function("func2", FUNC2_GUID), - ], - vec![], - ); - - let mut second_data = Data::new(vec![create_sample_function("func3", FUNC3_GUID)], vec![]); - - first_data.functions[0] - .constraints - .call_sites - .insert(create_sample_function_constraint("func2", Some(FUNC2_GUID))); - first_data.functions[1] - .constraints - .call_sites - .insert(create_sample_function_constraint::("func3", None)); - second_data.functions[0] - .constraints - .call_sites - .insert(create_sample_function_constraint::("func2", None)); - - let merged_data = Data::merge(vec![first_data, second_data]); - - assert_eq!(merged_data.functions.len(), 3); - // All function constraints should be resolved. - assert!(!merged_data.functions.iter().any(|f| f - .constraints - .call_sites - .iter() - .any(|fc| fc.guid == None))); - } -} diff --git a/rust/signature/function.rs b/rust/signature/function.rs deleted file mode 100644 index 53db35e..0000000 --- a/rust/signature/function.rs +++ /dev/null @@ -1,202 +0,0 @@ -use crate::fb_sig as fb; -use crate::r#type::Type; -use crate::signature::basic_block::BasicBlockGUID; -use crate::signature::function::constraints::FunctionConstraints; -use crate::symbol::Symbol; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use std::fmt::{Display, Formatter}; -use std::str::FromStr; -use uuid::{uuid, Uuid}; - -pub mod constraints; - -pub const NAMESPACE_FUNCTION: Uuid = uuid!("0192a179-61ac-7cef-88ed-012296e9492f"); - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct FunctionGUID { - pub guid: Uuid, -} - -impl FunctionGUID { - pub fn from_basic_blocks(basic_blocks: &[BasicBlockGUID]) -> Self { - let basic_blocks_bytes = basic_blocks - .iter() - .fold(Vec::new(), |mut bytes: Vec, bb| { - bytes.extend(bb.as_bytes()); - bytes - }); - let guid = Uuid::new_v5(&NAMESPACE_FUNCTION, &basic_blocks_bytes); - FunctionGUID { guid } - } - - pub fn as_bytes(&self) -> &[u8] { - self.guid.as_bytes() - } -} - -impl FromStr for FunctionGUID { - type Err = uuid::Error; - - fn from_str(s: &str) -> Result { - Uuid::parse_str(s).map(Into::into) - } -} - -impl TryFrom<&str> for FunctionGUID { - type Error = uuid::Error; - - fn try_from(value: &str) -> Result { - Self::from_str(value) - } -} - -impl From<&[u8]> for FunctionGUID { - fn from(value: &[u8]) -> Self { - Self { - guid: Uuid::new_v5(&NAMESPACE_FUNCTION, value), - } - } -} - -impl From for FunctionGUID { - fn from(value: Uuid) -> Self { - Self { guid: value } - } -} - -impl Display for FunctionGUID { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - Display::fmt(&self.guid, f) - } -} - -// TODO: bytemuck compat? -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Function { - pub guid: FunctionGUID, - pub symbol: Symbol, - pub ty: Type, - pub constraints: FunctionConstraints, -} - -impl Function { - // TODO: Just have these bare fns? - // TODO: Error checking... - pub fn from_bytes(buf: &[u8]) -> Option { - flatbuffers::root::(buf).ok().map(Into::into) - } - - pub fn to_bytes(&self) -> Vec { - let mut builder = FlatBufferBuilder::new(); - let fb_func = self.create(&mut builder); - builder.finish_minimal(fb_func); - builder.finished_data().to_vec() - } - - // TODO: How do we want to hide these? We need them to be public for fb extensions. - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let symbol = self.symbol.create(builder); - let ty = self.ty.create(builder); - let constraints = self.constraints.create(builder); - let guid = builder.create_string(&self.guid.to_string()); - fb::Function::create( - builder, - &fb::FunctionArgs { - guid: Some(guid), - symbol: Some(symbol), - type_: Some(ty), - constraints: Some(constraints), - }, - ) - } -} - -impl From> for Function { - fn from(value: fb::Function<'_>) -> Self { - let ty = value.type_(); - let guid = value.guid().parse::().unwrap(); - Self { - guid, - symbol: value.symbol().unwrap().into(), - ty: ty.unwrap().into(), - constraints: value.constraints().unwrap().into(), - } - } -} - -#[cfg(test)] -mod tests { - use crate::r#type::class::TypeClass; - use crate::r#type::Type; - use crate::signature::basic_block::BasicBlockGUID; - use crate::signature::function::constraints::FunctionConstraints; - use crate::signature::function::{Function, FunctionGUID}; - use crate::signature::Data; - use crate::symbol::class::SymbolClass; - use crate::symbol::{Symbol, SymbolModifiers}; - use uuid::{uuid, Uuid}; - - const EMPTY_FN_UUID: Uuid = uuid!("db867a3e-416a-5d7f-aa6d-b8ae6be36da2"); - const NONEMPTY_FN_UUID: Uuid = uuid!("7a55be03-76b7-5cb5-bae9-4edcf47795ac"); - - const FIRST_BB_UUID: Uuid = uuid!("036cccf0-8239-5b84-a811-60efc2d7eeb0"); - const SECOND_BB_UUID: Uuid = uuid!("3ed5c023-658d-5511-9710-40814f31af50"); - const THIRD_BB_UUID: Uuid = uuid!("8a076c92-0ba0-540d-b724-7fd5838da9df"); - - fn empty_fn_guid() -> FunctionGUID { - FunctionGUID::from_basic_blocks(&[]) - } - - fn nonempty_fn_guid() -> FunctionGUID { - FunctionGUID::from_basic_blocks(&[ - BasicBlockGUID::from(FIRST_BB_UUID), - BasicBlockGUID::from(SECOND_BB_UUID), - BasicBlockGUID::from(THIRD_BB_UUID), - ]) - } - - #[test] - fn empty_function_guid() { - assert_eq!(FunctionGUID::from(EMPTY_FN_UUID), empty_fn_guid()); - } - - #[test] - fn nonempty_function_guid() { - assert_eq!(FunctionGUID::from(NONEMPTY_FN_UUID), nonempty_fn_guid()); - } - - fn empty_function() -> Function { - Function { - guid: empty_fn_guid(), - symbol: Symbol::new("test", SymbolClass::Data, SymbolModifiers::empty()), - ty: Type::builder() - .name("aghhgh") - .class(TypeClass::Void) - .build(), - constraints: FunctionConstraints::default(), - } - } - - #[test] - fn test_data_from_bytes() { - let signature = empty_function(); - let data = Data { - functions: vec![signature.clone()], - types: vec![], - }; - let buf = data.to_bytes(); - let signatures = Data::from_bytes(&buf); - assert_eq!(Some(data), signatures) - } - - #[test] - fn test_function_from_bytes() { - let signature = empty_function(); - let bytes = signature.to_bytes(); - let from_bytes_sig = Function::from_bytes(&bytes).unwrap(); - assert_eq!(signature, from_bytes_sig) - } -} diff --git a/rust/signature/function/constraints.rs b/rust/signature/function/constraints.rs deleted file mode 100644 index cc8e713..0000000 --- a/rust/signature/function/constraints.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::fb_sig as fb; -use crate::signature::function::FunctionGUID; -use crate::symbol::Symbol; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use std::collections::HashSet; - -#[derive(Clone, Debug, Eq, PartialEq, Hash)] -pub struct FunctionConstraint { - pub guid: Option, - pub symbol: Option, - pub offset: i64, -} - -impl FunctionConstraint { - pub fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let guid = self - .guid - .map(|guid| builder.create_string(&guid.to_string())); - let symbol = self.symbol.as_ref().map(|symbol| symbol.create(builder)); - fb::FunctionConstraint::create( - builder, - &fb::FunctionConstraintArgs { - guid, - symbol, - offset: self.offset, - }, - ) - } -} - -impl From> for FunctionConstraint { - fn from(value: fb::FunctionConstraint<'_>) -> Self { - let guid = value - .guid() - .map(|guid| guid.parse::().unwrap()); - Self { - guid, - symbol: value.symbol().map(Symbol::from), - offset: value.offset(), - } - } -} - -#[derive(Clone, Debug, Eq, PartialEq, Default)] -pub struct FunctionConstraints { - pub adjacent: HashSet, - pub call_sites: HashSet, - pub caller_sites: HashSet, -} - -impl FunctionConstraints { - pub fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let _adjacent: Vec<_> = self - .adjacent - .iter() - .map(|constraint| constraint.create(builder)) - .collect(); - let adjacent = if _adjacent.is_empty() { - None - } else { - Some(builder.create_vector(&_adjacent)) - }; - - let _call_sites: Vec<_> = self - .call_sites - .iter() - .map(|constraint| constraint.create(builder)) - .collect(); - let call_sites = if _call_sites.is_empty() { - None - } else { - Some(builder.create_vector(&_call_sites)) - }; - - let _caller_sites: Vec<_> = self - .caller_sites - .iter() - .map(|constraint| constraint.create(builder)) - .collect(); - let caller_sites = if _caller_sites.is_empty() { - None - } else { - Some(builder.create_vector(&_caller_sites)) - }; - - fb::FunctionConstraints::create( - builder, - &fb::FunctionConstraintsArgs { - adjacent, - call_sites, - caller_sites, - }, - ) - } -} - -impl From> for FunctionConstraints { - fn from(value: fb::FunctionConstraints<'_>) -> Self { - let adjacent: HashSet = value - .adjacent() - .unwrap_or_default() - .iter() - .map(|constraint| constraint.into()) - .collect(); - let call_sites: HashSet = value - .call_sites() - .unwrap_or_default() - .iter() - .map(|constraint| constraint.into()) - .collect(); - let caller_sites: HashSet = value - .caller_sites() - .unwrap_or_default() - .iter() - .map(|constraint| constraint.into()) - .collect(); - - Self { - adjacent, - call_sites, - caller_sites, - } - } -} diff --git a/rust/src/cached_builder.rs b/rust/src/cached_builder.rs new file mode 100644 index 0000000..d93ca7e --- /dev/null +++ b/rust/src/cached_builder.rs @@ -0,0 +1,51 @@ +//! A space-optimized flatbuffer builder. +//! +//! By space-optimized we mean we provide records of previously constructed buffer objects to re-use. +//! Currently, this is done for the Type table. However, this could be done in the future for other things. + +use crate::fb_type as fb; +use crate::r#type::Type; +use flatbuffers::{FlatBufferBuilder, WIPOffset}; +use std::collections::HashMap; +use std::ops::{Deref, DerefMut}; + +/// Caches entries that are common to reduce final size of buffer. +pub struct CachedFlatBufferBuilder<'fbb> { + pub builder: FlatBufferBuilder<'fbb>, + /// A cache for deduplicating offsets for `Type` objects. + pub cached_type_offsets: HashMap>>, +} + +impl<'fbb> CachedFlatBufferBuilder<'fbb> { + pub fn new() -> Self { + Self::new_with_builder(FlatBufferBuilder::new()) + } + + /// Creates a new `CachedBufferBuilder` instance, wrapping the provided FlatBufferBuilder. + pub fn new_with_builder(builder: FlatBufferBuilder<'fbb>) -> Self { + Self { + builder, + cached_type_offsets: HashMap::new(), + } + } +} + +impl Default for CachedFlatBufferBuilder<'_> { + fn default() -> Self { + Self::new() + } +} + +impl<'fbb> Deref for CachedFlatBufferBuilder<'fbb> { + type Target = FlatBufferBuilder<'fbb>; + + fn deref(&self) -> &Self::Target { + &self.builder + } +} + +impl DerefMut for CachedFlatBufferBuilder<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.builder + } +} diff --git a/rust/src/chunk.rs b/rust/src/chunk.rs new file mode 100644 index 0000000..b7cb829 --- /dev/null +++ b/rust/src/chunk.rs @@ -0,0 +1,317 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::gen_flatbuffers::warp as fb; +use crate::r#type::chunk::TypeChunk; +use crate::signature::chunk::SignatureChunk; +use crate::target::Target; +use crate::FlatBufferObject; +pub use fb::ChunkType; +pub use fb::CompressionType; +use flatbuffers::WIPOffset; +use flate2::read::ZlibDecoder; +use flate2::write::ZlibEncoder; +use flate2::Compression; +use itertools::Itertools; +use std::borrow::Cow; +use std::io::{Read, Write}; + +// TODO: Splitting and merging. +pub trait ChunkHandler<'fbb>: Sized + AsRef<[u8]> + Clone +where + Self: 'fbb, +{ + /// The associated version for this chunk type. + const VERSION: u16; + + fn from_owned_data(data: Vec) -> Option { + Self::from_data(Cow::Owned(data)) + } + + fn from_data(data: Cow<'fbb, [u8]>) -> Option; + + /// Split the chunk into smaller chunks based on the number of chunk items. + /// + /// If not implemented for the chunk type, this will return a copy of the passed chunk. + fn split(&self, _count: usize) -> Vec { + vec![self.clone()] + } + + /// Merge multiple chunks into one unified chunk. + fn merge(chunks: &[Self]) -> Option; + + /// Size of the raw chunk data. + fn size(&self) -> u32; +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct ChunkHeader { + pub version: u16, + pub chunk_type: ChunkType, + pub compression_type: CompressionType, + pub size: u32, + pub target: Target, +} + +impl ChunkHeader { + pub fn from_chunk_kind( + kind: &ChunkKind, + compression_type: CompressionType, + target: Target, + ) -> Self { + Self { + version: kind.version(), + chunk_type: kind.chunk_type(), + compression_type, + size: kind.size(), + target, + } + } + + /// Encode the data using the header information. + pub fn encode_data<'a>(&self, data: &'a [u8]) -> Option> { + match self.compression_type { + CompressionType::None => Some(Cow::Borrowed(data)), + CompressionType::Zstd => { + let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default()); + encoder.write_all(data).ok()?; + Some(Cow::Owned(encoder.finish().ok()?)) + } + _ => None, + } + } + + /// Decode the data using the header information. + pub fn decode_data<'a>(&self, data: &'a [u8]) -> Option> { + match self.compression_type { + CompressionType::None => Some(Cow::Borrowed(data)), + CompressionType::Zstd => { + let mut decoder = ZlibDecoder::new(data); + let mut decompressed = Vec::new(); + decoder.read_to_end(&mut decompressed).ok()?; + Some(Cow::Owned(decompressed)) + } + _ => None, + } + } +} + +impl FlatBufferObject for ChunkHeader { + type FbType<'fbb> = fb::ChunkHeader<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let target = self.target.create(builder); + fb::ChunkHeader::create( + builder, + &fb::ChunkHeaderArgs { + version: self.version, + type_: self.chunk_type, + compression_type: self.compression_type, + size: self.size, + target: Some(target), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let header = Self { + version: value.version(), + chunk_type: value.type_(), + compression_type: value.compression_type(), + size: value.size(), + target: value + .target() + .and_then(|t| Target::from_object(&t)) + .unwrap_or_default(), + }; + + Some(header) + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum ChunkKind<'fbb> { + Signature(SignatureChunk<'fbb>), + Type(TypeChunk<'fbb>), +} + +impl ChunkKind<'_> { + pub fn as_bytes(&self) -> &[u8] { + match self { + ChunkKind::Signature(sc) => sc.as_ref(), + ChunkKind::Type(tc) => tc.as_ref(), + } + } + + pub fn version(&self) -> u16 { + match self { + ChunkKind::Signature(_) => SignatureChunk::VERSION, + ChunkKind::Type(_) => TypeChunk::VERSION, + } + } + + pub fn chunk_type(&self) -> ChunkType { + match self { + ChunkKind::Signature(_) => ChunkType::Signatures, + ChunkKind::Type(_) => ChunkType::Types, + } + } + + pub fn size(&self) -> u32 { + match self { + ChunkKind::Signature(sc) => sc.size(), + ChunkKind::Type(tc) => tc.size(), + } + } + + pub fn to_owned(&self) -> Self { + match self { + ChunkKind::Signature(sc) => ChunkKind::Signature(sc.to_owned()), + ChunkKind::Type(tc) => ChunkKind::Type(tc.to_owned()), + } + } + + pub fn split(&self, count: usize) -> Vec { + match self { + ChunkKind::Signature(sc) => sc + .split(count) + .into_iter() + .map(ChunkKind::Signature) + .collect(), + ChunkKind::Type(tc) => tc.split(count).into_iter().map(ChunkKind::Type).collect(), + } + } + + // TODO: This is kinda awful. + pub fn merge(chunks: &[Self]) -> Vec { + let signatures = chunks + .iter() + .filter_map(|c| match c { + ChunkKind::Signature(sc) => Some(sc), + _ => None, + }) + .cloned() + .collect::>(); + + let types = chunks + .iter() + .filter_map(|c| match c { + ChunkKind::Type(tc) => Some(tc), + _ => None, + }) + .cloned() + .collect::>(); + + let mut merged = Vec::new(); + if !signatures.is_empty() { + if let Some(merged_signatures) = SignatureChunk::merge(&signatures) { + merged.push(ChunkKind::Signature(merged_signatures)); + } + } + if !types.is_empty() { + if let Some(merged_types) = TypeChunk::merge(&types) { + merged.push(ChunkKind::Type(merged_types)); + } + } + merged + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct Chunk<'fbb> { + pub header: ChunkHeader, + pub kind: ChunkKind<'fbb>, +} + +impl<'fbb> Chunk<'fbb> { + pub fn new(kind: ChunkKind<'fbb>, compression_type: CompressionType) -> Chunk<'fbb> { + Self::new_with_target(kind, compression_type, Target::default()) + } + + pub fn new_with_target( + kind: ChunkKind<'fbb>, + compression_type: CompressionType, + target: Target, + ) -> Chunk<'fbb> { + // We can pull the header from the chunk kind, as most of the data is derived. + let header = ChunkHeader::from_chunk_kind(&kind, compression_type, target); + Self::new_with_header(header, kind) + } + + pub fn new_with_header(header: ChunkHeader, kind: ChunkKind<'fbb>) -> Chunk<'fbb> { + Self { header, kind } + } + + // TODO: Maybe some unnecessary clones here. + pub fn merge(chunks: &[Self], compression_type: CompressionType) -> Vec { + // Chunks with the same target are going to be grouped, returning a list of the merged chunks. + chunks + .iter() + .into_group_map_by(|chunk| chunk.header.target.clone()) + .into_iter() + .map(|(target, chunks)| { + ( + target, + chunks + .into_iter() + .map(|chunk| chunk.kind.clone()) + .collect::>(), + ) + }) + .flat_map(|(target, chunk_kinds)| { + ChunkKind::merge(&chunk_kinds) + .into_iter() + .map(move |merged_kind| { + Chunk::new_with_target(merged_kind, compression_type, target.clone()) + }) + }) + .collect() + } + + pub(crate) fn create_object( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> Option>> { + let header = self.header.create(builder); + let encoded_data = self.header.encode_data(self.kind.as_bytes())?; + let data = builder.create_vector(&encoded_data); + + Some(fb::Chunk::create( + builder, + &fb::ChunkArgs { + header: Some(header), + data: Some(data), + }, + )) + } + + pub(crate) fn from_object(value: &fb::Chunk<'fbb>) -> Option> { + let header = ChunkHeader::from_object(&value.header())?; + let decoded_data = header.decode_data(value.data()?.bytes())?; + let kind = match header.chunk_type { + ChunkType::Signatures => ChunkKind::Signature(SignatureChunk::from_data(decoded_data)?), + ChunkType::Types => ChunkKind::Type(TypeChunk::from_data(decoded_data)?), + // The chunk type is unhandled. + _ => return None, + }; + + Some(Self { header, kind }) + } + + // TODO: This duplicate code is awful. + pub(crate) fn from_owned_object(value: &fb::Chunk) -> Option> { + let header = ChunkHeader::from_object(&value.header())?; + let decoded_data = header.decode_data(value.data()?.bytes())?.to_vec(); + let kind = match header.chunk_type { + ChunkType::Signatures => { + ChunkKind::Signature(SignatureChunk::from_owned_data(decoded_data)?) + } + ChunkType::Types => ChunkKind::Type(TypeChunk::from_owned_data(decoded_data)?), + // The chunk type is unhandled. + _ => return None, + }; + + Some(Self { header, kind }) + } +} diff --git a/rust/gen_flatbuffers/mod.rs b/rust/src/gen_flatbuffers/mod.rs similarity index 65% rename from rust/gen_flatbuffers/mod.rs rename to rust/src/gen_flatbuffers/mod.rs index 854ab32..02ac80d 100644 --- a/rust/gen_flatbuffers/mod.rs +++ b/rust/src/gen_flatbuffers/mod.rs @@ -2,16 +2,24 @@ // @generated pub mod sig_bin { use super::*; + mod basic_block_guid_generated; + pub use self::basic_block_guid_generated::*; + mod constraint_guid_generated; + pub use self::constraint_guid_generated::*; + mod function_guid_generated; + pub use self::function_guid_generated::*; mod basic_block_generated; pub use self::basic_block_generated::*; - mod function_constraint_generated; - pub use self::function_constraint_generated::*; - mod function_constraints_generated; - pub use self::function_constraints_generated::*; + mod constraint_generated; + pub use self::constraint_generated::*; + mod function_comment_generated; + pub use self::function_comment_generated::*; + mod function_variable_generated; + pub use self::function_variable_generated::*; mod function_generated; pub use self::function_generated::*; - mod data_generated; - pub use self::data_generated::*; + mod signature_chunk_generated; + pub use self::signature_chunk_generated::*; } // sig_bin pub mod symbol_bin { use super::*; @@ -19,19 +27,20 @@ pub mod symbol_bin { pub use self::symbol_class_generated::*; mod symbol_modifiers_generated; pub use self::symbol_modifiers_generated::*; - mod function_symbol_class_generated; - pub use self::function_symbol_class_generated::*; - mod data_symbol_class_generated; - pub use self::data_symbol_class_generated::*; mod symbol_generated; pub use self::symbol_generated::*; } // symbol_bin +pub mod target_bin { + use super::*; + mod target_generated; + pub use self::target_generated::*; +} // target_bin pub mod type_bin { use super::*; - mod type_modifier_class_generated; - pub use self::type_modifier_class_generated::*; - mod type_alignment_generated; - pub use self::type_alignment_generated::*; + mod type_modifiers_generated; + pub use self::type_modifiers_generated::*; + mod metadata_value_type_generated; + pub use self::metadata_value_type_generated::*; mod pointer_addressing_generated; pub use self::pointer_addressing_generated::*; mod array_modifiers_generated; @@ -42,6 +51,8 @@ pub mod type_bin { pub use self::location_class_generated::*; mod type_class_generated; pub use self::type_class_generated::*; + mod type_guid_generated; + pub use self::type_guid_generated::*; mod unsigned_bit_offset_generated; pub use self::unsigned_bit_offset_generated::*; mod bit_offset_generated; @@ -52,20 +63,8 @@ pub mod type_bin { pub use self::bit_size_generated::*; mod bit_width_generated; pub use self::bit_width_generated::*; - mod constant_modifier_class_generated; - pub use self::constant_modifier_class_generated::*; - mod volatile_modifier_class_generated; - pub use self::volatile_modifier_class_generated::*; - mod descriptor_modifier_class_generated; - pub use self::descriptor_modifier_class_generated::*; - mod metadata_modifier_class_generated; - pub use self::metadata_modifier_class_generated::*; - mod type_modifier_generated; - pub use self::type_modifier_generated::*; - mod access_alignment_generated; - pub use self::access_alignment_generated::*; - mod fixed_alignment_generated; - pub use self::fixed_alignment_generated::*; + mod type_metadata_generated; + pub use self::type_metadata_generated::*; mod void_generated; pub use self::void_generated::*; mod boolean_generated; @@ -98,8 +97,6 @@ pub mod type_bin { pub use self::register_location_generated::*; mod stack_location_generated; pub use self::stack_location_generated::*; - mod function_member_location_generated; - pub use self::function_member_location_generated::*; mod function_member_generated; pub use self::function_member_generated::*; mod function_generated; @@ -110,6 +107,21 @@ pub mod type_bin { pub use self::type_generated::*; mod computed_type_generated; pub use self::computed_type_generated::*; - mod data_generated; - pub use self::data_generated::*; + mod type_chunk_generated; + pub use self::type_chunk_generated::*; } // type_bin +pub mod warp { + use super::*; + mod chunk_type_generated; + pub use self::chunk_type_generated::*; + mod compression_type_generated; + pub use self::compression_type_generated::*; + mod chunk_header_generated; + pub use self::chunk_header_generated::*; + mod chunk_generated; + pub use self::chunk_generated::*; + mod file_header_generated; + pub use self::file_header_generated::*; + mod file_generated; + pub use self::file_generated::*; +} // warp diff --git a/rust/gen_flatbuffers/sig_bin/basic_block_generated.rs b/rust/src/gen_flatbuffers/sig_bin/basic_block_generated.rs similarity index 86% rename from rust/gen_flatbuffers/sig_bin/basic_block_generated.rs rename to rust/src/gen_flatbuffers/sig_bin/basic_block_generated.rs index c97fa01..e28d23a 100644 --- a/rust/gen_flatbuffers/sig_bin/basic_block_generated.rs +++ b/rust/src/gen_flatbuffers/sig_bin/basic_block_generated.rs @@ -43,11 +43,11 @@ impl<'a> BasicBlock<'a> { #[inline] - pub fn guid(&self) -> &'a str { + pub fn guid(&self) -> &'a BasicBlockGUID { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>(BasicBlock::VT_GUID, None).unwrap()} + unsafe { self._tab.get::(BasicBlock::VT_GUID, None).unwrap()} } } @@ -58,13 +58,13 @@ impl flatbuffers::Verifiable for BasicBlock<'_> { ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::>("guid", Self::VT_GUID, true)? + .visit_field::("guid", Self::VT_GUID, true)? .finish(); Ok(()) } } pub struct BasicBlockArgs<'a> { - pub guid: Option>, + pub guid: Option<&'a BasicBlockGUID>, } impl<'a> Default for BasicBlockArgs<'a> { #[inline] @@ -81,8 +81,8 @@ pub struct BasicBlockBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { } impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> BasicBlockBuilder<'a, 'b, A> { #[inline] - pub fn add_guid(&mut self, guid: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(BasicBlock::VT_GUID, guid); + pub fn add_guid(&mut self, guid: &BasicBlockGUID) { + self.fbb_.push_slot_always::<&BasicBlockGUID>(BasicBlock::VT_GUID, guid); } #[inline] pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> BasicBlockBuilder<'a, 'b, A> { diff --git a/rust/src/gen_flatbuffers/sig_bin/basic_block_guid_generated.rs b/rust/src/gen_flatbuffers/sig_bin/basic_block_guid_generated.rs new file mode 100644 index 0000000..3fea618 --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/basic_block_guid_generated.rs @@ -0,0 +1,92 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +// struct BasicBlockGUID, aligned to 1 +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq)] +pub struct BasicBlockGUID(pub [u8; 16]); +impl Default for BasicBlockGUID { + fn default() -> Self { + Self([0; 16]) + } +} +impl core::fmt::Debug for BasicBlockGUID { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("BasicBlockGUID") + .field("value", &self.value()) + .finish() + } +} + +impl flatbuffers::SimpleToVerifyInSlice for BasicBlockGUID {} +impl<'a> flatbuffers::Follow<'a> for BasicBlockGUID { + type Inner = &'a BasicBlockGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + <&'a BasicBlockGUID>::follow(buf, loc) + } +} +impl<'a> flatbuffers::Follow<'a> for &'a BasicBlockGUID { + type Inner = &'a BasicBlockGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + flatbuffers::follow_cast_ref::(buf, loc) + } +} +impl<'b> flatbuffers::Push for BasicBlockGUID { + type Output = BasicBlockGUID; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + let src = ::core::slice::from_raw_parts(self as *const BasicBlockGUID as *const u8, ::size()); + dst.copy_from_slice(src); + } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(1) + } +} + +impl<'a> flatbuffers::Verifiable for BasicBlockGUID { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.in_buffer::(pos) + } +} + +impl<'a> BasicBlockGUID { + #[allow(clippy::too_many_arguments)] + pub fn new( + value: &[u8; 16], + ) -> Self { + let mut s = Self([0; 16]); + s.set_value(value); + s + } + + pub fn value(&'a self) -> flatbuffers::Array<'a, u8, 16> { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::Array::follow(&self.0, 0) } + } + + pub fn set_value(&mut self, items: &[u8; 16]) { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::emplace_scalar_array(&mut self.0, 0, items) }; + } + +} + diff --git a/rust/src/gen_flatbuffers/sig_bin/constraint_generated.rs b/rust/src/gen_flatbuffers/sig_bin/constraint_generated.rs new file mode 100644 index 0000000..ce8bd58 --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/constraint_generated.rs @@ -0,0 +1,126 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum ConstraintOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct Constraint<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Constraint<'a> { + type Inner = Constraint<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> Constraint<'a> { + pub const VT_GUID: flatbuffers::VOffsetT = 4; + pub const VT_OFFSET: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Constraint { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args ConstraintArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = ConstraintBuilder::new(_fbb); + builder.add_offset(args.offset); + if let Some(x) = args.guid { builder.add_guid(x); } + builder.finish() + } + + + #[inline] + pub fn guid(&self) -> &'a ConstraintGUID { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Constraint::VT_GUID, None).unwrap()} + } + #[inline] + pub fn offset(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Constraint::VT_OFFSET, Some(0)).unwrap()} + } +} + +impl flatbuffers::Verifiable for Constraint<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("guid", Self::VT_GUID, true)? + .visit_field::("offset", Self::VT_OFFSET, false)? + .finish(); + Ok(()) + } +} +pub struct ConstraintArgs<'a> { + pub guid: Option<&'a ConstraintGUID>, + pub offset: i64, +} +impl<'a> Default for ConstraintArgs<'a> { + #[inline] + fn default() -> Self { + ConstraintArgs { + guid: None, // required field + offset: 0, + } + } +} + +pub struct ConstraintBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ConstraintBuilder<'a, 'b, A> { + #[inline] + pub fn add_guid(&mut self, guid: &ConstraintGUID) { + self.fbb_.push_slot_always::<&ConstraintGUID>(Constraint::VT_GUID, guid); + } + #[inline] + pub fn add_offset(&mut self, offset: i64) { + self.fbb_.push_slot::(Constraint::VT_OFFSET, offset, 0); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ConstraintBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + ConstraintBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, Constraint::VT_GUID,"guid"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for Constraint<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("Constraint"); + ds.field("guid", &self.guid()); + ds.field("offset", &self.offset()); + ds.finish() + } +} diff --git a/rust/src/gen_flatbuffers/sig_bin/constraint_guid_generated.rs b/rust/src/gen_flatbuffers/sig_bin/constraint_guid_generated.rs new file mode 100644 index 0000000..ec2369f --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/constraint_guid_generated.rs @@ -0,0 +1,92 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +// struct ConstraintGUID, aligned to 1 +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq)] +pub struct ConstraintGUID(pub [u8; 16]); +impl Default for ConstraintGUID { + fn default() -> Self { + Self([0; 16]) + } +} +impl core::fmt::Debug for ConstraintGUID { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("ConstraintGUID") + .field("value", &self.value()) + .finish() + } +} + +impl flatbuffers::SimpleToVerifyInSlice for ConstraintGUID {} +impl<'a> flatbuffers::Follow<'a> for ConstraintGUID { + type Inner = &'a ConstraintGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + <&'a ConstraintGUID>::follow(buf, loc) + } +} +impl<'a> flatbuffers::Follow<'a> for &'a ConstraintGUID { + type Inner = &'a ConstraintGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + flatbuffers::follow_cast_ref::(buf, loc) + } +} +impl<'b> flatbuffers::Push for ConstraintGUID { + type Output = ConstraintGUID; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + let src = ::core::slice::from_raw_parts(self as *const ConstraintGUID as *const u8, ::size()); + dst.copy_from_slice(src); + } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(1) + } +} + +impl<'a> flatbuffers::Verifiable for ConstraintGUID { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.in_buffer::(pos) + } +} + +impl<'a> ConstraintGUID { + #[allow(clippy::too_many_arguments)] + pub fn new( + value: &[u8; 16], + ) -> Self { + let mut s = Self([0; 16]); + s.set_value(value); + s + } + + pub fn value(&'a self) -> flatbuffers::Array<'a, u8, 16> { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::Array::follow(&self.0, 0) } + } + + pub fn set_value(&mut self, items: &[u8; 16]) { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::emplace_scalar_array(&mut self.0, 0, items) }; + } + +} + diff --git a/rust/src/gen_flatbuffers/sig_bin/function_comment_generated.rs b/rust/src/gen_flatbuffers/sig_bin/function_comment_generated.rs new file mode 100644 index 0000000..3411490 --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/function_comment_generated.rs @@ -0,0 +1,126 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum FunctionCommentOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct FunctionComment<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for FunctionComment<'a> { + type Inner = FunctionComment<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> FunctionComment<'a> { + pub const VT_OFFSET: flatbuffers::VOffsetT = 4; + pub const VT_TEXT: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + FunctionComment { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args FunctionCommentArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = FunctionCommentBuilder::new(_fbb); + builder.add_offset(args.offset); + if let Some(x) = args.text { builder.add_text(x); } + builder.finish() + } + + + #[inline] + pub fn offset(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(FunctionComment::VT_OFFSET, Some(0)).unwrap()} + } + #[inline] + pub fn text(&self) -> &'a str { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(FunctionComment::VT_TEXT, None).unwrap()} + } +} + +impl flatbuffers::Verifiable for FunctionComment<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("offset", Self::VT_OFFSET, false)? + .visit_field::>("text", Self::VT_TEXT, true)? + .finish(); + Ok(()) + } +} +pub struct FunctionCommentArgs<'a> { + pub offset: i64, + pub text: Option>, +} +impl<'a> Default for FunctionCommentArgs<'a> { + #[inline] + fn default() -> Self { + FunctionCommentArgs { + offset: 0, + text: None, // required field + } + } +} + +pub struct FunctionCommentBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionCommentBuilder<'a, 'b, A> { + #[inline] + pub fn add_offset(&mut self, offset: i64) { + self.fbb_.push_slot::(FunctionComment::VT_OFFSET, offset, 0); + } + #[inline] + pub fn add_text(&mut self, text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(FunctionComment::VT_TEXT, text); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionCommentBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + FunctionCommentBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, FunctionComment::VT_TEXT,"text"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for FunctionComment<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("FunctionComment"); + ds.field("offset", &self.offset()); + ds.field("text", &self.text()); + ds.finish() + } +} diff --git a/rust/gen_flatbuffers/sig_bin/function_generated.rs b/rust/src/gen_flatbuffers/sig_bin/function_generated.rs similarity index 60% rename from rust/gen_flatbuffers/sig_bin/function_generated.rs rename to rust/src/gen_flatbuffers/sig_bin/function_generated.rs index 02c83cd..3dbed29 100644 --- a/rust/gen_flatbuffers/sig_bin/function_generated.rs +++ b/rust/src/gen_flatbuffers/sig_bin/function_generated.rs @@ -29,6 +29,8 @@ impl<'a> Function<'a> { pub const VT_SYMBOL: flatbuffers::VOffsetT = 6; pub const VT_TYPE_: flatbuffers::VOffsetT = 8; pub const VT_CONSTRAINTS: flatbuffers::VOffsetT = 10; + pub const VT_COMMENTS: flatbuffers::VOffsetT = 12; + pub const VT_VARIABLES: flatbuffers::VOffsetT = 14; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { @@ -40,6 +42,8 @@ impl<'a> Function<'a> { args: &'args FunctionArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = FunctionBuilder::new(_fbb); + if let Some(x) = args.variables { builder.add_variables(x); } + if let Some(x) = args.comments { builder.add_comments(x); } if let Some(x) = args.constraints { builder.add_constraints(x); } if let Some(x) = args.type_ { builder.add_type_(x); } if let Some(x) = args.symbol { builder.add_symbol(x); } @@ -49,11 +53,11 @@ impl<'a> Function<'a> { #[inline] - pub fn guid(&self) -> &'a str { + pub fn guid(&self) -> &'a FunctionGUID { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>(Function::VT_GUID, None).unwrap()} + unsafe { self._tab.get::(Function::VT_GUID, None).unwrap()} } #[inline] pub fn symbol(&self) -> Option> { @@ -70,11 +74,25 @@ impl<'a> Function<'a> { unsafe { self._tab.get::>(Function::VT_TYPE_, None)} } #[inline] - pub fn constraints(&self) -> Option> { + pub fn constraints(&self) -> Option>>> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>(Function::VT_CONSTRAINTS, None)} + unsafe { self._tab.get::>>>(Function::VT_CONSTRAINTS, None)} + } + #[inline] + pub fn comments(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(Function::VT_COMMENTS, None)} + } + #[inline] + pub fn variables(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(Function::VT_VARIABLES, None)} } } @@ -85,19 +103,23 @@ impl flatbuffers::Verifiable for Function<'_> { ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::>("guid", Self::VT_GUID, true)? + .visit_field::("guid", Self::VT_GUID, true)? .visit_field::>("symbol", Self::VT_SYMBOL, false)? .visit_field::>("type_", Self::VT_TYPE_, false)? - .visit_field::>("constraints", Self::VT_CONSTRAINTS, false)? + .visit_field::>>>("constraints", Self::VT_CONSTRAINTS, false)? + .visit_field::>>>("comments", Self::VT_COMMENTS, false)? + .visit_field::>>>("variables", Self::VT_VARIABLES, false)? .finish(); Ok(()) } } pub struct FunctionArgs<'a> { - pub guid: Option>, + pub guid: Option<&'a FunctionGUID>, pub symbol: Option>>, pub type_: Option>>, - pub constraints: Option>>, + pub constraints: Option>>>>, + pub comments: Option>>>>, + pub variables: Option>>>>, } impl<'a> Default for FunctionArgs<'a> { #[inline] @@ -107,6 +129,8 @@ impl<'a> Default for FunctionArgs<'a> { symbol: None, type_: None, constraints: None, + comments: None, + variables: None, } } } @@ -117,8 +141,8 @@ pub struct FunctionBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { } impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionBuilder<'a, 'b, A> { #[inline] - pub fn add_guid(&mut self, guid: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(Function::VT_GUID, guid); + pub fn add_guid(&mut self, guid: &FunctionGUID) { + self.fbb_.push_slot_always::<&FunctionGUID>(Function::VT_GUID, guid); } #[inline] pub fn add_symbol(&mut self, symbol: flatbuffers::WIPOffset>) { @@ -129,8 +153,16 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionBuilder<'a, 'b, A> { self.fbb_.push_slot_always::>(Function::VT_TYPE_, type_); } #[inline] - pub fn add_constraints(&mut self, constraints: flatbuffers::WIPOffset>) { - self.fbb_.push_slot_always::>(Function::VT_CONSTRAINTS, constraints); + pub fn add_constraints(&mut self, constraints: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Function::VT_CONSTRAINTS, constraints); + } + #[inline] + pub fn add_comments(&mut self, comments: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Function::VT_COMMENTS, comments); + } + #[inline] + pub fn add_variables(&mut self, variables: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Function::VT_VARIABLES, variables); } #[inline] pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionBuilder<'a, 'b, A> { @@ -155,6 +187,8 @@ impl core::fmt::Debug for Function<'_> { ds.field("symbol", &self.symbol()); ds.field("type_", &self.type_()); ds.field("constraints", &self.constraints()); + ds.field("comments", &self.comments()); + ds.field("variables", &self.variables()); ds.finish() } } diff --git a/rust/src/gen_flatbuffers/sig_bin/function_guid_generated.rs b/rust/src/gen_flatbuffers/sig_bin/function_guid_generated.rs new file mode 100644 index 0000000..a8d098e --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/function_guid_generated.rs @@ -0,0 +1,92 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +// struct FunctionGUID, aligned to 1 +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq)] +pub struct FunctionGUID(pub [u8; 16]); +impl Default for FunctionGUID { + fn default() -> Self { + Self([0; 16]) + } +} +impl core::fmt::Debug for FunctionGUID { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("FunctionGUID") + .field("value", &self.value()) + .finish() + } +} + +impl flatbuffers::SimpleToVerifyInSlice for FunctionGUID {} +impl<'a> flatbuffers::Follow<'a> for FunctionGUID { + type Inner = &'a FunctionGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + <&'a FunctionGUID>::follow(buf, loc) + } +} +impl<'a> flatbuffers::Follow<'a> for &'a FunctionGUID { + type Inner = &'a FunctionGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + flatbuffers::follow_cast_ref::(buf, loc) + } +} +impl<'b> flatbuffers::Push for FunctionGUID { + type Output = FunctionGUID; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + let src = ::core::slice::from_raw_parts(self as *const FunctionGUID as *const u8, ::size()); + dst.copy_from_slice(src); + } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(1) + } +} + +impl<'a> flatbuffers::Verifiable for FunctionGUID { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.in_buffer::(pos) + } +} + +impl<'a> FunctionGUID { + #[allow(clippy::too_many_arguments)] + pub fn new( + value: &[u8; 16], + ) -> Self { + let mut s = Self([0; 16]); + s.set_value(value); + s + } + + pub fn value(&'a self) -> flatbuffers::Array<'a, u8, 16> { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::Array::follow(&self.0, 0) } + } + + pub fn set_value(&mut self, items: &[u8; 16]) { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::emplace_scalar_array(&mut self.0, 0, items) }; + } + +} + diff --git a/rust/src/gen_flatbuffers/sig_bin/function_variable_generated.rs b/rust/src/gen_flatbuffers/sig_bin/function_variable_generated.rs new file mode 100644 index 0000000..a2a3279 --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/function_variable_generated.rs @@ -0,0 +1,229 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum FunctionVariableOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct FunctionVariable<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for FunctionVariable<'a> { + type Inner = FunctionVariable<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> FunctionVariable<'a> { + pub const VT_OFFSET: flatbuffers::VOffsetT = 4; + pub const VT_NAME: flatbuffers::VOffsetT = 6; + pub const VT_LOCATION_TYPE: flatbuffers::VOffsetT = 8; + pub const VT_LOCATION: flatbuffers::VOffsetT = 10; + pub const VT_TYPE_: flatbuffers::VOffsetT = 12; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + FunctionVariable { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args FunctionVariableArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = FunctionVariableBuilder::new(_fbb); + builder.add_offset(args.offset); + if let Some(x) = args.type_ { builder.add_type_(x); } + if let Some(x) = args.location { builder.add_location(x); } + if let Some(x) = args.name { builder.add_name(x); } + builder.add_location_type(args.location_type); + builder.finish() + } + + + #[inline] + pub fn offset(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(FunctionVariable::VT_OFFSET, Some(0)).unwrap()} + } + #[inline] + pub fn name(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(FunctionVariable::VT_NAME, None)} + } + #[inline] + pub fn location_type(&self) -> super::type_bin::LocationClass { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(FunctionVariable::VT_LOCATION_TYPE, Some(super::type_bin::LocationClass::NONE)).unwrap()} + } + #[inline] + pub fn location(&self) -> flatbuffers::Table<'a> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(FunctionVariable::VT_LOCATION, None).unwrap()} + } + #[inline] + pub fn type_(&self) -> Option> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(FunctionVariable::VT_TYPE_, None)} + } + #[inline] + #[allow(non_snake_case)] + pub fn location_as_register_location(&self) -> Option> { + if self.location_type() == super::type_bin::LocationClass::RegisterLocation { + let u = self.location(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { super::type_bin::RegisterLocation::init_from_table(u) }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn location_as_stack_location(&self) -> Option> { + if self.location_type() == super::type_bin::LocationClass::StackLocation { + let u = self.location(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { super::type_bin::StackLocation::init_from_table(u) }) + } else { + None + } + } + +} + +impl flatbuffers::Verifiable for FunctionVariable<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("offset", Self::VT_OFFSET, false)? + .visit_field::>("name", Self::VT_NAME, false)? + .visit_union::("location_type", Self::VT_LOCATION_TYPE, "location", Self::VT_LOCATION, true, |key, v, pos| { + match key { + super::type_bin::LocationClass::RegisterLocation => v.verify_union_variant::>("super::type_bin::LocationClass::RegisterLocation", pos), + super::type_bin::LocationClass::StackLocation => v.verify_union_variant::>("super::type_bin::LocationClass::StackLocation", pos), + _ => Ok(()), + } + })? + .visit_field::>("type_", Self::VT_TYPE_, false)? + .finish(); + Ok(()) + } +} +pub struct FunctionVariableArgs<'a> { + pub offset: i64, + pub name: Option>, + pub location_type: super::type_bin::LocationClass, + pub location: Option>, + pub type_: Option>>, +} +impl<'a> Default for FunctionVariableArgs<'a> { + #[inline] + fn default() -> Self { + FunctionVariableArgs { + offset: 0, + name: None, + location_type: super::type_bin::LocationClass::NONE, + location: None, // required field + type_: None, + } + } +} + +pub struct FunctionVariableBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionVariableBuilder<'a, 'b, A> { + #[inline] + pub fn add_offset(&mut self, offset: i64) { + self.fbb_.push_slot::(FunctionVariable::VT_OFFSET, offset, 0); + } + #[inline] + pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(FunctionVariable::VT_NAME, name); + } + #[inline] + pub fn add_location_type(&mut self, location_type: super::type_bin::LocationClass) { + self.fbb_.push_slot::(FunctionVariable::VT_LOCATION_TYPE, location_type, super::type_bin::LocationClass::NONE); + } + #[inline] + pub fn add_location(&mut self, location: flatbuffers::WIPOffset) { + self.fbb_.push_slot_always::>(FunctionVariable::VT_LOCATION, location); + } + #[inline] + pub fn add_type_(&mut self, type_: flatbuffers::WIPOffset>) { + self.fbb_.push_slot_always::>(FunctionVariable::VT_TYPE_, type_); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionVariableBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + FunctionVariableBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, FunctionVariable::VT_LOCATION,"location"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for FunctionVariable<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("FunctionVariable"); + ds.field("offset", &self.offset()); + ds.field("name", &self.name()); + ds.field("location_type", &self.location_type()); + match self.location_type() { + super::type_bin::LocationClass::RegisterLocation => { + if let Some(x) = self.location_as_register_location() { + ds.field("location", &x) + } else { + ds.field("location", &"InvalidFlatbuffer: Union discriminant does not match value.") + } + }, + super::type_bin::LocationClass::StackLocation => { + if let Some(x) = self.location_as_stack_location() { + ds.field("location", &x) + } else { + ds.field("location", &"InvalidFlatbuffer: Union discriminant does not match value.") + } + }, + _ => { + let x: Option<()> = None; + ds.field("location", &x) + }, + }; + ds.field("type_", &self.type_()); + ds.finish() + } +} diff --git a/rust/src/gen_flatbuffers/sig_bin/signature_chunk_generated.rs b/rust/src/gen_flatbuffers/sig_bin/signature_chunk_generated.rs new file mode 100644 index 0000000..edee0d0 --- /dev/null +++ b/rust/src/gen_flatbuffers/sig_bin/signature_chunk_generated.rs @@ -0,0 +1,180 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum SignatureChunkOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct SignatureChunk<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for SignatureChunk<'a> { + type Inner = SignatureChunk<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> SignatureChunk<'a> { + pub const VT_FUNCTIONS: flatbuffers::VOffsetT = 4; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + SignatureChunk { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args SignatureChunkArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = SignatureChunkBuilder::new(_fbb); + if let Some(x) = args.functions { builder.add_functions(x); } + builder.finish() + } + + + #[inline] + pub fn functions(&self) -> flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(SignatureChunk::VT_FUNCTIONS, None).unwrap()} + } +} + +impl flatbuffers::Verifiable for SignatureChunk<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>>>("functions", Self::VT_FUNCTIONS, true)? + .finish(); + Ok(()) + } +} +pub struct SignatureChunkArgs<'a> { + pub functions: Option>>>>, +} +impl<'a> Default for SignatureChunkArgs<'a> { + #[inline] + fn default() -> Self { + SignatureChunkArgs { + functions: None, // required field + } + } +} + +pub struct SignatureChunkBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SignatureChunkBuilder<'a, 'b, A> { + #[inline] + pub fn add_functions(&mut self, functions: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(SignatureChunk::VT_FUNCTIONS, functions); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> SignatureChunkBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + SignatureChunkBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, SignatureChunk::VT_FUNCTIONS,"functions"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for SignatureChunk<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("SignatureChunk"); + ds.field("functions", &self.functions()); + ds.finish() + } +} +#[inline] +/// Verifies that a buffer of bytes contains a `SignatureChunk` +/// and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_signature_chunk_unchecked`. +pub fn root_as_signature_chunk(buf: &[u8]) -> Result { + flatbuffers::root::(buf) +} +#[inline] +/// Verifies that a buffer of bytes contains a size prefixed +/// `SignatureChunk` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `size_prefixed_root_as_signature_chunk_unchecked`. +pub fn size_prefixed_root_as_signature_chunk(buf: &[u8]) -> Result { + flatbuffers::size_prefixed_root::(buf) +} +#[inline] +/// Verifies, with the given options, that a buffer of bytes +/// contains a `SignatureChunk` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_signature_chunk_unchecked`. +pub fn root_as_signature_chunk_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::root_with_opts::>(opts, buf) +} +#[inline] +/// Verifies, with the given verifier options, that a buffer of +/// bytes contains a size prefixed `SignatureChunk` and returns +/// it. Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_signature_chunk_unchecked`. +pub fn size_prefixed_root_as_signature_chunk_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::size_prefixed_root_with_opts::>(opts, buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a SignatureChunk and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid `SignatureChunk`. +pub unsafe fn root_as_signature_chunk_unchecked(buf: &[u8]) -> SignatureChunk { + flatbuffers::root_unchecked::(buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a size prefixed SignatureChunk and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid size prefixed `SignatureChunk`. +pub unsafe fn size_prefixed_root_as_signature_chunk_unchecked(buf: &[u8]) -> SignatureChunk { + flatbuffers::size_prefixed_root_unchecked::(buf) +} +#[inline] +pub fn finish_signature_chunk_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + root: flatbuffers::WIPOffset>) { + fbb.finish(root, None); +} + +#[inline] +pub fn finish_size_prefixed_signature_chunk_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { + fbb.finish_size_prefixed(root, None); +} diff --git a/rust/gen_flatbuffers/symbol_bin/symbol_class_generated.rs b/rust/src/gen_flatbuffers/symbol_bin/symbol_class_generated.rs similarity index 84% rename from rust/gen_flatbuffers/symbol_bin/symbol_class_generated.rs rename to rust/src/gen_flatbuffers/symbol_bin/symbol_class_generated.rs index ee49be1..6340c49 100644 --- a/rust/gen_flatbuffers/symbol_bin/symbol_class_generated.rs +++ b/rust/src/gen_flatbuffers/symbol_bin/symbol_class_generated.rs @@ -16,9 +16,9 @@ pub const ENUM_MAX_SYMBOL_CLASS: u8 = 2; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] #[allow(non_camel_case_types)] pub const ENUM_VALUES_SYMBOL_CLASS: [SymbolClass; 3] = [ - SymbolClass::NONE, - SymbolClass::FunctionSymbolClass, - SymbolClass::DataSymbolClass, + SymbolClass::Function, + SymbolClass::Data, + SymbolClass::Bare, ]; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] @@ -26,23 +26,23 @@ pub const ENUM_VALUES_SYMBOL_CLASS: [SymbolClass; 3] = [ pub struct SymbolClass(pub u8); #[allow(non_upper_case_globals)] impl SymbolClass { - pub const NONE: Self = Self(0); - pub const FunctionSymbolClass: Self = Self(1); - pub const DataSymbolClass: Self = Self(2); + pub const Function: Self = Self(0); + pub const Data: Self = Self(1); + pub const Bare: Self = Self(2); pub const ENUM_MIN: u8 = 0; pub const ENUM_MAX: u8 = 2; pub const ENUM_VALUES: &'static [Self] = &[ - Self::NONE, - Self::FunctionSymbolClass, - Self::DataSymbolClass, + Self::Function, + Self::Data, + Self::Bare, ]; /// Returns the variant's name or "" if unknown. pub fn variant_name(self) -> Option<&'static str> { match self { - Self::NONE => Some("NONE"), - Self::FunctionSymbolClass => Some("FunctionSymbolClass"), - Self::DataSymbolClass => Some("DataSymbolClass"), + Self::Function => Some("Function"), + Self::Data => Some("Data"), + Self::Bare => Some("Bare"), _ => None, } } @@ -98,5 +98,3 @@ impl<'a> flatbuffers::Verifiable for SymbolClass { } impl flatbuffers::SimpleToVerifyInSlice for SymbolClass {} -pub struct SymbolClassUnionTableOffset {} - diff --git a/rust/gen_flatbuffers/symbol_bin/symbol_generated.rs b/rust/src/gen_flatbuffers/symbol_bin/symbol_generated.rs similarity index 54% rename from rust/gen_flatbuffers/symbol_bin/symbol_generated.rs rename to rust/src/gen_flatbuffers/symbol_bin/symbol_generated.rs index 7845a1d..d198ea9 100644 --- a/rust/gen_flatbuffers/symbol_bin/symbol_generated.rs +++ b/rust/src/gen_flatbuffers/symbol_bin/symbol_generated.rs @@ -27,8 +27,7 @@ impl<'a> flatbuffers::Follow<'a> for Symbol<'a> { impl<'a> Symbol<'a> { pub const VT_NAME: flatbuffers::VOffsetT = 4; pub const VT_MODIFIERS: flatbuffers::VOffsetT = 6; - pub const VT_CLASS_TYPE: flatbuffers::VOffsetT = 8; - pub const VT_CLASS: flatbuffers::VOffsetT = 10; + pub const VT_CLASS: flatbuffers::VOffsetT = 8; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { @@ -40,9 +39,8 @@ impl<'a> Symbol<'a> { args: &'args SymbolArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = SymbolBuilder::new(_fbb); - if let Some(x) = args.class { builder.add_class(x); } if let Some(x) = args.name { builder.add_name(x); } - builder.add_class_type(args.class_type); + builder.add_class(args.class); builder.add_modifiers(args.modifiers); builder.finish() } @@ -63,47 +61,12 @@ impl<'a> Symbol<'a> { unsafe { self._tab.get::(Symbol::VT_MODIFIERS, Some(Default::default())).unwrap()} } #[inline] - pub fn class_type(&self) -> SymbolClass { + pub fn class(&self) -> SymbolClass { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::(Symbol::VT_CLASS_TYPE, Some(SymbolClass::NONE)).unwrap()} + unsafe { self._tab.get::(Symbol::VT_CLASS, Some(SymbolClass::Function)).unwrap()} } - #[inline] - pub fn class(&self) -> flatbuffers::Table<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(Symbol::VT_CLASS, None).unwrap()} - } - #[inline] - #[allow(non_snake_case)] - pub fn class_as_function_symbol_class(&self) -> Option> { - if self.class_type() == SymbolClass::FunctionSymbolClass { - let u = self.class(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { FunctionSymbolClass::init_from_table(u) }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn class_as_data_symbol_class(&self) -> Option> { - if self.class_type() == SymbolClass::DataSymbolClass { - let u = self.class(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { DataSymbolClass::init_from_table(u) }) - } else { - None - } - } - } impl flatbuffers::Verifiable for Symbol<'_> { @@ -115,13 +78,7 @@ impl flatbuffers::Verifiable for Symbol<'_> { v.visit_table(pos)? .visit_field::>("name", Self::VT_NAME, false)? .visit_field::("modifiers", Self::VT_MODIFIERS, false)? - .visit_union::("class_type", Self::VT_CLASS_TYPE, "class", Self::VT_CLASS, true, |key, v, pos| { - match key { - SymbolClass::FunctionSymbolClass => v.verify_union_variant::>("SymbolClass::FunctionSymbolClass", pos), - SymbolClass::DataSymbolClass => v.verify_union_variant::>("SymbolClass::DataSymbolClass", pos), - _ => Ok(()), - } - })? + .visit_field::("class", Self::VT_CLASS, false)? .finish(); Ok(()) } @@ -129,8 +86,7 @@ impl flatbuffers::Verifiable for Symbol<'_> { pub struct SymbolArgs<'a> { pub name: Option>, pub modifiers: SymbolModifiers, - pub class_type: SymbolClass, - pub class: Option>, + pub class: SymbolClass, } impl<'a> Default for SymbolArgs<'a> { #[inline] @@ -138,8 +94,7 @@ impl<'a> Default for SymbolArgs<'a> { SymbolArgs { name: None, modifiers: Default::default(), - class_type: SymbolClass::NONE, - class: None, // required field + class: SymbolClass::Function, } } } @@ -158,12 +113,8 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SymbolBuilder<'a, 'b, A> { self.fbb_.push_slot::(Symbol::VT_MODIFIERS, modifiers, Default::default()); } #[inline] - pub fn add_class_type(&mut self, class_type: SymbolClass) { - self.fbb_.push_slot::(Symbol::VT_CLASS_TYPE, class_type, SymbolClass::NONE); - } - #[inline] - pub fn add_class(&mut self, class: flatbuffers::WIPOffset) { - self.fbb_.push_slot_always::>(Symbol::VT_CLASS, class); + pub fn add_class(&mut self, class: SymbolClass) { + self.fbb_.push_slot::(Symbol::VT_CLASS, class, SymbolClass::Function); } #[inline] pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> SymbolBuilder<'a, 'b, A> { @@ -176,7 +127,6 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SymbolBuilder<'a, 'b, A> { #[inline] pub fn finish(self) -> flatbuffers::WIPOffset> { let o = self.fbb_.end_table(self.start_); - self.fbb_.required(o, Symbol::VT_CLASS,"class"); flatbuffers::WIPOffset::new(o.value()) } } @@ -186,27 +136,7 @@ impl core::fmt::Debug for Symbol<'_> { let mut ds = f.debug_struct("Symbol"); ds.field("name", &self.name()); ds.field("modifiers", &self.modifiers()); - ds.field("class_type", &self.class_type()); - match self.class_type() { - SymbolClass::FunctionSymbolClass => { - if let Some(x) = self.class_as_function_symbol_class() { - ds.field("class", &x) - } else { - ds.field("class", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - SymbolClass::DataSymbolClass => { - if let Some(x) = self.class_as_data_symbol_class() { - ds.field("class", &x) - } else { - ds.field("class", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - _ => { - let x: Option<()> = None; - ds.field("class", &x) - }, - }; + ds.field("class", &self.class()); ds.finish() } } diff --git a/rust/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs b/rust/src/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs similarity index 70% rename from rust/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs rename to rust/src/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs index 7924d94..59954df 100644 --- a/rust/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs +++ b/rust/src/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs @@ -12,7 +12,7 @@ use super::*; #[allow(non_upper_case_globals)] mod bitflags_symbol_modifiers { flatbuffers::bitflags::bitflags! { - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq)] pub struct SymbolModifiers: u8 { const External = 1; const Exported = 2; @@ -26,11 +26,7 @@ impl<'a> flatbuffers::Follow<'a> for SymbolModifiers { #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { let b = flatbuffers::read_scalar_at::(buf, loc); - // Safety: - // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size. - // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0 - // https://github.com/bitflags/bitflags/issues/262 - Self::from_bits_unchecked(b) + Self::from_bits_retain(b) } } @@ -52,11 +48,7 @@ impl flatbuffers::EndianScalar for SymbolModifiers { #[allow(clippy::wrong_self_convention)] fn from_little_endian(v: u8) -> Self { let b = u8::from_le(v); - // Safety: - // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size. - // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0 - // https://github.com/bitflags/bitflags/issues/262 - unsafe { Self::from_bits_unchecked(b) } + Self::from_bits_retain(b) } } diff --git a/rust/src/gen_flatbuffers/target_bin/target_generated.rs b/rust/src/gen_flatbuffers/target_bin/target_generated.rs new file mode 100644 index 0000000..27fb2f0 --- /dev/null +++ b/rust/src/gen_flatbuffers/target_bin/target_generated.rs @@ -0,0 +1,125 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum TargetOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct Target<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Target<'a> { + type Inner = Target<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> Target<'a> { + pub const VT_ARCHITECTURE: flatbuffers::VOffsetT = 4; + pub const VT_PLATFORM: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Target { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args TargetArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = TargetBuilder::new(_fbb); + if let Some(x) = args.platform { builder.add_platform(x); } + if let Some(x) = args.architecture { builder.add_architecture(x); } + builder.finish() + } + + + #[inline] + pub fn architecture(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(Target::VT_ARCHITECTURE, None)} + } + #[inline] + pub fn platform(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(Target::VT_PLATFORM, None)} + } +} + +impl flatbuffers::Verifiable for Target<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>("architecture", Self::VT_ARCHITECTURE, false)? + .visit_field::>("platform", Self::VT_PLATFORM, false)? + .finish(); + Ok(()) + } +} +pub struct TargetArgs<'a> { + pub architecture: Option>, + pub platform: Option>, +} +impl<'a> Default for TargetArgs<'a> { + #[inline] + fn default() -> Self { + TargetArgs { + architecture: None, + platform: None, + } + } +} + +pub struct TargetBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TargetBuilder<'a, 'b, A> { + #[inline] + pub fn add_architecture(&mut self, architecture: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(Target::VT_ARCHITECTURE, architecture); + } + #[inline] + pub fn add_platform(&mut self, platform: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(Target::VT_PLATFORM, platform); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TargetBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + TargetBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for Target<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("Target"); + ds.field("architecture", &self.architecture()); + ds.field("platform", &self.platform()); + ds.finish() + } +} diff --git a/rust/gen_flatbuffers/type_bin/array_generated.rs b/rust/src/gen_flatbuffers/type_bin/array_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/array_generated.rs rename to rust/src/gen_flatbuffers/type_bin/array_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/array_modifiers_generated.rs b/rust/src/gen_flatbuffers/type_bin/array_modifiers_generated.rs similarity index 70% rename from rust/gen_flatbuffers/type_bin/array_modifiers_generated.rs rename to rust/src/gen_flatbuffers/type_bin/array_modifiers_generated.rs index 9e0f916..d11751d 100644 --- a/rust/gen_flatbuffers/type_bin/array_modifiers_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/array_modifiers_generated.rs @@ -12,7 +12,7 @@ use super::*; #[allow(non_upper_case_globals)] mod bitflags_array_modifiers { flatbuffers::bitflags::bitflags! { - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq)] pub struct ArrayModifiers: u8 { const NullTerminated = 1; } @@ -25,11 +25,7 @@ impl<'a> flatbuffers::Follow<'a> for ArrayModifiers { #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { let b = flatbuffers::read_scalar_at::(buf, loc); - // Safety: - // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size. - // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0 - // https://github.com/bitflags/bitflags/issues/262 - Self::from_bits_unchecked(b) + Self::from_bits_retain(b) } } @@ -51,11 +47,7 @@ impl flatbuffers::EndianScalar for ArrayModifiers { #[allow(clippy::wrong_self_convention)] fn from_little_endian(v: u8) -> Self { let b = u8::from_le(v); - // Safety: - // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size. - // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0 - // https://github.com/bitflags/bitflags/issues/262 - unsafe { Self::from_bits_unchecked(b) } + Self::from_bits_retain(b) } } diff --git a/rust/gen_flatbuffers/type_bin/bit_offset_generated.rs b/rust/src/gen_flatbuffers/type_bin/bit_offset_generated.rs similarity index 94% rename from rust/gen_flatbuffers/type_bin/bit_offset_generated.rs rename to rust/src/gen_flatbuffers/type_bin/bit_offset_generated.rs index fde384d..8f3234d 100644 --- a/rust/gen_flatbuffers/type_bin/bit_offset_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/bit_offset_generated.rs @@ -45,9 +45,13 @@ impl<'b> flatbuffers::Push for BitOffset { type Output = BitOffset; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - let src = ::core::slice::from_raw_parts(self as *const BitOffset as *const u8, Self::size()); + let src = ::core::slice::from_raw_parts(self as *const BitOffset as *const u8, ::size()); dst.copy_from_slice(src); } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(8) + } } impl<'a> flatbuffers::Verifiable for BitOffset { diff --git a/rust/gen_flatbuffers/type_bin/bit_shift_generated.rs b/rust/src/gen_flatbuffers/type_bin/bit_shift_generated.rs similarity index 94% rename from rust/gen_flatbuffers/type_bin/bit_shift_generated.rs rename to rust/src/gen_flatbuffers/type_bin/bit_shift_generated.rs index c69d1c5..432ea95 100644 --- a/rust/gen_flatbuffers/type_bin/bit_shift_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/bit_shift_generated.rs @@ -45,9 +45,13 @@ impl<'b> flatbuffers::Push for BitShift { type Output = BitShift; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - let src = ::core::slice::from_raw_parts(self as *const BitShift as *const u8, Self::size()); + let src = ::core::slice::from_raw_parts(self as *const BitShift as *const u8, ::size()); dst.copy_from_slice(src); } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(8) + } } impl<'a> flatbuffers::Verifiable for BitShift { diff --git a/rust/gen_flatbuffers/type_bin/bit_size_generated.rs b/rust/src/gen_flatbuffers/type_bin/bit_size_generated.rs similarity index 94% rename from rust/gen_flatbuffers/type_bin/bit_size_generated.rs rename to rust/src/gen_flatbuffers/type_bin/bit_size_generated.rs index 30dd075..6478287 100644 --- a/rust/gen_flatbuffers/type_bin/bit_size_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/bit_size_generated.rs @@ -45,9 +45,13 @@ impl<'b> flatbuffers::Push for BitSize { type Output = BitSize; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - let src = ::core::slice::from_raw_parts(self as *const BitSize as *const u8, Self::size()); + let src = ::core::slice::from_raw_parts(self as *const BitSize as *const u8, ::size()); dst.copy_from_slice(src); } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(8) + } } impl<'a> flatbuffers::Verifiable for BitSize { diff --git a/rust/gen_flatbuffers/type_bin/bit_width_generated.rs b/rust/src/gen_flatbuffers/type_bin/bit_width_generated.rs similarity index 94% rename from rust/gen_flatbuffers/type_bin/bit_width_generated.rs rename to rust/src/gen_flatbuffers/type_bin/bit_width_generated.rs index 20e35c5..6ac3396 100644 --- a/rust/gen_flatbuffers/type_bin/bit_width_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/bit_width_generated.rs @@ -45,9 +45,13 @@ impl<'b> flatbuffers::Push for BitWidth { type Output = BitWidth; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - let src = ::core::slice::from_raw_parts(self as *const BitWidth as *const u8, Self::size()); + let src = ::core::slice::from_raw_parts(self as *const BitWidth as *const u8, ::size()); dst.copy_from_slice(src); } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(2) + } } impl<'a> flatbuffers::Verifiable for BitWidth { diff --git a/rust/gen_flatbuffers/type_bin/boolean_generated.rs b/rust/src/gen_flatbuffers/type_bin/boolean_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/boolean_generated.rs rename to rust/src/gen_flatbuffers/type_bin/boolean_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/calling_convention_generated.rs b/rust/src/gen_flatbuffers/type_bin/calling_convention_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/calling_convention_generated.rs rename to rust/src/gen_flatbuffers/type_bin/calling_convention_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/character_generated.rs b/rust/src/gen_flatbuffers/type_bin/character_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/character_generated.rs rename to rust/src/gen_flatbuffers/type_bin/character_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/computed_type_generated.rs b/rust/src/gen_flatbuffers/type_bin/computed_type_generated.rs similarity index 89% rename from rust/gen_flatbuffers/type_bin/computed_type_generated.rs rename to rust/src/gen_flatbuffers/type_bin/computed_type_generated.rs index 1b367fa..01f9ec1 100644 --- a/rust/gen_flatbuffers/type_bin/computed_type_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/computed_type_generated.rs @@ -45,11 +45,11 @@ impl<'a> ComputedType<'a> { #[inline] - pub fn guid(&self) -> &'a str { + pub fn guid(&self) -> &'a TypeGUID { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>(ComputedType::VT_GUID, None).unwrap()} + unsafe { self._tab.get::(ComputedType::VT_GUID, None).unwrap()} } #[inline] pub fn type_(&self) -> Option> { @@ -67,14 +67,14 @@ impl flatbuffers::Verifiable for ComputedType<'_> { ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::>("guid", Self::VT_GUID, true)? + .visit_field::("guid", Self::VT_GUID, true)? .visit_field::>("type_", Self::VT_TYPE_, false)? .finish(); Ok(()) } } pub struct ComputedTypeArgs<'a> { - pub guid: Option>, + pub guid: Option<&'a TypeGUID>, pub type_: Option>>, } impl<'a> Default for ComputedTypeArgs<'a> { @@ -93,8 +93,8 @@ pub struct ComputedTypeBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { } impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ComputedTypeBuilder<'a, 'b, A> { #[inline] - pub fn add_guid(&mut self, guid: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(ComputedType::VT_GUID, guid); + pub fn add_guid(&mut self, guid: &TypeGUID) { + self.fbb_.push_slot_always::<&TypeGUID>(ComputedType::VT_GUID, guid); } #[inline] pub fn add_type_(&mut self, type_: flatbuffers::WIPOffset>) { diff --git a/rust/gen_flatbuffers/type_bin/enumeration_generated.rs b/rust/src/gen_flatbuffers/type_bin/enumeration_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/enumeration_generated.rs rename to rust/src/gen_flatbuffers/type_bin/enumeration_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/enumeration_member_generated.rs b/rust/src/gen_flatbuffers/type_bin/enumeration_member_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/enumeration_member_generated.rs rename to rust/src/gen_flatbuffers/type_bin/enumeration_member_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/float_generated.rs b/rust/src/gen_flatbuffers/type_bin/float_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/float_generated.rs rename to rust/src/gen_flatbuffers/type_bin/float_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/function_generated.rs b/rust/src/gen_flatbuffers/type_bin/function_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/function_generated.rs rename to rust/src/gen_flatbuffers/type_bin/function_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/function_member_generated.rs b/rust/src/gen_flatbuffers/type_bin/function_member_generated.rs similarity index 57% rename from rust/gen_flatbuffers/type_bin/function_member_generated.rs rename to rust/src/gen_flatbuffers/type_bin/function_member_generated.rs index fd541b3..2c3ef0d 100644 --- a/rust/gen_flatbuffers/type_bin/function_member_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/function_member_generated.rs @@ -27,7 +27,8 @@ impl<'a> flatbuffers::Follow<'a> for FunctionMember<'a> { impl<'a> FunctionMember<'a> { pub const VT_NAME: flatbuffers::VOffsetT = 4; pub const VT_TYPE_: flatbuffers::VOffsetT = 6; - pub const VT_LOCATIONS: flatbuffers::VOffsetT = 8; + pub const VT_LOCATION_TYPE: flatbuffers::VOffsetT = 8; + pub const VT_LOCATION: flatbuffers::VOffsetT = 10; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { @@ -39,9 +40,10 @@ impl<'a> FunctionMember<'a> { args: &'args FunctionMemberArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = FunctionMemberBuilder::new(_fbb); - if let Some(x) = args.locations { builder.add_locations(x); } + if let Some(x) = args.location { builder.add_location(x); } if let Some(x) = args.type_ { builder.add_type_(x); } if let Some(x) = args.name { builder.add_name(x); } + builder.add_location_type(args.location_type); builder.finish() } @@ -61,12 +63,49 @@ impl<'a> FunctionMember<'a> { unsafe { self._tab.get::>(FunctionMember::VT_TYPE_, None).unwrap()} } #[inline] - pub fn locations(&self) -> Option>>> { + pub fn location_type(&self) -> LocationClass { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>>>(FunctionMember::VT_LOCATIONS, None)} + unsafe { self._tab.get::(FunctionMember::VT_LOCATION_TYPE, Some(LocationClass::NONE)).unwrap()} } + #[inline] + pub fn location(&self) -> Option> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(FunctionMember::VT_LOCATION, None)} + } + #[inline] + #[allow(non_snake_case)] + pub fn location_as_register_location(&self) -> Option> { + if self.location_type() == LocationClass::RegisterLocation { + self.location().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { RegisterLocation::init_from_table(t) } + }) + } else { + None + } + } + + #[inline] + #[allow(non_snake_case)] + pub fn location_as_stack_location(&self) -> Option> { + if self.location_type() == LocationClass::StackLocation { + self.location().map(|t| { + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + unsafe { StackLocation::init_from_table(t) } + }) + } else { + None + } + } + } impl flatbuffers::Verifiable for FunctionMember<'_> { @@ -78,7 +117,13 @@ impl flatbuffers::Verifiable for FunctionMember<'_> { v.visit_table(pos)? .visit_field::>("name", Self::VT_NAME, false)? .visit_field::>("type_", Self::VT_TYPE_, true)? - .visit_field::>>>("locations", Self::VT_LOCATIONS, false)? + .visit_union::("location_type", Self::VT_LOCATION_TYPE, "location", Self::VT_LOCATION, false, |key, v, pos| { + match key { + LocationClass::RegisterLocation => v.verify_union_variant::>("LocationClass::RegisterLocation", pos), + LocationClass::StackLocation => v.verify_union_variant::>("LocationClass::StackLocation", pos), + _ => Ok(()), + } + })? .finish(); Ok(()) } @@ -86,7 +131,8 @@ impl flatbuffers::Verifiable for FunctionMember<'_> { pub struct FunctionMemberArgs<'a> { pub name: Option>, pub type_: Option>>, - pub locations: Option>>>>, + pub location_type: LocationClass, + pub location: Option>, } impl<'a> Default for FunctionMemberArgs<'a> { #[inline] @@ -94,7 +140,8 @@ impl<'a> Default for FunctionMemberArgs<'a> { FunctionMemberArgs { name: None, type_: None, // required field - locations: None, + location_type: LocationClass::NONE, + location: None, } } } @@ -113,8 +160,12 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FunctionMemberBuilder<'a, 'b, A self.fbb_.push_slot_always::>(FunctionMember::VT_TYPE_, type_); } #[inline] - pub fn add_locations(&mut self, locations: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(FunctionMember::VT_LOCATIONS, locations); + pub fn add_location_type(&mut self, location_type: LocationClass) { + self.fbb_.push_slot::(FunctionMember::VT_LOCATION_TYPE, location_type, LocationClass::NONE); + } + #[inline] + pub fn add_location(&mut self, location: flatbuffers::WIPOffset) { + self.fbb_.push_slot_always::>(FunctionMember::VT_LOCATION, location); } #[inline] pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FunctionMemberBuilder<'a, 'b, A> { @@ -137,7 +188,27 @@ impl core::fmt::Debug for FunctionMember<'_> { let mut ds = f.debug_struct("FunctionMember"); ds.field("name", &self.name()); ds.field("type_", &self.type_()); - ds.field("locations", &self.locations()); + ds.field("location_type", &self.location_type()); + match self.location_type() { + LocationClass::RegisterLocation => { + if let Some(x) = self.location_as_register_location() { + ds.field("location", &x) + } else { + ds.field("location", &"InvalidFlatbuffer: Union discriminant does not match value.") + } + }, + LocationClass::StackLocation => { + if let Some(x) = self.location_as_stack_location() { + ds.field("location", &x) + } else { + ds.field("location", &"InvalidFlatbuffer: Union discriminant does not match value.") + } + }, + _ => { + let x: Option<()> = None; + ds.field("location", &x) + }, + }; ds.finish() } } diff --git a/rust/gen_flatbuffers/type_bin/function_member_location_generated.rs b/rust/src/gen_flatbuffers/type_bin/function_member_location_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/function_member_location_generated.rs rename to rust/src/gen_flatbuffers/type_bin/function_member_location_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/integer_generated.rs b/rust/src/gen_flatbuffers/type_bin/integer_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/integer_generated.rs rename to rust/src/gen_flatbuffers/type_bin/integer_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/location_class_generated.rs b/rust/src/gen_flatbuffers/type_bin/location_class_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/location_class_generated.rs rename to rust/src/gen_flatbuffers/type_bin/location_class_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/type_alignment_generated.rs b/rust/src/gen_flatbuffers/type_bin/metadata_value_type_generated.rs similarity index 66% rename from rust/gen_flatbuffers/type_bin/type_alignment_generated.rs rename to rust/src/gen_flatbuffers/type_bin/metadata_value_type_generated.rs index 3ce9e85..0fe2f0a 100644 --- a/rust/gen_flatbuffers/type_bin/type_alignment_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/metadata_value_type_generated.rs @@ -10,44 +10,40 @@ use core::cmp::Ordering; use self::flatbuffers::{EndianScalar, Follow}; use super::*; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] -pub const ENUM_MIN_TYPE_ALIGNMENT: u8 = 0; +pub const ENUM_MIN_METADATA_VALUE_TYPE: u8 = 0; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] -pub const ENUM_MAX_TYPE_ALIGNMENT: u8 = 2; +pub const ENUM_MAX_METADATA_VALUE_TYPE: u8 = 1; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] #[allow(non_camel_case_types)] -pub const ENUM_VALUES_TYPE_ALIGNMENT: [TypeAlignment; 3] = [ - TypeAlignment::NONE, - TypeAlignment::AccessAlignment, - TypeAlignment::FixedAlignment, +pub const ENUM_VALUES_METADATA_VALUE_TYPE: [MetadataValueType; 2] = [ + MetadataValueType::Raw, + MetadataValueType::String, ]; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[repr(transparent)] -pub struct TypeAlignment(pub u8); +pub struct MetadataValueType(pub u8); #[allow(non_upper_case_globals)] -impl TypeAlignment { - pub const NONE: Self = Self(0); - pub const AccessAlignment: Self = Self(1); - pub const FixedAlignment: Self = Self(2); +impl MetadataValueType { + pub const Raw: Self = Self(0); + pub const String: Self = Self(1); pub const ENUM_MIN: u8 = 0; - pub const ENUM_MAX: u8 = 2; + pub const ENUM_MAX: u8 = 1; pub const ENUM_VALUES: &'static [Self] = &[ - Self::NONE, - Self::AccessAlignment, - Self::FixedAlignment, + Self::Raw, + Self::String, ]; /// Returns the variant's name or "" if unknown. pub fn variant_name(self) -> Option<&'static str> { match self { - Self::NONE => Some("NONE"), - Self::AccessAlignment => Some("AccessAlignment"), - Self::FixedAlignment => Some("FixedAlignment"), + Self::Raw => Some("Raw"), + Self::String => Some("String"), _ => None, } } } -impl core::fmt::Debug for TypeAlignment { +impl core::fmt::Debug for MetadataValueType { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { if let Some(name) = self.variant_name() { f.write_str(name) @@ -56,7 +52,7 @@ impl core::fmt::Debug for TypeAlignment { } } } -impl<'a> flatbuffers::Follow<'a> for TypeAlignment { +impl<'a> flatbuffers::Follow<'a> for MetadataValueType { type Inner = Self; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { @@ -65,15 +61,15 @@ impl<'a> flatbuffers::Follow<'a> for TypeAlignment { } } -impl flatbuffers::Push for TypeAlignment { - type Output = TypeAlignment; +impl flatbuffers::Push for MetadataValueType { + type Output = MetadataValueType; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { flatbuffers::emplace_scalar::(dst, self.0); } } -impl flatbuffers::EndianScalar for TypeAlignment { +impl flatbuffers::EndianScalar for MetadataValueType { type Scalar = u8; #[inline] fn to_little_endian(self) -> u8 { @@ -87,7 +83,7 @@ impl flatbuffers::EndianScalar for TypeAlignment { } } -impl<'a> flatbuffers::Verifiable for TypeAlignment { +impl<'a> flatbuffers::Verifiable for MetadataValueType { #[inline] fn run_verifier( v: &mut flatbuffers::Verifier, pos: usize @@ -97,6 +93,4 @@ impl<'a> flatbuffers::Verifiable for TypeAlignment { } } -impl flatbuffers::SimpleToVerifyInSlice for TypeAlignment {} -pub struct TypeAlignmentUnionTableOffset {} - +impl flatbuffers::SimpleToVerifyInSlice for MetadataValueType {} diff --git a/rust/gen_flatbuffers/type_bin/pointer_addressing_generated.rs b/rust/src/gen_flatbuffers/type_bin/pointer_addressing_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/pointer_addressing_generated.rs rename to rust/src/gen_flatbuffers/type_bin/pointer_addressing_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/pointer_generated.rs b/rust/src/gen_flatbuffers/type_bin/pointer_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/pointer_generated.rs rename to rust/src/gen_flatbuffers/type_bin/pointer_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/referrer_generated.rs b/rust/src/gen_flatbuffers/type_bin/referrer_generated.rs similarity index 88% rename from rust/gen_flatbuffers/type_bin/referrer_generated.rs rename to rust/src/gen_flatbuffers/type_bin/referrer_generated.rs index 9cf9d6e..8d3b51c 100644 --- a/rust/gen_flatbuffers/type_bin/referrer_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/referrer_generated.rs @@ -45,11 +45,11 @@ impl<'a> Referrer<'a> { #[inline] - pub fn guid(&self) -> Option<&'a str> { + pub fn guid(&self) -> Option<&'a TypeGUID> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>(Referrer::VT_GUID, None)} + unsafe { self._tab.get::(Referrer::VT_GUID, None)} } #[inline] pub fn name(&self) -> Option<&'a str> { @@ -67,14 +67,14 @@ impl flatbuffers::Verifiable for Referrer<'_> { ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::>("guid", Self::VT_GUID, false)? + .visit_field::("guid", Self::VT_GUID, false)? .visit_field::>("name", Self::VT_NAME, false)? .finish(); Ok(()) } } pub struct ReferrerArgs<'a> { - pub guid: Option>, + pub guid: Option<&'a TypeGUID>, pub name: Option>, } impl<'a> Default for ReferrerArgs<'a> { @@ -93,8 +93,8 @@ pub struct ReferrerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { } impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ReferrerBuilder<'a, 'b, A> { #[inline] - pub fn add_guid(&mut self, guid: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(Referrer::VT_GUID, guid); + pub fn add_guid(&mut self, guid: &TypeGUID) { + self.fbb_.push_slot_always::<&TypeGUID>(Referrer::VT_GUID, guid); } #[inline] pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b str>) { diff --git a/rust/gen_flatbuffers/type_bin/register_location_generated.rs b/rust/src/gen_flatbuffers/type_bin/register_location_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/register_location_generated.rs rename to rust/src/gen_flatbuffers/type_bin/register_location_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/stack_location_generated.rs b/rust/src/gen_flatbuffers/type_bin/stack_location_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/stack_location_generated.rs rename to rust/src/gen_flatbuffers/type_bin/stack_location_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/structure_generated.rs b/rust/src/gen_flatbuffers/type_bin/structure_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/structure_generated.rs rename to rust/src/gen_flatbuffers/type_bin/structure_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/structure_member_generated.rs b/rust/src/gen_flatbuffers/type_bin/structure_member_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/structure_member_generated.rs rename to rust/src/gen_flatbuffers/type_bin/structure_member_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs b/rust/src/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs similarity index 72% rename from rust/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs rename to rust/src/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs index 11e4841..bf5b77a 100644 --- a/rust/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs @@ -12,7 +12,7 @@ use super::*; #[allow(non_upper_case_globals)] mod bitflags_structure_member_modifiers { flatbuffers::bitflags::bitflags! { - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq)] pub struct StructureMemberModifiers: u8 { const Internal = 1; const Flattened = 2; @@ -26,11 +26,7 @@ impl<'a> flatbuffers::Follow<'a> for StructureMemberModifiers { #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { let b = flatbuffers::read_scalar_at::(buf, loc); - // Safety: - // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size. - // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0 - // https://github.com/bitflags/bitflags/issues/262 - Self::from_bits_unchecked(b) + Self::from_bits_retain(b) } } @@ -52,11 +48,7 @@ impl flatbuffers::EndianScalar for StructureMemberModifiers { #[allow(clippy::wrong_self_convention)] fn from_little_endian(v: u8) -> Self { let b = u8::from_le(v); - // Safety: - // This is safe because we know bitflags is implemented with a repr transparent uint of the correct size. - // from_bits_unchecked will be replaced by an equivalent but safe from_bits_retain in bitflags 2.0 - // https://github.com/bitflags/bitflags/issues/262 - unsafe { Self::from_bits_unchecked(b) } + Self::from_bits_retain(b) } } diff --git a/rust/gen_flatbuffers/type_bin/data_generated.rs b/rust/src/gen_flatbuffers/type_bin/type_chunk_generated.rs similarity index 56% rename from rust/gen_flatbuffers/type_bin/data_generated.rs rename to rust/src/gen_flatbuffers/type_bin/type_chunk_generated.rs index 09055ee..d0396d1 100644 --- a/rust/gen_flatbuffers/type_bin/data_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/type_chunk_generated.rs @@ -9,185 +9,172 @@ use core::mem; use core::cmp::Ordering; use self::flatbuffers::{EndianScalar, Follow}; use super::*; -pub enum DataOffset {} +pub enum TypeChunkOffset {} #[derive(Copy, Clone, PartialEq)] -pub struct Data<'a> { +pub struct TypeChunk<'a> { pub _tab: flatbuffers::Table<'a>, } -impl<'a> flatbuffers::Follow<'a> for Data<'a> { - type Inner = Data<'a>; +impl<'a> flatbuffers::Follow<'a> for TypeChunk<'a> { + type Inner = TypeChunk<'a>; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { Self { _tab: flatbuffers::Table::new(buf, loc) } } } -impl<'a> Data<'a> { +impl<'a> TypeChunk<'a> { pub const VT_TYPES: flatbuffers::VOffsetT = 4; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - Data { _tab: table } + TypeChunk { _tab: table } } #[allow(unused_mut)] pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args DataArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = DataBuilder::new(_fbb); + args: &'args TypeChunkArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = TypeChunkBuilder::new(_fbb); if let Some(x) = args.types { builder.add_types(x); } builder.finish() } #[inline] - pub fn types(&self) -> Option>>> { + pub fn types(&self) -> flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset>> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>>>(Data::VT_TYPES, None)} + unsafe { self._tab.get::>>>(TypeChunk::VT_TYPES, None).unwrap()} } } -impl flatbuffers::Verifiable for Data<'_> { +impl flatbuffers::Verifiable for TypeChunk<'_> { #[inline] fn run_verifier( v: &mut flatbuffers::Verifier, pos: usize ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::>>>("types", Self::VT_TYPES, false)? + .visit_field::>>>("types", Self::VT_TYPES, true)? .finish(); Ok(()) } } -pub struct DataArgs<'a> { +pub struct TypeChunkArgs<'a> { pub types: Option>>>>, } -impl<'a> Default for DataArgs<'a> { +impl<'a> Default for TypeChunkArgs<'a> { #[inline] fn default() -> Self { - DataArgs { - types: None, + TypeChunkArgs { + types: None, // required field } } } -pub struct DataBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { +pub struct TypeChunkBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DataBuilder<'a, 'b, A> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TypeChunkBuilder<'a, 'b, A> { #[inline] pub fn add_types(&mut self, types: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(Data::VT_TYPES, types); + self.fbb_.push_slot_always::>(TypeChunk::VT_TYPES, types); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DataBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TypeChunkBuilder<'a, 'b, A> { let start = _fbb.start_table(); - DataBuilder { + TypeChunkBuilder { fbb_: _fbb, start_: start, } } #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { + pub fn finish(self) -> flatbuffers::WIPOffset> { let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, TypeChunk::VT_TYPES,"types"); flatbuffers::WIPOffset::new(o.value()) } } -impl core::fmt::Debug for Data<'_> { +impl core::fmt::Debug for TypeChunk<'_> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("Data"); + let mut ds = f.debug_struct("TypeChunk"); ds.field("types", &self.types()); ds.finish() } } #[inline] -/// Verifies that a buffer of bytes contains a `Data` +/// Verifies that a buffer of bytes contains a `TypeChunk` /// and returns it. /// Note that verification is still experimental and may not /// catch every error, or be maximally performant. For the /// previous, unchecked, behavior use -/// `root_as_data_unchecked`. -pub fn root_as_data(buf: &[u8]) -> Result { - flatbuffers::root::(buf) +/// `root_as_type_chunk_unchecked`. +pub fn root_as_type_chunk(buf: &[u8]) -> Result { + flatbuffers::root::(buf) } #[inline] /// Verifies that a buffer of bytes contains a size prefixed -/// `Data` and returns it. +/// `TypeChunk` and returns it. /// Note that verification is still experimental and may not /// catch every error, or be maximally performant. For the /// previous, unchecked, behavior use -/// `size_prefixed_root_as_data_unchecked`. -pub fn size_prefixed_root_as_data(buf: &[u8]) -> Result { - flatbuffers::size_prefixed_root::(buf) +/// `size_prefixed_root_as_type_chunk_unchecked`. +pub fn size_prefixed_root_as_type_chunk(buf: &[u8]) -> Result { + flatbuffers::size_prefixed_root::(buf) } #[inline] /// Verifies, with the given options, that a buffer of bytes -/// contains a `Data` and returns it. +/// contains a `TypeChunk` and returns it. /// Note that verification is still experimental and may not /// catch every error, or be maximally performant. For the /// previous, unchecked, behavior use -/// `root_as_data_unchecked`. -pub fn root_as_data_with_opts<'b, 'o>( +/// `root_as_type_chunk_unchecked`. +pub fn root_as_type_chunk_with_opts<'b, 'o>( opts: &'o flatbuffers::VerifierOptions, buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::root_with_opts::>(opts, buf) } #[inline] /// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `Data` and returns +/// bytes contains a size prefixed `TypeChunk` and returns /// it. Note that verification is still experimental and may not /// catch every error, or be maximally performant. For the /// previous, unchecked, behavior use -/// `root_as_data_unchecked`. -pub fn size_prefixed_root_as_data_with_opts<'b, 'o>( +/// `root_as_type_chunk_unchecked`. +pub fn size_prefixed_root_as_type_chunk_with_opts<'b, 'o>( opts: &'o flatbuffers::VerifierOptions, buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::size_prefixed_root_with_opts::>(opts, buf) } #[inline] -/// Assumes, without verification, that a buffer of bytes contains a Data and returns it. +/// Assumes, without verification, that a buffer of bytes contains a TypeChunk and returns it. /// # Safety -/// Callers must trust the given bytes do indeed contain a valid `Data`. -pub unsafe fn root_as_data_unchecked(buf: &[u8]) -> Data { - flatbuffers::root_unchecked::(buf) +/// Callers must trust the given bytes do indeed contain a valid `TypeChunk`. +pub unsafe fn root_as_type_chunk_unchecked(buf: &[u8]) -> TypeChunk { + flatbuffers::root_unchecked::(buf) } #[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed Data and returns it. +/// Assumes, without verification, that a buffer of bytes contains a size prefixed TypeChunk and returns it. /// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `Data`. -pub unsafe fn size_prefixed_root_as_data_unchecked(buf: &[u8]) -> Data { - flatbuffers::size_prefixed_root_unchecked::(buf) +/// Callers must trust the given bytes do indeed contain a valid size prefixed `TypeChunk`. +pub unsafe fn size_prefixed_root_as_type_chunk_unchecked(buf: &[u8]) -> TypeChunk { + flatbuffers::size_prefixed_root_unchecked::(buf) } -pub const DATA_IDENTIFIER: &str = "TBIN"; - -#[inline] -pub fn data_buffer_has_identifier(buf: &[u8]) -> bool { - flatbuffers::buffer_has_identifier(buf, DATA_IDENTIFIER, false) -} - -#[inline] -pub fn data_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { - flatbuffers::buffer_has_identifier(buf, DATA_IDENTIFIER, true) -} - -pub const DATA_EXTENSION: &str = "tbin"; - #[inline] -pub fn finish_data_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( +pub fn finish_type_chunk_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>) { - fbb.finish(root, Some(DATA_IDENTIFIER)); + root: flatbuffers::WIPOffset>) { + fbb.finish(root, None); } #[inline] -pub fn finish_size_prefixed_data_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { - fbb.finish_size_prefixed(root, Some(DATA_IDENTIFIER)); +pub fn finish_size_prefixed_type_chunk_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { + fbb.finish_size_prefixed(root, None); } diff --git a/rust/gen_flatbuffers/type_bin/type_class_generated.rs b/rust/src/gen_flatbuffers/type_bin/type_class_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/type_class_generated.rs rename to rust/src/gen_flatbuffers/type_bin/type_class_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/type_generated.rs b/rust/src/gen_flatbuffers/type_bin/type_generated.rs similarity index 78% rename from rust/gen_flatbuffers/type_bin/type_generated.rs rename to rust/src/gen_flatbuffers/type_bin/type_generated.rs index 204adcf..a6f7cbf 100644 --- a/rust/gen_flatbuffers/type_bin/type_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/type_generated.rs @@ -29,9 +29,9 @@ impl<'a> Type<'a> { pub const VT_CLASS_TYPE: flatbuffers::VOffsetT = 6; pub const VT_CLASS: flatbuffers::VOffsetT = 8; pub const VT_CONFIDENCE: flatbuffers::VOffsetT = 10; - pub const VT_ALIGNMENT_TYPE: flatbuffers::VOffsetT = 12; - pub const VT_ALIGNMENT_: flatbuffers::VOffsetT = 14; - pub const VT_MODIFIERS: flatbuffers::VOffsetT = 16; + pub const VT_ALIGNMENT: flatbuffers::VOffsetT = 12; + pub const VT_MODIFIERS: flatbuffers::VOffsetT = 14; + pub const VT_METADATA: flatbuffers::VOffsetT = 16; pub const VT_ANCESTORS: flatbuffers::VOffsetT = 18; #[inline] @@ -45,11 +45,11 @@ impl<'a> Type<'a> { ) -> flatbuffers::WIPOffset> { let mut builder = TypeBuilder::new(_fbb); if let Some(x) = args.ancestors { builder.add_ancestors(x); } - if let Some(x) = args.modifiers { builder.add_modifiers(x); } - if let Some(x) = args.alignment_ { builder.add_alignment_(x); } + if let Some(x) = args.metadata { builder.add_metadata(x); } if let Some(x) = args.class { builder.add_class(x); } if let Some(x) = args.name { builder.add_name(x); } - builder.add_alignment_type(args.alignment_type); + builder.add_alignment(args.alignment); + builder.add_modifiers(args.modifiers); builder.add_confidence(args.confidence); builder.add_class_type(args.class_type); builder.finish() @@ -85,32 +85,32 @@ impl<'a> Type<'a> { unsafe { self._tab.get::(Type::VT_CONFIDENCE, Some(255)).unwrap()} } #[inline] - pub fn alignment_type(&self) -> TypeAlignment { + pub fn alignment(&self) -> u16 { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::(Type::VT_ALIGNMENT_TYPE, Some(TypeAlignment::NONE)).unwrap()} + unsafe { self._tab.get::(Type::VT_ALIGNMENT, Some(0)).unwrap()} } #[inline] - pub fn alignment_(&self) -> Option> { + pub fn modifiers(&self) -> TypeModifiers { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>>(Type::VT_ALIGNMENT_, None)} + unsafe { self._tab.get::(Type::VT_MODIFIERS, Some(Default::default())).unwrap()} } #[inline] - pub fn modifiers(&self) -> Option>>> { + pub fn metadata(&self) -> Option>>> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>>>(Type::VT_MODIFIERS, None)} + unsafe { self._tab.get::>>>(Type::VT_METADATA, None)} } #[inline] - pub fn ancestors(&self) -> Option>> { + pub fn ancestors(&self) -> Option> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>>>(Type::VT_ANCESTORS, None)} + unsafe { self._tab.get::>>(Type::VT_ANCESTORS, None)} } #[inline] #[allow(non_snake_case)] @@ -280,36 +280,6 @@ impl<'a> Type<'a> { } } - #[inline] - #[allow(non_snake_case)] - pub fn alignment__as_access_alignment(&self) -> Option> { - if self.alignment_type() == TypeAlignment::AccessAlignment { - self.alignment_().map(|t| { - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - unsafe { AccessAlignment::init_from_table(t) } - }) - } else { - None - } - } - - #[inline] - #[allow(non_snake_case)] - pub fn alignment__as_fixed_alignment(&self) -> Option> { - if self.alignment_type() == TypeAlignment::FixedAlignment { - self.alignment_().map(|t| { - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - unsafe { FixedAlignment::init_from_table(t) } - }) - } else { - None - } - } - } impl flatbuffers::Verifiable for Type<'_> { @@ -338,15 +308,10 @@ impl flatbuffers::Verifiable for Type<'_> { } })? .visit_field::("confidence", Self::VT_CONFIDENCE, false)? - .visit_union::("alignment_type", Self::VT_ALIGNMENT_TYPE, "alignment_", Self::VT_ALIGNMENT_, false, |key, v, pos| { - match key { - TypeAlignment::AccessAlignment => v.verify_union_variant::>("TypeAlignment::AccessAlignment", pos), - TypeAlignment::FixedAlignment => v.verify_union_variant::>("TypeAlignment::FixedAlignment", pos), - _ => Ok(()), - } - })? - .visit_field::>>>("modifiers", Self::VT_MODIFIERS, false)? - .visit_field::>>>("ancestors", Self::VT_ANCESTORS, false)? + .visit_field::("alignment", Self::VT_ALIGNMENT, false)? + .visit_field::("modifiers", Self::VT_MODIFIERS, false)? + .visit_field::>>>("metadata", Self::VT_METADATA, false)? + .visit_field::>>("ancestors", Self::VT_ANCESTORS, false)? .finish(); Ok(()) } @@ -356,10 +321,10 @@ pub struct TypeArgs<'a> { pub class_type: TypeClass, pub class: Option>, pub confidence: u8, - pub alignment_type: TypeAlignment, - pub alignment_: Option>, - pub modifiers: Option>>>>, - pub ancestors: Option>>>, + pub alignment: u16, + pub modifiers: TypeModifiers, + pub metadata: Option>>>>, + pub ancestors: Option>>, } impl<'a> Default for TypeArgs<'a> { #[inline] @@ -369,9 +334,9 @@ impl<'a> Default for TypeArgs<'a> { class_type: TypeClass::NONE, class: None, // required field confidence: 255, - alignment_type: TypeAlignment::NONE, - alignment_: None, - modifiers: None, + alignment: 0, + modifiers: Default::default(), + metadata: None, ancestors: None, } } @@ -399,19 +364,19 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TypeBuilder<'a, 'b, A> { self.fbb_.push_slot::(Type::VT_CONFIDENCE, confidence, 255); } #[inline] - pub fn add_alignment_type(&mut self, alignment_type: TypeAlignment) { - self.fbb_.push_slot::(Type::VT_ALIGNMENT_TYPE, alignment_type, TypeAlignment::NONE); + pub fn add_alignment(&mut self, alignment: u16) { + self.fbb_.push_slot::(Type::VT_ALIGNMENT, alignment, 0); } #[inline] - pub fn add_alignment_(&mut self, alignment_: flatbuffers::WIPOffset) { - self.fbb_.push_slot_always::>(Type::VT_ALIGNMENT_, alignment_); + pub fn add_modifiers(&mut self, modifiers: TypeModifiers) { + self.fbb_.push_slot::(Type::VT_MODIFIERS, modifiers, Default::default()); } #[inline] - pub fn add_modifiers(&mut self, modifiers: flatbuffers::WIPOffset>>>) { - self.fbb_.push_slot_always::>(Type::VT_MODIFIERS, modifiers); + pub fn add_metadata(&mut self, metadata: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Type::VT_METADATA, metadata); } #[inline] - pub fn add_ancestors(&mut self, ancestors: flatbuffers::WIPOffset>>) { + pub fn add_ancestors(&mut self, ancestors: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(Type::VT_ANCESTORS, ancestors); } #[inline] @@ -526,28 +491,9 @@ impl core::fmt::Debug for Type<'_> { }, }; ds.field("confidence", &self.confidence()); - ds.field("alignment_type", &self.alignment_type()); - match self.alignment_type() { - TypeAlignment::AccessAlignment => { - if let Some(x) = self.alignment__as_access_alignment() { - ds.field("alignment_", &x) - } else { - ds.field("alignment_", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - TypeAlignment::FixedAlignment => { - if let Some(x) = self.alignment__as_fixed_alignment() { - ds.field("alignment_", &x) - } else { - ds.field("alignment_", &"InvalidFlatbuffer: Union discriminant does not match value.") - } - }, - _ => { - let x: Option<()> = None; - ds.field("alignment_", &x) - }, - }; + ds.field("alignment", &self.alignment()); ds.field("modifiers", &self.modifiers()); + ds.field("metadata", &self.metadata()); ds.field("ancestors", &self.ancestors()); ds.finish() } diff --git a/rust/src/gen_flatbuffers/type_bin/type_guid_generated.rs b/rust/src/gen_flatbuffers/type_bin/type_guid_generated.rs new file mode 100644 index 0000000..49854d2 --- /dev/null +++ b/rust/src/gen_flatbuffers/type_bin/type_guid_generated.rs @@ -0,0 +1,92 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +// struct TypeGUID, aligned to 1 +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq)] +pub struct TypeGUID(pub [u8; 16]); +impl Default for TypeGUID { + fn default() -> Self { + Self([0; 16]) + } +} +impl core::fmt::Debug for TypeGUID { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("TypeGUID") + .field("value", &self.value()) + .finish() + } +} + +impl flatbuffers::SimpleToVerifyInSlice for TypeGUID {} +impl<'a> flatbuffers::Follow<'a> for TypeGUID { + type Inner = &'a TypeGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + <&'a TypeGUID>::follow(buf, loc) + } +} +impl<'a> flatbuffers::Follow<'a> for &'a TypeGUID { + type Inner = &'a TypeGUID; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + flatbuffers::follow_cast_ref::(buf, loc) + } +} +impl<'b> flatbuffers::Push for TypeGUID { + type Output = TypeGUID; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + let src = ::core::slice::from_raw_parts(self as *const TypeGUID as *const u8, ::size()); + dst.copy_from_slice(src); + } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(1) + } +} + +impl<'a> flatbuffers::Verifiable for TypeGUID { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.in_buffer::(pos) + } +} + +impl<'a> TypeGUID { + #[allow(clippy::too_many_arguments)] + pub fn new( + value: &[u8; 16], + ) -> Self { + let mut s = Self([0; 16]); + s.set_value(value); + s + } + + pub fn value(&'a self) -> flatbuffers::Array<'a, u8, 16> { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::Array::follow(&self.0, 0) } + } + + pub fn set_value(&mut self, items: &[u8; 16]) { + // Safety: + // Created from a valid Table for this object + // Which contains a valid array in this slot + unsafe { flatbuffers::emplace_scalar_array(&mut self.0, 0, items) }; + } + +} + diff --git a/rust/gen_flatbuffers/type_bin/metadata_modifier_class_generated.rs b/rust/src/gen_flatbuffers/type_bin/type_metadata_generated.rs similarity index 53% rename from rust/gen_flatbuffers/type_bin/metadata_modifier_class_generated.rs rename to rust/src/gen_flatbuffers/type_bin/type_metadata_generated.rs index 1992d83..88ea79c 100644 --- a/rust/gen_flatbuffers/type_bin/metadata_modifier_class_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/type_metadata_generated.rs @@ -9,116 +9,144 @@ use core::mem; use core::cmp::Ordering; use self::flatbuffers::{EndianScalar, Follow}; use super::*; -pub enum MetadataModifierClassOffset {} +pub enum TypeMetadataOffset {} #[derive(Copy, Clone, PartialEq)] -pub struct MetadataModifierClass<'a> { +pub struct TypeMetadata<'a> { pub _tab: flatbuffers::Table<'a>, } -impl<'a> flatbuffers::Follow<'a> for MetadataModifierClass<'a> { - type Inner = MetadataModifierClass<'a>; +impl<'a> flatbuffers::Follow<'a> for TypeMetadata<'a> { + type Inner = TypeMetadata<'a>; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { Self { _tab: flatbuffers::Table::new(buf, loc) } } } -impl<'a> MetadataModifierClass<'a> { +impl<'a> TypeMetadata<'a> { pub const VT_KEY: flatbuffers::VOffsetT = 4; - pub const VT_VALUE: flatbuffers::VOffsetT = 6; + pub const VT_VALUE_TYPE: flatbuffers::VOffsetT = 6; + pub const VT_VALUE: flatbuffers::VOffsetT = 8; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - MetadataModifierClass { _tab: table } + TypeMetadata { _tab: table } } #[allow(unused_mut)] pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args MetadataModifierClassArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = MetadataModifierClassBuilder::new(_fbb); + args: &'args TypeMetadataArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = TypeMetadataBuilder::new(_fbb); if let Some(x) = args.value { builder.add_value(x); } if let Some(x) = args.key { builder.add_key(x); } + builder.add_value_type(args.value_type); builder.finish() } #[inline] - pub fn key(&self) -> Option<&'a str> { + pub fn key(&self) -> &'a str { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>(MetadataModifierClass::VT_KEY, None)} + unsafe { self._tab.get::>(TypeMetadata::VT_KEY, None).unwrap()} + } + #[inline] + pub fn key_compare_less_than(&self, o: &TypeMetadata) -> bool { + self.key() < o.key() + } + + #[inline] + pub fn key_compare_with_value(&self, val: & str) -> ::core::cmp::Ordering { + let key = self.key(); + key.cmp(val) + } + #[inline] + pub fn value_type(&self) -> MetadataValueType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TypeMetadata::VT_VALUE_TYPE, Some(MetadataValueType::Raw)).unwrap()} } #[inline] pub fn value(&self) -> Option> { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::>>(MetadataModifierClass::VT_VALUE, None)} + unsafe { self._tab.get::>>(TypeMetadata::VT_VALUE, None)} } } -impl flatbuffers::Verifiable for MetadataModifierClass<'_> { +impl flatbuffers::Verifiable for TypeMetadata<'_> { #[inline] fn run_verifier( v: &mut flatbuffers::Verifier, pos: usize ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::>("key", Self::VT_KEY, false)? + .visit_field::>("key", Self::VT_KEY, true)? + .visit_field::("value_type", Self::VT_VALUE_TYPE, false)? .visit_field::>>("value", Self::VT_VALUE, false)? .finish(); Ok(()) } } -pub struct MetadataModifierClassArgs<'a> { +pub struct TypeMetadataArgs<'a> { pub key: Option>, + pub value_type: MetadataValueType, pub value: Option>>, } -impl<'a> Default for MetadataModifierClassArgs<'a> { +impl<'a> Default for TypeMetadataArgs<'a> { #[inline] fn default() -> Self { - MetadataModifierClassArgs { - key: None, + TypeMetadataArgs { + key: None, // required field + value_type: MetadataValueType::Raw, value: None, } } } -pub struct MetadataModifierClassBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { +pub struct TypeMetadataBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> MetadataModifierClassBuilder<'a, 'b, A> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TypeMetadataBuilder<'a, 'b, A> { #[inline] pub fn add_key(&mut self, key: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>(MetadataModifierClass::VT_KEY, key); + self.fbb_.push_slot_always::>(TypeMetadata::VT_KEY, key); + } + #[inline] + pub fn add_value_type(&mut self, value_type: MetadataValueType) { + self.fbb_.push_slot::(TypeMetadata::VT_VALUE_TYPE, value_type, MetadataValueType::Raw); } #[inline] pub fn add_value(&mut self, value: flatbuffers::WIPOffset>) { - self.fbb_.push_slot_always::>(MetadataModifierClass::VT_VALUE, value); + self.fbb_.push_slot_always::>(TypeMetadata::VT_VALUE, value); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> MetadataModifierClassBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TypeMetadataBuilder<'a, 'b, A> { let start = _fbb.start_table(); - MetadataModifierClassBuilder { + TypeMetadataBuilder { fbb_: _fbb, start_: start, } } #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { + pub fn finish(self) -> flatbuffers::WIPOffset> { let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, TypeMetadata::VT_KEY,"key"); flatbuffers::WIPOffset::new(o.value()) } } -impl core::fmt::Debug for MetadataModifierClass<'_> { +impl core::fmt::Debug for TypeMetadata<'_> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("MetadataModifierClass"); + let mut ds = f.debug_struct("TypeMetadata"); ds.field("key", &self.key()); + ds.field("value_type", &self.value_type()); ds.field("value", &self.value()); ds.finish() } diff --git a/rust/src/gen_flatbuffers/type_bin/type_modifiers_generated.rs b/rust/src/gen_flatbuffers/type_bin/type_modifiers_generated.rs new file mode 100644 index 0000000..3edb301 --- /dev/null +++ b/rust/src/gen_flatbuffers/type_bin/type_modifiers_generated.rs @@ -0,0 +1,65 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +#[allow(non_upper_case_globals)] +mod bitflags_type_modifiers { + flatbuffers::bitflags::bitflags! { + #[derive(Default, Debug, Clone, Copy, PartialEq)] + pub struct TypeModifiers: u8 { + const Constant = 1; + const Volatile = 2; + } + } +} +pub use self::bitflags_type_modifiers::TypeModifiers; + +impl<'a> flatbuffers::Follow<'a> for TypeModifiers { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); + Self::from_bits_retain(b) + } +} + +impl flatbuffers::Push for TypeModifiers { + type Output = TypeModifiers; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.bits()); + } +} + +impl flatbuffers::EndianScalar for TypeModifiers { + type Scalar = u8; + #[inline] + fn to_little_endian(self) -> u8 { + self.bits().to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: u8) -> Self { + let b = u8::from_le(v); + Self::from_bits_retain(b) + } +} + +impl<'a> flatbuffers::Verifiable for TypeModifiers { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + u8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for TypeModifiers {} diff --git a/rust/gen_flatbuffers/type_bin/union_generated.rs b/rust/src/gen_flatbuffers/type_bin/union_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/union_generated.rs rename to rust/src/gen_flatbuffers/type_bin/union_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/union_member_generated.rs b/rust/src/gen_flatbuffers/type_bin/union_member_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/union_member_generated.rs rename to rust/src/gen_flatbuffers/type_bin/union_member_generated.rs diff --git a/rust/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs b/rust/src/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs similarity index 94% rename from rust/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs rename to rust/src/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs index 5cdf6d0..f1810d8 100644 --- a/rust/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs +++ b/rust/src/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs @@ -45,9 +45,13 @@ impl<'b> flatbuffers::Push for UnsignedBitOffset { type Output = UnsignedBitOffset; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - let src = ::core::slice::from_raw_parts(self as *const UnsignedBitOffset as *const u8, Self::size()); + let src = ::core::slice::from_raw_parts(self as *const UnsignedBitOffset as *const u8, ::size()); dst.copy_from_slice(src); } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(8) + } } impl<'a> flatbuffers::Verifiable for UnsignedBitOffset { diff --git a/rust/gen_flatbuffers/type_bin/void_generated.rs b/rust/src/gen_flatbuffers/type_bin/void_generated.rs similarity index 100% rename from rust/gen_flatbuffers/type_bin/void_generated.rs rename to rust/src/gen_flatbuffers/type_bin/void_generated.rs diff --git a/rust/src/gen_flatbuffers/warp/chunk_generated.rs b/rust/src/gen_flatbuffers/warp/chunk_generated.rs new file mode 100644 index 0000000..7f83105 --- /dev/null +++ b/rust/src/gen_flatbuffers/warp/chunk_generated.rs @@ -0,0 +1,126 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum ChunkOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct Chunk<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Chunk<'a> { + type Inner = Chunk<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> Chunk<'a> { + pub const VT_HEADER: flatbuffers::VOffsetT = 4; + pub const VT_DATA: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Chunk { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args ChunkArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = ChunkBuilder::new(_fbb); + if let Some(x) = args.data { builder.add_data(x); } + if let Some(x) = args.header { builder.add_header(x); } + builder.finish() + } + + + #[inline] + pub fn header(&self) -> ChunkHeader<'a> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(Chunk::VT_HEADER, None).unwrap()} + } + #[inline] + pub fn data(&self) -> Option> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(Chunk::VT_DATA, None)} + } +} + +impl flatbuffers::Verifiable for Chunk<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>("header", Self::VT_HEADER, true)? + .visit_field::>>("data", Self::VT_DATA, false)? + .finish(); + Ok(()) + } +} +pub struct ChunkArgs<'a> { + pub header: Option>>, + pub data: Option>>, +} +impl<'a> Default for ChunkArgs<'a> { + #[inline] + fn default() -> Self { + ChunkArgs { + header: None, // required field + data: None, + } + } +} + +pub struct ChunkBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ChunkBuilder<'a, 'b, A> { + #[inline] + pub fn add_header(&mut self, header: flatbuffers::WIPOffset>) { + self.fbb_.push_slot_always::>(Chunk::VT_HEADER, header); + } + #[inline] + pub fn add_data(&mut self, data: flatbuffers::WIPOffset>) { + self.fbb_.push_slot_always::>(Chunk::VT_DATA, data); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ChunkBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + ChunkBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, Chunk::VT_HEADER,"header"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for Chunk<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("Chunk"); + ds.field("header", &self.header()); + ds.field("data", &self.data()); + ds.finish() + } +} diff --git a/rust/src/gen_flatbuffers/warp/chunk_header_generated.rs b/rust/src/gen_flatbuffers/warp/chunk_header_generated.rs new file mode 100644 index 0000000..c226b8e --- /dev/null +++ b/rust/src/gen_flatbuffers/warp/chunk_header_generated.rs @@ -0,0 +1,176 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum ChunkHeaderOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct ChunkHeader<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for ChunkHeader<'a> { + type Inner = ChunkHeader<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> ChunkHeader<'a> { + pub const VT_VERSION: flatbuffers::VOffsetT = 4; + pub const VT_TYPE_: flatbuffers::VOffsetT = 6; + pub const VT_COMPRESSION_TYPE: flatbuffers::VOffsetT = 8; + pub const VT_SIZE: flatbuffers::VOffsetT = 10; + pub const VT_TARGET: flatbuffers::VOffsetT = 12; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + ChunkHeader { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args ChunkHeaderArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = ChunkHeaderBuilder::new(_fbb); + if let Some(x) = args.target { builder.add_target(x); } + builder.add_size(args.size); + builder.add_version(args.version); + builder.add_compression_type(args.compression_type); + builder.add_type_(args.type_); + builder.finish() + } + + + #[inline] + pub fn version(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(ChunkHeader::VT_VERSION, Some(0)).unwrap()} + } + #[inline] + pub fn type_(&self) -> ChunkType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(ChunkHeader::VT_TYPE_, Some(ChunkType::Signatures)).unwrap()} + } + #[inline] + pub fn compression_type(&self) -> CompressionType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(ChunkHeader::VT_COMPRESSION_TYPE, Some(CompressionType::None)).unwrap()} + } + #[inline] + pub fn size(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(ChunkHeader::VT_SIZE, Some(0)).unwrap()} + } + #[inline] + pub fn target(&self) -> Option> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(ChunkHeader::VT_TARGET, None)} + } +} + +impl flatbuffers::Verifiable for ChunkHeader<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("version", Self::VT_VERSION, false)? + .visit_field::("type_", Self::VT_TYPE_, false)? + .visit_field::("compression_type", Self::VT_COMPRESSION_TYPE, false)? + .visit_field::("size", Self::VT_SIZE, false)? + .visit_field::>("target", Self::VT_TARGET, false)? + .finish(); + Ok(()) + } +} +pub struct ChunkHeaderArgs<'a> { + pub version: u16, + pub type_: ChunkType, + pub compression_type: CompressionType, + pub size: u32, + pub target: Option>>, +} +impl<'a> Default for ChunkHeaderArgs<'a> { + #[inline] + fn default() -> Self { + ChunkHeaderArgs { + version: 0, + type_: ChunkType::Signatures, + compression_type: CompressionType::None, + size: 0, + target: None, + } + } +} + +pub struct ChunkHeaderBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ChunkHeaderBuilder<'a, 'b, A> { + #[inline] + pub fn add_version(&mut self, version: u16) { + self.fbb_.push_slot::(ChunkHeader::VT_VERSION, version, 0); + } + #[inline] + pub fn add_type_(&mut self, type_: ChunkType) { + self.fbb_.push_slot::(ChunkHeader::VT_TYPE_, type_, ChunkType::Signatures); + } + #[inline] + pub fn add_compression_type(&mut self, compression_type: CompressionType) { + self.fbb_.push_slot::(ChunkHeader::VT_COMPRESSION_TYPE, compression_type, CompressionType::None); + } + #[inline] + pub fn add_size(&mut self, size: u32) { + self.fbb_.push_slot::(ChunkHeader::VT_SIZE, size, 0); + } + #[inline] + pub fn add_target(&mut self, target: flatbuffers::WIPOffset>) { + self.fbb_.push_slot_always::>(ChunkHeader::VT_TARGET, target); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ChunkHeaderBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + ChunkHeaderBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for ChunkHeader<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("ChunkHeader"); + ds.field("version", &self.version()); + ds.field("type_", &self.type_()); + ds.field("compression_type", &self.compression_type()); + ds.field("size", &self.size()); + ds.field("target", &self.target()); + ds.finish() + } +} diff --git a/rust/src/gen_flatbuffers/warp/chunk_type_generated.rs b/rust/src/gen_flatbuffers/warp/chunk_type_generated.rs new file mode 100644 index 0000000..4b37cbd --- /dev/null +++ b/rust/src/gen_flatbuffers/warp/chunk_type_generated.rs @@ -0,0 +1,96 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_CHUNK_TYPE: u8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_CHUNK_TYPE: u8 = 1; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_CHUNK_TYPE: [ChunkType; 2] = [ + ChunkType::Signatures, + ChunkType::Types, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct ChunkType(pub u8); +#[allow(non_upper_case_globals)] +impl ChunkType { + pub const Signatures: Self = Self(0); + pub const Types: Self = Self(1); + + pub const ENUM_MIN: u8 = 0; + pub const ENUM_MAX: u8 = 1; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::Signatures, + Self::Types, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::Signatures => Some("Signatures"), + Self::Types => Some("Types"), + _ => None, + } + } +} +impl core::fmt::Debug for ChunkType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for ChunkType { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); + Self(b) + } +} + +impl flatbuffers::Push for ChunkType { + type Output = ChunkType; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.0); + } +} + +impl flatbuffers::EndianScalar for ChunkType { + type Scalar = u8; + #[inline] + fn to_little_endian(self) -> u8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: u8) -> Self { + let b = u8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for ChunkType { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + u8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for ChunkType {} diff --git a/rust/gen_flatbuffers/type_bin/type_modifier_class_generated.rs b/rust/src/gen_flatbuffers/warp/compression_type_generated.rs similarity index 56% rename from rust/gen_flatbuffers/type_bin/type_modifier_class_generated.rs rename to rust/src/gen_flatbuffers/warp/compression_type_generated.rs index 611ac89..5928a82 100644 --- a/rust/gen_flatbuffers/type_bin/type_modifier_class_generated.rs +++ b/rust/src/gen_flatbuffers/warp/compression_type_generated.rs @@ -10,52 +10,40 @@ use core::cmp::Ordering; use self::flatbuffers::{EndianScalar, Follow}; use super::*; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] -pub const ENUM_MIN_TYPE_MODIFIER_CLASS: u8 = 0; +pub const ENUM_MIN_COMPRESSION_TYPE: u8 = 0; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] -pub const ENUM_MAX_TYPE_MODIFIER_CLASS: u8 = 4; +pub const ENUM_MAX_COMPRESSION_TYPE: u8 = 1; #[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] #[allow(non_camel_case_types)] -pub const ENUM_VALUES_TYPE_MODIFIER_CLASS: [TypeModifierClass; 5] = [ - TypeModifierClass::NONE, - TypeModifierClass::ConstantModifierClass, - TypeModifierClass::VolatileModifierClass, - TypeModifierClass::DescriptorModifierClass, - TypeModifierClass::MetadataModifierClass, +pub const ENUM_VALUES_COMPRESSION_TYPE: [CompressionType; 2] = [ + CompressionType::None, + CompressionType::Zstd, ]; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[repr(transparent)] -pub struct TypeModifierClass(pub u8); +pub struct CompressionType(pub u8); #[allow(non_upper_case_globals)] -impl TypeModifierClass { - pub const NONE: Self = Self(0); - pub const ConstantModifierClass: Self = Self(1); - pub const VolatileModifierClass: Self = Self(2); - pub const DescriptorModifierClass: Self = Self(3); - pub const MetadataModifierClass: Self = Self(4); +impl CompressionType { + pub const None: Self = Self(0); + pub const Zstd: Self = Self(1); pub const ENUM_MIN: u8 = 0; - pub const ENUM_MAX: u8 = 4; + pub const ENUM_MAX: u8 = 1; pub const ENUM_VALUES: &'static [Self] = &[ - Self::NONE, - Self::ConstantModifierClass, - Self::VolatileModifierClass, - Self::DescriptorModifierClass, - Self::MetadataModifierClass, + Self::None, + Self::Zstd, ]; /// Returns the variant's name or "" if unknown. pub fn variant_name(self) -> Option<&'static str> { match self { - Self::NONE => Some("NONE"), - Self::ConstantModifierClass => Some("ConstantModifierClass"), - Self::VolatileModifierClass => Some("VolatileModifierClass"), - Self::DescriptorModifierClass => Some("DescriptorModifierClass"), - Self::MetadataModifierClass => Some("MetadataModifierClass"), + Self::None => Some("None"), + Self::Zstd => Some("Zstd"), _ => None, } } } -impl core::fmt::Debug for TypeModifierClass { +impl core::fmt::Debug for CompressionType { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { if let Some(name) = self.variant_name() { f.write_str(name) @@ -64,7 +52,7 @@ impl core::fmt::Debug for TypeModifierClass { } } } -impl<'a> flatbuffers::Follow<'a> for TypeModifierClass { +impl<'a> flatbuffers::Follow<'a> for CompressionType { type Inner = Self; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { @@ -73,15 +61,15 @@ impl<'a> flatbuffers::Follow<'a> for TypeModifierClass { } } -impl flatbuffers::Push for TypeModifierClass { - type Output = TypeModifierClass; +impl flatbuffers::Push for CompressionType { + type Output = CompressionType; #[inline] unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { flatbuffers::emplace_scalar::(dst, self.0); } } -impl flatbuffers::EndianScalar for TypeModifierClass { +impl flatbuffers::EndianScalar for CompressionType { type Scalar = u8; #[inline] fn to_little_endian(self) -> u8 { @@ -95,7 +83,7 @@ impl flatbuffers::EndianScalar for TypeModifierClass { } } -impl<'a> flatbuffers::Verifiable for TypeModifierClass { +impl<'a> flatbuffers::Verifiable for CompressionType { #[inline] fn run_verifier( v: &mut flatbuffers::Verifier, pos: usize @@ -105,6 +93,4 @@ impl<'a> flatbuffers::Verifiable for TypeModifierClass { } } -impl flatbuffers::SimpleToVerifyInSlice for TypeModifierClass {} -pub struct TypeModifierClassUnionTableOffset {} - +impl flatbuffers::SimpleToVerifyInSlice for CompressionType {} diff --git a/rust/src/gen_flatbuffers/warp/file_generated.rs b/rust/src/gen_flatbuffers/warp/file_generated.rs new file mode 100644 index 0000000..61e9dfc --- /dev/null +++ b/rust/src/gen_flatbuffers/warp/file_generated.rs @@ -0,0 +1,211 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// @generated +extern crate alloc; +extern crate flatbuffers; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::mem; +use core::cmp::Ordering; +use self::flatbuffers::{EndianScalar, Follow}; +use super::*; +pub enum FileOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct File<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for File<'a> { + type Inner = File<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> File<'a> { + pub const VT_HEADER: flatbuffers::VOffsetT = 4; + pub const VT_CHUNKS: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + File { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args FileArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = FileBuilder::new(_fbb); + if let Some(x) = args.chunks { builder.add_chunks(x); } + if let Some(x) = args.header { builder.add_header(x); } + builder.finish() + } + + + #[inline] + pub fn header(&self) -> FileHeader<'a> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(File::VT_HEADER, None).unwrap()} + } + #[inline] + pub fn chunks(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(File::VT_CHUNKS, None)} + } +} + +impl flatbuffers::Verifiable for File<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>("header", Self::VT_HEADER, true)? + .visit_field::>>>("chunks", Self::VT_CHUNKS, false)? + .finish(); + Ok(()) + } +} +pub struct FileArgs<'a> { + pub header: Option>>, + pub chunks: Option>>>>, +} +impl<'a> Default for FileArgs<'a> { + #[inline] + fn default() -> Self { + FileArgs { + header: None, // required field + chunks: None, + } + } +} + +pub struct FileBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FileBuilder<'a, 'b, A> { + #[inline] + pub fn add_header(&mut self, header: flatbuffers::WIPOffset>) { + self.fbb_.push_slot_always::>(File::VT_HEADER, header); + } + #[inline] + pub fn add_chunks(&mut self, chunks: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(File::VT_CHUNKS, chunks); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FileBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + FileBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + self.fbb_.required(o, File::VT_HEADER,"header"); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for File<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("File"); + ds.field("header", &self.header()); + ds.field("chunks", &self.chunks()); + ds.finish() + } +} +#[inline] +/// Verifies that a buffer of bytes contains a `File` +/// and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_file_unchecked`. +pub fn root_as_file(buf: &[u8]) -> Result { + flatbuffers::root::(buf) +} +#[inline] +/// Verifies that a buffer of bytes contains a size prefixed +/// `File` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `size_prefixed_root_as_file_unchecked`. +pub fn size_prefixed_root_as_file(buf: &[u8]) -> Result { + flatbuffers::size_prefixed_root::(buf) +} +#[inline] +/// Verifies, with the given options, that a buffer of bytes +/// contains a `File` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_file_unchecked`. +pub fn root_as_file_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::root_with_opts::>(opts, buf) +} +#[inline] +/// Verifies, with the given verifier options, that a buffer of +/// bytes contains a size prefixed `File` and returns +/// it. Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_file_unchecked`. +pub fn size_prefixed_root_as_file_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::size_prefixed_root_with_opts::>(opts, buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a File and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid `File`. +pub unsafe fn root_as_file_unchecked(buf: &[u8]) -> File { + flatbuffers::root_unchecked::(buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a size prefixed File and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid size prefixed `File`. +pub unsafe fn size_prefixed_root_as_file_unchecked(buf: &[u8]) -> File { + flatbuffers::size_prefixed_root_unchecked::(buf) +} +pub const FILE_IDENTIFIER: &str = "WARP"; + +#[inline] +pub fn file_buffer_has_identifier(buf: &[u8]) -> bool { + flatbuffers::buffer_has_identifier(buf, FILE_IDENTIFIER, false) +} + +#[inline] +pub fn file_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { + flatbuffers::buffer_has_identifier(buf, FILE_IDENTIFIER, true) +} + +pub const FILE_EXTENSION: &str = "warp"; + +#[inline] +pub fn finish_file_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + root: flatbuffers::WIPOffset>) { + fbb.finish(root, Some(FILE_IDENTIFIER)); +} + +#[inline] +pub fn finish_size_prefixed_file_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { + fbb.finish_size_prefixed(root, Some(FILE_IDENTIFIER)); +} diff --git a/rust/gen_flatbuffers/type_bin/fixed_alignment_generated.rs b/rust/src/gen_flatbuffers/warp/file_header_generated.rs similarity index 54% rename from rust/gen_flatbuffers/type_bin/fixed_alignment_generated.rs rename to rust/src/gen_flatbuffers/warp/file_header_generated.rs index e63b445..04abe6f 100644 --- a/rust/gen_flatbuffers/type_bin/fixed_alignment_generated.rs +++ b/rust/src/gen_flatbuffers/warp/file_header_generated.rs @@ -9,100 +9,100 @@ use core::mem; use core::cmp::Ordering; use self::flatbuffers::{EndianScalar, Follow}; use super::*; -pub enum FixedAlignmentOffset {} +pub enum FileHeaderOffset {} #[derive(Copy, Clone, PartialEq)] -pub struct FixedAlignment<'a> { +pub struct FileHeader<'a> { pub _tab: flatbuffers::Table<'a>, } -impl<'a> flatbuffers::Follow<'a> for FixedAlignment<'a> { - type Inner = FixedAlignment<'a>; +impl<'a> flatbuffers::Follow<'a> for FileHeader<'a> { + type Inner = FileHeader<'a>; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { Self { _tab: flatbuffers::Table::new(buf, loc) } } } -impl<'a> FixedAlignment<'a> { - pub const VT_WIDTH: flatbuffers::VOffsetT = 4; +impl<'a> FileHeader<'a> { + pub const VT_VERSION: flatbuffers::VOffsetT = 4; #[inline] pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - FixedAlignment { _tab: table } + FileHeader { _tab: table } } #[allow(unused_mut)] pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args FixedAlignmentArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = FixedAlignmentBuilder::new(_fbb); - if let Some(x) = args.width { builder.add_width(x); } + args: &'args FileHeaderArgs + ) -> flatbuffers::WIPOffset> { + let mut builder = FileHeaderBuilder::new(_fbb); + builder.add_version(args.version); builder.finish() } #[inline] - pub fn width(&self) -> Option<&'a BitWidth> { + pub fn version(&self) -> u16 { // Safety: // Created from valid Table for this object // which contains a valid value in this slot - unsafe { self._tab.get::(FixedAlignment::VT_WIDTH, None)} + unsafe { self._tab.get::(FileHeader::VT_VERSION, Some(0)).unwrap()} } } -impl flatbuffers::Verifiable for FixedAlignment<'_> { +impl flatbuffers::Verifiable for FileHeader<'_> { #[inline] fn run_verifier( v: &mut flatbuffers::Verifier, pos: usize ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::("width", Self::VT_WIDTH, false)? + .visit_field::("version", Self::VT_VERSION, false)? .finish(); Ok(()) } } -pub struct FixedAlignmentArgs<'a> { - pub width: Option<&'a BitWidth>, +pub struct FileHeaderArgs { + pub version: u16, } -impl<'a> Default for FixedAlignmentArgs<'a> { +impl<'a> Default for FileHeaderArgs { #[inline] fn default() -> Self { - FixedAlignmentArgs { - width: None, + FileHeaderArgs { + version: 0, } } } -pub struct FixedAlignmentBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { +pub struct FileHeaderBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FixedAlignmentBuilder<'a, 'b, A> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> FileHeaderBuilder<'a, 'b, A> { #[inline] - pub fn add_width(&mut self, width: &BitWidth) { - self.fbb_.push_slot_always::<&BitWidth>(FixedAlignment::VT_WIDTH, width); + pub fn add_version(&mut self, version: u16) { + self.fbb_.push_slot::(FileHeader::VT_VERSION, version, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FixedAlignmentBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> FileHeaderBuilder<'a, 'b, A> { let start = _fbb.start_table(); - FixedAlignmentBuilder { + FileHeaderBuilder { fbb_: _fbb, start_: start, } } #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { + pub fn finish(self) -> flatbuffers::WIPOffset> { let o = self.fbb_.end_table(self.start_); flatbuffers::WIPOffset::new(o.value()) } } -impl core::fmt::Debug for FixedAlignment<'_> { +impl core::fmt::Debug for FileHeader<'_> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("FixedAlignment"); - ds.field("width", &self.width()); + let mut ds = f.debug_struct("FileHeader"); + ds.field("version", &self.version()); ds.finish() } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 0000000..b27a28e --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,239 @@ +pub(crate) mod cached_builder; +pub mod chunk; +pub mod mock; +pub mod signature; +pub mod symbol; +pub mod target; +pub mod r#type; + +#[allow(warnings)] +#[rustfmt::skip] +mod gen_flatbuffers; + +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::chunk::Chunk; +use crate::signature::function::FunctionGUID; +use flatbuffers::{Follow, UnionWIPOffset, Verifiable, WIPOffset}; +use gen_flatbuffers::sig_bin as fb_sig; +use gen_flatbuffers::symbol_bin as fb_symbol; +use gen_flatbuffers::target_bin as fb_target; +use gen_flatbuffers::type_bin as fb_type; +use gen_flatbuffers::warp as fb_warp; +use std::fmt::{Debug, Display}; + +/// The current file version. +pub const FILE_VERSION: u16 = 1; + +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct WarpFileHeader { + pub version: u16, +} + +impl WarpFileHeader { + pub fn new() -> Self { + Self { + version: FILE_VERSION, + } + } +} + +impl Default for WarpFileHeader { + fn default() -> Self { + Self::new() + } +} + +impl FlatBufferObject for WarpFileHeader { + type FbType<'fbb> = fb_warp::FileHeader<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb_warp::FileHeader::create( + builder, + &fb_warp::FileHeaderArgs { + version: self.version, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + version: value.version(), + }) + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct WarpFile<'fbb> { + pub header: WarpFileHeader, + pub chunks: Vec>, +} + +impl<'fbb> WarpFile<'fbb> { + pub fn new(header: WarpFileHeader, chunks: Vec>) -> Self { + Self { header, chunks } + } + + // TODO: This is a little bad, is there any way we can "stream" the file? We can stream the chunks. + // TODO: I just need to figure out how the reader and writer streams for pdb and dwarf work in rust. + + pub fn to_owned(&self) -> Self { + Self { + header: self.header.clone(), + chunks: self.chunks.iter().map(|c| c.to_owned()).collect(), + } + } + + pub fn from_bytes(bytes: &'fbb [u8]) -> Option { + let object = flatbuffers::root::(bytes).ok()?; + Self::from_object(&object) + } + + pub fn from_owned_bytes(bytes: Vec) -> Option { + let object = flatbuffers::root::(&bytes).ok()?; + Self::from_owned_object(&object) + } + + pub fn to_bytes(&self) -> Vec { + let mut builder = CachedFlatBufferBuilder::new(); + let root = self.create(&mut builder); + builder.finish_minimal(root); + builder.finished_data().to_vec() + } + + fn create( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let header = self.header.create(builder); + let _chunks: Vec<_> = self + .chunks + .iter() + .flat_map(|c| c.create_object(builder)) + .collect(); + let chunks = builder.create_vector(&_chunks); + fb_warp::File::create( + builder, + &fb_warp::FileArgs { + header: Some(header), + chunks: Some(chunks), + }, + ) + } + + fn from_object(value: &fb_warp::File<'fbb>) -> Option { + let _chunks = value.chunks()?; + let chunks = _chunks + .iter() + .flat_map(|c| Chunk::from_object(&c)) + .collect(); + Some(Self { + header: WarpFileHeader::from_object(&value.header())?, + chunks, + }) + } + + fn from_owned_object(value: &fb_warp::File) -> Option { + let _chunks = value.chunks()?; + let chunks = _chunks + .iter() + .flat_map(|c| Chunk::from_owned_object(&c)) + .collect(); + Some(Self { + header: WarpFileHeader::from_object(&value.header())?, + chunks, + }) + } +} + +pub(crate) trait FlatBufferObject: Sized { + type FbType<'fbb>: Follow<'fbb> + Verifiable; + + /// Construct the flat buffer object that [`Self`] represents within the given [`CachedFlatBufferBuilder`]. + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset>; + + #[allow(dead_code)] + fn to_bytes(&self) -> Vec { + let mut builder = CachedFlatBufferBuilder::new(); + let root = self.create(&mut builder); + builder.finish_minimal(root); + builder.finished_data().to_vec() + } + + fn from_object(value: &Self::FbType<'_>) -> Option; +} + +pub(crate) trait FlatBufferUnion { + fn create(&self, builder: &mut CachedFlatBufferBuilder) -> WIPOffset; +} + +impl From for gen_flatbuffers::type_bin::BitWidth { + fn from(value: u16) -> Self { + Self::new(value) + } +} + +impl From<&gen_flatbuffers::type_bin::BitWidth> for u16 { + fn from(value: &gen_flatbuffers::type_bin::BitWidth) -> Self { + value.value() + } +} + +impl From for gen_flatbuffers::type_bin::BitSize { + fn from(value: u64) -> Self { + Self::new(value) + } +} + +impl From<&gen_flatbuffers::type_bin::BitSize> for u64 { + fn from(value: &gen_flatbuffers::type_bin::BitSize) -> Self { + value.value() + } +} + +impl From for gen_flatbuffers::type_bin::UnsignedBitOffset { + fn from(value: u64) -> Self { + Self::new(value) + } +} + +impl From<&gen_flatbuffers::type_bin::UnsignedBitOffset> for u64 { + fn from(value: &gen_flatbuffers::type_bin::UnsignedBitOffset) -> Self { + value.value() + } +} + +impl From for gen_flatbuffers::type_bin::BitOffset { + fn from(value: i64) -> Self { + Self::new(value) + } +} + +impl From<&gen_flatbuffers::type_bin::BitOffset> for i64 { + fn from(value: &gen_flatbuffers::type_bin::BitOffset) -> Self { + value.value() + } +} + +impl From for gen_flatbuffers::type_bin::BitShift { + fn from(value: i64) -> Self { + Self::new(value) + } +} + +impl From<&gen_flatbuffers::type_bin::BitShift> for i64 { + fn from(value: &gen_flatbuffers::type_bin::BitShift) -> Self { + value.value() + } +} + +impl Display for gen_flatbuffers::sig_bin::FunctionGUID { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", FunctionGUID::from(*self)) + } +} diff --git a/rust/src/mock.rs b/rust/src/mock.rs new file mode 100644 index 0000000..1bbad3f --- /dev/null +++ b/rust/src/mock.rs @@ -0,0 +1,183 @@ +//! Mocking functions to help with testing + +use crate::r#type::class::function::{Location, StackLocation}; +use crate::r#type::class::{ + ArrayClass, BooleanClass, CharacterClass, EnumerationClass, EnumerationMember, FloatClass, + FunctionClass, IntegerClass, PointerClass, ReferrerClass, StructureClass, StructureMember, + TypeClass, UnionClass, UnionMember, +}; +use crate::r#type::guid::TypeGUID; +use crate::r#type::{Type, TypeMetadata}; +use crate::signature::comment::FunctionComment; +use crate::signature::constraint::{Constraint, ConstraintGUID}; +use crate::signature::function::{Function, FunctionGUID}; +use crate::signature::variable::FunctionVariable; +use crate::symbol::{Symbol, SymbolClass}; + +/// Computes the function guid from the given magic string. +pub fn mock_function_guid(magic: &str) -> FunctionGUID { + FunctionGUID::from(magic.as_bytes()) +} + +pub fn mock_constraint_guid(magic: &str) -> ConstraintGUID { + ConstraintGUID::from(magic.as_bytes()) +} + +pub fn mock_constraint(magic: &str, offset: Option) -> Constraint { + Constraint { + guid: mock_constraint_guid(magic), + offset, + } +} + +pub fn mock_symbol(magic: &str, class: SymbolClass) -> Symbol { + Symbol { + name: magic.to_string(), + modifiers: Default::default(), + class, + } +} + +pub fn mock_function_type_class() -> TypeClass { + TypeClass::Function(FunctionClass { + calling_convention: None, + in_members: vec![], + out_members: vec![], + }) +} + +pub fn mock_int_type_class(width: Option, signed: bool) -> TypeClass { + TypeClass::Integer(IntegerClass { width, signed }) +} + +pub fn mock_bool_type_class() -> TypeClass { + TypeClass::Boolean(BooleanClass { width: None }) +} + +pub fn mock_void_type_class() -> TypeClass { + TypeClass::Void +} + +pub fn mock_char_type_class(width: Option) -> TypeClass { + TypeClass::Character(CharacterClass { width }) +} + +pub fn mock_float_type_class(width: Option) -> TypeClass { + TypeClass::Float(FloatClass { width }) +} + +pub fn mock_array_type_class(member_ty: &Type, len: u64) -> TypeClass { + TypeClass::Array(ArrayClass { + length: Some(len), + member_type: Box::new(member_ty.clone()), + modifiers: Default::default(), + }) +} + +pub fn mock_struct_type_class(members: &[(u64, &str, &Type)]) -> TypeClass { + TypeClass::Structure(StructureClass { + members: members + .iter() + .map(|&(offset, name, ty)| StructureMember { + name: Some(name.to_string()), + offset, + ty: Box::new(ty.clone()), + modifiers: Default::default(), + }) + .collect(), + }) +} + +pub fn mock_enum_type_class(member_ty: &Type, members: &[(&str, u64)]) -> TypeClass { + TypeClass::Enumeration(EnumerationClass { + member_type: Box::new(member_ty.clone()), + members: members + .iter() + .map(|&(name, constant)| EnumerationMember { + name: Some(name.to_string()), + constant, + }) + .collect(), + }) +} + +pub fn mock_union_type_class(members: &[(&str, &Type)]) -> TypeClass { + TypeClass::Union(UnionClass { + members: members + .iter() + .map(|&(name, ty)| UnionMember { + name: name.to_string(), + ty: Box::new(ty.clone()), + }) + .collect(), + }) +} + +pub fn mock_ptr_type_class(child_ty: &Type, width: Option) -> TypeClass { + TypeClass::Pointer(PointerClass { + width, + child_type: Box::new(child_ty.clone()), + addressing: Default::default(), + }) +} + +pub fn mock_ref_type_class(guid: Option, name: Option) -> TypeClass { + TypeClass::Referrer(ReferrerClass { guid, name }) +} + +pub fn mock_guid_ref_type_class(guid: TypeGUID) -> TypeClass { + mock_ref_type_class(Some(guid), None) +} + +pub fn mock_name_ref_type_class(name: String) -> TypeClass { + mock_ref_type_class(None, Some(name)) +} + +pub fn mock_type_ref_type_class(ref_ty: &Type) -> TypeClass { + let guid = TypeGUID::from(ref_ty); + let name = ref_ty.name.clone(); + mock_ref_type_class(Some(guid), name) +} + +pub fn mock_type(magic: &str, class: TypeClass) -> Type { + Type { + name: Some(magic.to_string()), + class, + confidence: 255, + modifiers: Default::default(), + metadata: vec![], + alignment: Default::default(), + ancestors: vec![], + } +} + +pub fn mock_type_metadata(magic: &str) -> TypeMetadata { + TypeMetadata::new_string(magic.to_string(), magic.to_string()) +} + +pub fn mock_function_comment(magic: &str) -> FunctionComment { + FunctionComment { + offset: 0, + text: magic.to_string(), + } +} + +pub fn mock_function_variable(magic: &str) -> FunctionVariable { + FunctionVariable { + offset: 0, + location: Location::Stack(StackLocation { offset: 0 }), + name: Some(magic.to_string()), + ty: None, + } +} + +pub fn mock_function(magic: &str) -> Function { + Function { + guid: mock_function_guid(magic), + symbol: mock_symbol(magic, SymbolClass::Function), + ty: Some(mock_type(magic, mock_function_type_class())), + constraints: Default::default(), + comments: Default::default(), + variables: Default::default(), + } +} diff --git a/rust/src/signature.rs b/rust/src/signature.rs new file mode 100644 index 0000000..36f659e --- /dev/null +++ b/rust/src/signature.rs @@ -0,0 +1,6 @@ +pub mod basic_block; +pub mod chunk; +pub mod comment; +pub mod constraint; +pub mod function; +pub mod variable; diff --git a/rust/signature/basic_block.rs b/rust/src/signature/basic_block.rs similarity index 53% rename from rust/signature/basic_block.rs rename to rust/src/signature/basic_block.rs index 72750a0..75db4af 100644 --- a/rust/signature/basic_block.rs +++ b/rust/src/signature/basic_block.rs @@ -1,5 +1,6 @@ -use crate::fb_sig as fb; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_sig as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; use std::fmt::{Display, Formatter}; use std::str::FromStr; use uuid::uuid; @@ -7,6 +8,8 @@ use uuid::Uuid; pub const NAMESPACE_BASICBLOCK: Uuid = uuid!("0192a178-7a5f-7936-8653-3cbaa7d6afe7"); +/// This type is marked `repr(transparent)` to the underlying `[u8; 16]` type, so it is safe to use in FFI. +#[repr(transparent)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct BasicBlockGUID { guid: Uuid, @@ -40,6 +43,20 @@ impl From for BasicBlockGUID { } } +impl From for BasicBlockGUID { + fn from(value: fb::BasicBlockGUID) -> Self { + Self { + guid: Uuid::from_bytes(value.0), + } + } +} + +impl From for fb::BasicBlockGUID { + fn from(value: BasicBlockGUID) -> Self { + Self(value.guid.into_bytes()) + } +} + impl Display for BasicBlockGUID { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.guid, f) @@ -56,32 +73,33 @@ impl BasicBlock { Self { guid } } - // TODO: Error checking... pub fn from_bytes(buf: &[u8]) -> Option { flatbuffers::root::(buf) .ok() - .map(Into::into) + .and_then(|b| BasicBlock::from_object(&b)) } +} - pub fn to_bytes(&self) -> Vec { - let mut builder = FlatBufferBuilder::new(); - let fb_bb = self.create(&mut builder); - builder.finish_minimal(fb_bb); - builder.finished_data().to_vec() - } +impl FlatBufferObject for BasicBlock { + type FbType<'fbb> = fb::BasicBlock<'fbb>; - pub(crate) fn create<'a>( + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let guid = builder.create_string(&self.guid.to_string()); - fb::BasicBlock::create(builder, &fb::BasicBlockArgs { guid: Some(guid) }) + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::BasicBlock::create( + builder, + &fb::BasicBlockArgs { + guid: Some(&self.guid.into()), + }, + ) } -} -impl From> for BasicBlock { - fn from(value: fb::BasicBlock<'_>) -> Self { - let guid = value.guid().parse::().unwrap(); - Self { guid } + fn from_object(value: &Self::FbType<'_>) -> Option { + let bb = Self { + guid: BasicBlockGUID::from(*value.guid()), + }; + + Some(bb) } } diff --git a/rust/src/signature/chunk.rs b/rust/src/signature/chunk.rs new file mode 100644 index 0000000..f9e5ae9 --- /dev/null +++ b/rust/src/signature/chunk.rs @@ -0,0 +1,186 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::chunk::ChunkHandler; +use crate::fb_sig as fb; +use crate::signature::function::{Function, FunctionGUID}; +use crate::FlatBufferObject; +use flatbuffers::VerifierOptions; +use std::borrow::Cow; +use std::collections::HashMap; +use std::fmt::Debug; +// TODO: Rename 'fbb to 'a the lifetime is no longer tied to the flatbuffer builder. + +#[derive(Clone, PartialEq)] +pub struct SignatureChunk<'fbb> { + buffer: Cow<'fbb, [u8]>, + lookup: HashMap>, +} + +impl<'fbb> SignatureChunk<'fbb> { + /// Construct a [`SignatureChunk`] using the provided [`CachedFlatBufferBuilder`] and [`Function`] list. + pub fn new(functions: &[Function]) -> Option> { + let mut builder = CachedFlatBufferBuilder::new(); + // Build the new flatbuffer signature chunk from the given functions. + let _functions: Vec<_> = functions.iter().map(|f| f.create(&mut builder)).collect(); + let functions = builder.create_vector(&_functions); + let chunk = fb::SignatureChunk::create( + &mut builder, + &fb::SignatureChunkArgs { + functions: Some(functions), + }, + ); + + // Round-trip the flatbuffer signature chunk back to a SignatureChunk. + // NOTE: The returned SignatureChunk does not own the underlying buffer, we clone it to avoid annoying lifetime issues. + builder.finish_minimal(chunk); + let chunk_data = builder.finished_data().to_vec(); + SignatureChunk::from_data(Cow::Owned(chunk_data)) + } + + /// Builds the lookup table for function guids. + /// + /// NOTE: Called when constructing the chunk in [`SignatureChunk::from_data`]. + fn build_lookup(&mut self) { + self.lookup = self + .raw_functions() + .enumerate() + .fold(HashMap::new(), |mut acc, (idx, f)| { + let guid = FunctionGUID::from(*f.guid()); + acc.entry(guid).or_default().push(idx); + acc + }); + } + + fn get_raw_function(&self, idx: usize) -> Option { + if idx >= self.object().functions().len() { + return None; + } + Some(self.object().functions().get(idx)) + } + + pub fn object(&self) -> fb::SignatureChunk { + // SAFETY: We have already verified the buffer. + unsafe { fb::root_as_signature_chunk_unchecked(&self.buffer) } + } + + pub fn raw_functions(&self) -> impl Iterator> + '_ { + self.object().functions().iter() + } + + /// Retrieve all functions as an owned [`Function`]. + /// + /// This function should not be used in hot paths, instead use [`SignatureChunk::raw_functions`] + /// which you should then filter functions off of before creating an owned [`Function`]. An example + /// of a function that does this is [`SignatureChunk::functions_with_guid`]. + pub fn functions(&self) -> impl Iterator + '_ { + self.raw_functions().flat_map(|f| Function::from_object(&f)) + } + + pub fn raw_functions_with_guid<'a>( + &'a self, + guid: &FunctionGUID, + ) -> impl Iterator> + 'a { + self.lookup + .get(guid) + .cloned() + .unwrap_or_default() + .into_iter() + .filter_map(|idx| self.get_raw_function(idx)) + } + + pub fn functions_with_guid<'a>( + &'a self, + guid: &FunctionGUID, + ) -> impl Iterator + 'a { + self.raw_functions_with_guid(guid) + .flat_map(|f| Function::from_object(&f)) + } + + pub fn from_owned_data(data: Vec) -> Option { + Self::from_data(Cow::Owned(data)) + } + + // TODO: Other types of lookups: by symbol, by constraints, by type? +} + +impl Debug for SignatureChunk<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let functions: Vec<_> = self.functions().collect(); + f.debug_struct("SignatureChunk") + .field("functions", &functions) + .finish() + } +} + +impl<'fbb> ChunkHandler<'fbb> for SignatureChunk<'fbb> { + const VERSION: u16 = 0; + + fn from_data(data: Cow<'fbb, [u8]>) -> Option { + // We must verify the buffer before we can create a SignatureChunk. + // See SignatureChunk::object for more details. + let verify_opts = VerifierOptions { + max_tables: 10_000_000, + ..Default::default() + }; + let _verified_object = fb::root_as_signature_chunk_with_opts(&verify_opts, &data).ok()?; + let mut chunk = Self { + buffer: data, + lookup: HashMap::new(), + }; + chunk.build_lookup(); + Some(chunk) + } + + fn merge(chunks: &[Self]) -> Option { + let mut functions: Vec<_> = chunks.iter().flat_map(|c| c.functions()).collect(); + // First sort by name, this will get us in the "perceived" order, useful for users. + // Second sort by guid, this will get us in the "dedupe" order, useful for deduplicating. + functions.sort_unstable_by(|a, b| { + a.symbol + .name + .cmp(&b.symbol.name) + .then_with(|| a.guid.cmp(&b.guid)) + }); + functions.dedup_by(|a, b| { + // Different guid, we want to keep both. + if a.guid != b.guid || a.symbol.name != b.symbol.name { + return false; + } + + // Keep constraints from both functions. + // We assume this is the same function if they share the same name but different constraints. + // We assume the function is different if they both have a type and it differs. + match (&a.ty, &b.ty) { + (Some(a_ty), None) => { + // Copy over a's type as well, since b has no type. + b.ty = Some(a_ty.clone()); + b.constraints.extend(a.constraints.clone()); + true + } + (Some(a_ty), Some(b_ty)) => { + if a_ty == b_ty { + // Same type - merge constraints and deduplicate + b.constraints.extend(a.constraints.clone()); + true + } else { + false + } + } + (None, Some(_)) | (None, None) => { + b.constraints.extend(a.constraints.clone()); + true + } + } + }); + Self::new(&functions) + } + + fn size(&self) -> u32 { + self.buffer.len() as u32 + } +} + +impl AsRef<[u8]> for SignatureChunk<'_> { + fn as_ref(&self) -> &[u8] { + &self.buffer + } +} diff --git a/rust/src/signature/comment.rs b/rust/src/signature/comment.rs new file mode 100644 index 0000000..0953811 --- /dev/null +++ b/rust/src/signature/comment.rs @@ -0,0 +1,35 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::fb_sig as fb; +use crate::FlatBufferObject; +use flatbuffers::WIPOffset; + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] +pub struct FunctionComment { + pub offset: i64, + pub text: String, +} + +impl FlatBufferObject for FunctionComment { + type FbType<'fbb> = fb::FunctionComment<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let text = builder.create_string(&self.text); + fb::FunctionComment::create( + builder, + &fb::FunctionCommentArgs { + offset: self.offset, + text: Some(text), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + offset: value.offset(), + text: value.text().to_string(), + }) + } +} diff --git a/rust/src/signature/constraint.rs b/rust/src/signature/constraint.rs new file mode 100644 index 0000000..57dc33d --- /dev/null +++ b/rust/src/signature/constraint.rs @@ -0,0 +1,145 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::signature::function::FunctionGUID; +use crate::symbol::Symbol; +use crate::{fb_sig as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; +use uuid::{uuid, Uuid}; + +pub const NAMESPACE_CONSTRAINT: Uuid = uuid!("019701f3-e89c-7afa-9181-371a5e98a576"); + +/// For a [`Constraint`] which is unrelated (represented as `None`), we use [`i64::MAX`] when storing in the flatbuffer. +pub const UNRELATED_OFFSET: i64 = i64::MAX; + +/// This type is marked `repr(transparent)` to the underlying `[u8; 16]` type, so it is safe to use in FFI. +#[repr(transparent)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct ConstraintGUID { + pub guid: Uuid, +} + +impl ConstraintGUID { + // TODO: From value + // TODO: From string + + pub fn from_function_guid(guid: &FunctionGUID) -> Self { + // TODO: Should we prefix the bytes with some tag so that function guid cant collide with something else? + let guid = Uuid::new_v5(&NAMESPACE_CONSTRAINT, guid.as_bytes()); + ConstraintGUID { guid } + } + + pub fn from_symbol(symbol: &Symbol) -> Self { + // TODO: Should we prefix the bytes with some tag so that symbol cant collide with something else? + let guid = Uuid::new_v5(&NAMESPACE_CONSTRAINT, symbol.name.as_bytes()); + ConstraintGUID { guid } + } + + pub fn from_value(value: u64) -> Self { + // TODO: Should we prefix the bytes with some tag so that value cant collide with something else? + let guid = Uuid::new_v5(&NAMESPACE_CONSTRAINT, &value.to_le_bytes()); + ConstraintGUID { guid } + } +} + +impl FromStr for ConstraintGUID { + type Err = uuid::Error; + + fn from_str(s: &str) -> Result { + Uuid::parse_str(s).map(Into::into) + } +} + +impl TryFrom<&str> for ConstraintGUID { + type Error = uuid::Error; + + fn try_from(value: &str) -> Result { + Self::from_str(value) + } +} + +impl From<&[u8]> for ConstraintGUID { + fn from(value: &[u8]) -> Self { + Self { + guid: Uuid::new_v5(&NAMESPACE_CONSTRAINT, value), + } + } +} + +impl From for ConstraintGUID { + fn from(value: Uuid) -> Self { + Self { guid: value } + } +} + +impl From for ConstraintGUID { + fn from(value: fb::ConstraintGUID) -> Self { + Self { + guid: Uuid::from_bytes(value.0), + } + } +} + +impl From for fb::ConstraintGUID { + fn from(value: ConstraintGUID) -> Self { + Self(value.guid.into_bytes()) + } +} + +impl Display for ConstraintGUID { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.guid, f) + } +} + +// TODO: Add a wrapper container type for the hashset and provided helpers +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Constraint { + pub guid: ConstraintGUID, + pub offset: Option, +} + +impl Constraint { + pub fn from_function(guid: &FunctionGUID, offset: Option) -> Self { + Self { + guid: ConstraintGUID::from_function_guid(guid), + offset, + } + } + + pub fn from_symbol(symbol: &Symbol, offset: Option) -> Self { + Self { + guid: ConstraintGUID::from_symbol(symbol), + offset, + } + } +} + +impl FlatBufferObject for Constraint { + type FbType<'fbb> = fb::Constraint<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::Constraint::create( + builder, + &fb::ConstraintArgs { + guid: Some(&self.guid.into()), + offset: self.offset.unwrap_or(UNRELATED_OFFSET), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let constraint = Self { + guid: ConstraintGUID::from(*value.guid()), + offset: match value.offset() { + UNRELATED_OFFSET => None, + _ => Some(value.offset()), + }, + }; + + Some(constraint) + } +} diff --git a/rust/src/signature/function.rs b/rust/src/signature/function.rs new file mode 100644 index 0000000..1b8ab73 --- /dev/null +++ b/rust/src/signature/function.rs @@ -0,0 +1,195 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::r#type::Type; +use crate::signature::basic_block::BasicBlockGUID; +use crate::signature::comment::FunctionComment; +use crate::signature::constraint::Constraint; +use crate::signature::variable::FunctionVariable; +use crate::symbol::Symbol; +use crate::{fb_sig as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; +use std::collections::HashSet; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; +use uuid::{uuid, Uuid}; + +pub const NAMESPACE_FUNCTION: Uuid = uuid!("0192a179-61ac-7cef-88ed-012296e9492f"); + +/// This type is marked `repr(transparent)` to the underlying `[u8; 16]` type, so it is safe to use in FFI. +#[repr(transparent)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct FunctionGUID { + pub guid: Uuid, +} + +impl FunctionGUID { + pub fn from_basic_blocks(basic_blocks: &[BasicBlockGUID]) -> Self { + let basic_blocks_bytes = basic_blocks + .iter() + .fold(Vec::new(), |mut bytes: Vec, bb| { + bytes.extend(bb.as_bytes()); + bytes + }); + let guid = Uuid::new_v5(&NAMESPACE_FUNCTION, &basic_blocks_bytes); + FunctionGUID { guid } + } + + pub fn as_bytes(&self) -> &[u8] { + self.guid.as_bytes() + } +} + +impl FromStr for FunctionGUID { + type Err = uuid::Error; + + fn from_str(s: &str) -> Result { + Uuid::parse_str(s).map(Into::into) + } +} + +impl TryFrom<&str> for FunctionGUID { + type Error = uuid::Error; + + fn try_from(value: &str) -> Result { + Self::from_str(value) + } +} + +impl From<&[u8]> for FunctionGUID { + fn from(value: &[u8]) -> Self { + Self { + guid: Uuid::new_v5(&NAMESPACE_FUNCTION, value), + } + } +} + +impl From for FunctionGUID { + fn from(value: Uuid) -> Self { + Self { guid: value } + } +} + +impl From for FunctionGUID { + fn from(value: fb::FunctionGUID) -> Self { + Self { + guid: Uuid::from_bytes(value.0), + } + } +} + +impl From for fb::FunctionGUID { + fn from(value: FunctionGUID) -> Self { + Self(value.guid.into_bytes()) + } +} + +impl Display for FunctionGUID { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.guid, f) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Function { + pub guid: FunctionGUID, + pub symbol: Symbol, + pub ty: Option, + pub constraints: HashSet, + pub comments: Vec, + pub variables: Vec, +} + +impl Function { + pub fn from_bytes(buf: &[u8]) -> Option { + flatbuffers::root::(buf) + .ok() + .and_then(|f| Function::from_object(&f)) + } + + pub fn to_bytes(&self) -> Vec { + let mut builder = CachedFlatBufferBuilder::new(); + let fb_type = self.create(&mut builder); + builder.finish_minimal(fb_type); + builder.finished_data().to_vec() + } +} + +impl FlatBufferObject for Function { + type FbType<'fbb> = fb::Function<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let symbol = self.symbol.create(builder); + let ty = self.ty.as_ref().map(|t| t.create(builder)); + let _constraints: Vec<_> = self + .constraints + .iter() + .map(|constraint| constraint.create(builder)) + .collect(); + let constraints = if _constraints.is_empty() { + None + } else { + Some(builder.create_vector(&_constraints)) + }; + let _comments: Vec<_> = self.comments.iter().map(|c| c.create(builder)).collect(); + let comments = if _comments.is_empty() { + None + } else { + Some(builder.create_vector(&_comments)) + }; + let _variables: Vec<_> = self.variables.iter().map(|v| v.create(builder)).collect(); + let variables = if _variables.is_empty() { + None + } else { + Some(builder.create_vector(&_variables)) + }; + + fb::Function::create( + builder, + &fb::FunctionArgs { + guid: Some(&self.guid.into()), + symbol: Some(symbol), + type_: ty, + constraints, + comments, + variables, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let ty = value.type_(); + let constraints: HashSet = value + .constraints() + .unwrap_or_default() + .iter() + .flat_map(|constraint| Constraint::from_object(&constraint)) + .collect(); + let comments: Vec = value + .comments() + .unwrap_or_default() + .iter() + .flat_map(|comment| FunctionComment::from_object(&comment)) + .collect(); + let variables: Vec = value + .variables() + .unwrap_or_default() + .iter() + .flat_map(|variable| FunctionVariable::from_object(&variable)) + .collect(); + let func = Self { + guid: FunctionGUID::from(*value.guid()), + symbol: Symbol::from_object(&value.symbol()?)?, + ty: match ty { + Some(ty) => Type::from_object(&ty), + None => None, + }, + constraints, + comments, + variables, + }; + + Some(func) + } +} diff --git a/rust/src/signature/variable.rs b/rust/src/signature/variable.rs new file mode 100644 index 0000000..d136d56 --- /dev/null +++ b/rust/src/signature/variable.rs @@ -0,0 +1,62 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::fb_sig as fb; +use crate::gen_flatbuffers::type_bin::LocationClass; +use crate::r#type::class::function::{Location, RegisterLocation, StackLocation}; +use crate::r#type::Type; +use crate::{FlatBufferObject, FlatBufferUnion}; +use flatbuffers::WIPOffset; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FunctionVariable { + pub offset: i64, + pub location: Location, + pub name: Option, + pub ty: Option, +} + +impl FlatBufferObject for FunctionVariable { + type FbType<'fbb> = fb::FunctionVariable<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let location_type = self.location.ty(); + let location = self.location.create(builder); + let ty = self.ty.as_ref().map(|t| t.create(builder)); + let name = self.name.as_ref().map(|n| builder.create_string(n)); + fb::FunctionVariable::create( + builder, + &fb::FunctionVariableArgs { + offset: self.offset, + name, + location_type, + location: Some(location), + type_: ty, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let location = match value.location_type() { + LocationClass::RegisterLocation => { + let register_loc = value.location_as_register_location()?; + Location::Register(RegisterLocation::from_object(®ister_loc)?) + } + LocationClass::StackLocation => { + let stack_loc = value.location_as_stack_location()?; + Location::Stack(StackLocation::from_object(&stack_loc)?) + } + // NOTE: Unknown location class, probable malformed data. + _ => return None, + }; + + let ty = value.type_().and_then(|ty| Type::from_object(&ty)); + Some(Self { + offset: value.offset(), + location, + name: value.name().map(|s| s.to_string()), + ty, + }) + } +} diff --git a/rust/src/symbol.rs b/rust/src/symbol.rs new file mode 100644 index 0000000..d489194 --- /dev/null +++ b/rust/src/symbol.rs @@ -0,0 +1,97 @@ +use crate::{fb_symbol as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; +use std::hash::Hash; + +use crate::cached_builder::CachedFlatBufferBuilder; +pub use fb::SymbolClass; +pub use fb::SymbolModifiers; + +#[derive(Clone, Debug, PartialEq)] +pub struct Symbol { + pub name: String, + pub modifiers: SymbolModifiers, + pub class: SymbolClass, +} + +impl Symbol { + pub fn new(name: impl Into, class: SymbolClass, modifiers: SymbolModifiers) -> Self { + Self { + name: name.into(), + modifiers, + class, + } + } +} + +impl FlatBufferObject for Symbol { + type FbType<'fbb> = fb::Symbol<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let name = builder.create_string(&self.name); + + fb::Symbol::create( + builder, + &fb::SymbolArgs { + name: Some(name), + modifiers: self.modifiers, + class: self.class, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let sym = Self { + name: value.name()?.to_string(), + modifiers: value.modifiers(), + class: value.class(), + }; + + Some(sym) + } +} + +impl Eq for Symbol {} + +impl Hash for Symbol { + fn hash(&self, state: &mut H) { + self.name.hash(state); + self.modifiers.bits().hash(state); + self.class.hash(state); + } +} + +impl Ord for Symbol { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + // NOTE: Flatbuffers currently do not add Ord impl for bitfields. + self.name + .cmp(&other.name) + .then(self.modifiers.bits().cmp(&other.modifiers.bits())) + .then(self.class.cmp(&other.class)) + } +} + +impl PartialOrd for Symbol { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let mut builder = CachedFlatBufferBuilder::new(); + let symbol = Symbol { + name: "".to_string(), + modifiers: SymbolModifiers::empty(), + class: SymbolClass::Data, + }; + let _created_symbol = symbol.create(&mut builder); + // TODO: Add actual tests. + } +} diff --git a/rust/src/target.rs b/rust/src/target.rs new file mode 100644 index 0000000..5217def --- /dev/null +++ b/rust/src/target.rs @@ -0,0 +1,36 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::fb_target as fb; +use crate::FlatBufferObject; +use flatbuffers::WIPOffset; + +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] +pub struct Target { + pub architecture: Option, + pub platform: Option, +} + +impl FlatBufferObject for Target { + type FbType<'fbb> = fb::Target<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let architecture = self.architecture.clone().map(|n| builder.create_string(&n)); + let platform = self.platform.clone().map(|n| builder.create_string(&n)); + fb::Target::create( + builder, + &fb::TargetArgs { + architecture, + platform, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + architecture: value.architecture().map(|n| n.to_string()), + platform: value.platform().map(|n| n.to_string()), + }) + } +} diff --git a/rust/src/type.rs b/rust/src/type.rs new file mode 100644 index 0000000..1d0d92c --- /dev/null +++ b/rust/src/type.rs @@ -0,0 +1,415 @@ +use bon::bon; +use std::hash::Hash; + +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::r#type::class::{ + ArrayClass, BooleanClass, CharacterClass, EnumerationClass, FloatClass, FunctionClass, + IntegerClass, PointerClass, ReferrerClass, StructureClass, TypeClass, UnionClass, +}; +use crate::r#type::guid::TypeGUID; +use crate::{fb_type as fb, FlatBufferObject, FlatBufferUnion}; +use flatbuffers::WIPOffset; + +// We re-export bit flags as there is no need to wrap them. +pub use fb::MetadataValueType; +pub use fb::TypeModifiers; + +pub mod chunk; +pub mod class; +pub mod guid; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ComputedType { + pub guid: TypeGUID, + pub ty: Type, +} + +impl ComputedType { + pub fn new(ty: Type) -> ComputedType { + let guid = TypeGUID::from(&ty); + Self::new_with_guid(ty, guid) + } + + pub fn new_with_guid(ty: Type, guid: TypeGUID) -> ComputedType { + ComputedType { guid, ty } + } + + pub fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let created_ty = self.ty.create(builder); + fb::ComputedType::create( + builder, + &fb::ComputedTypeArgs { + guid: Some(&self.guid.into()), + type_: Some(created_ty), + }, + ) + } +} + +impl FlatBufferObject for ComputedType { + type FbType<'fbb> = fb::ComputedType<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let created_ty = self.ty.create(builder); + fb::ComputedType::create( + builder, + &fb::ComputedTypeArgs { + guid: Some(&self.guid.into()), + type_: Some(created_ty), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let ty: Type = Type::from_object(&value.type_()?)?; + let guid = TypeGUID::from(*value.guid()); + Some(Self::new_with_guid(ty, guid)) + } +} + +#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum Alignment { + #[default] + Access, + Fixed(u16), +} + +impl From for Alignment { + fn from(value: u16) -> Self { + match value { + 0 => Self::Access, + value => Self::Fixed(value), + } + } +} + +impl From for u16 { + fn from(value: Alignment) -> Self { + match value { + Alignment::Access => 0, + Alignment::Fixed(value) => value, + } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct Type { + pub name: Option, + pub class: TypeClass, + // TODO: Make confidence a modifier? + pub confidence: u8, + pub modifiers: TypeModifiers, + // TODO: Make this a HashMap? + pub metadata: Vec, + pub alignment: Alignment, + pub ancestors: Vec, +} + +#[bon] +impl Type { + #[builder] + pub fn new>( + name: Option, + class: impl Into, + confidence: Option, + modifiers: Option, + metadata: Option>, + alignment: Option, + ancestors: Option>, + ) -> Self { + Self { + name: name.map(|n| n.into()), + class: class.into(), + confidence: confidence.unwrap_or(u8::MAX), + modifiers: modifiers.unwrap_or_default(), + metadata: metadata.unwrap_or_default(), + alignment: alignment.unwrap_or_default(), + ancestors: ancestors.unwrap_or_default(), + } + } +} + +impl Type { + /// Copy a type and make it an ancestor, effectively allowing a mutation of the type. + pub fn from_ancestor(ancestor: &Type) -> Self { + let mut new_type = ancestor.clone(); + new_type.ancestors.push(TypeGUID::from(ancestor)); + new_type + } + + pub fn from_bytes(buf: &[u8]) -> Option { + flatbuffers::root::(buf) + .ok() + .and_then(|ty| Type::from_object(&ty)) + } + + pub fn to_bytes(&self) -> Vec { + let mut builder = CachedFlatBufferBuilder::new(); + let fb_type = self.create(&mut builder); + builder.finish_minimal(fb_type); + builder.finished_data().to_vec() + } + + pub fn is_const(&self) -> bool { + self.modifiers.contains(TypeModifiers::Constant) + } + + pub fn is_volatile(&self) -> bool { + self.modifiers.contains(TypeModifiers::Volatile) + } + + pub fn size(&self) -> Option { + self.class.size() + } +} + +impl FlatBufferObject for Type { + type FbType<'fbb> = fb::Type<'fbb>; + + /// Serialize the type to the flatbuffer builder. + /// + /// Unique to this `create` function is the type cache which will reuse existing common types + /// such as a 32bit signed integer so that the finished data does not contain duplicate data. + /// This is extremely important to maintaining a reasonable size for large datasets. One thing this + /// will not cover is cross-buffer references. The referenced cache item must be in the + /// buffer to reference. + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + // Check if we have already created this type, if so, return the existing offset. + if let Some(existing_offset) = builder.cached_type_offsets.get(self) { + return *existing_offset; + } + + let name = self.name.as_ref().map(|n| builder.create_string(n)); + let class_type = self.class.ty(); + let class = self.class.create(builder); + + let mut ancestors = None; + if !self.ancestors.is_empty() { + let _ancestors = self + .ancestors + .iter() + .map(|guid| fb::TypeGUID::from(*guid)) + .collect::>(); + ancestors = Some(builder.create_vector(&_ancestors)); + } + + let mut metadata = None; + if !self.metadata.is_empty() { + let _metadata = self + .metadata + .iter() + .map(|metadata| metadata.create(builder)) + .collect::>(); + metadata = Some(builder.create_vector(&_metadata)); + } + + let offset = fb::Type::create( + builder, + &fb::TypeArgs { + name, + class_type, + class: Some(class), + confidence: self.confidence, + ancestors, + modifiers: self.modifiers, + metadata, + alignment: self.alignment.into(), + }, + ); + + // Make the offset available for future lookups. + builder.cached_type_offsets.insert(self.clone(), offset); + offset + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let name = value.name().map(str::to_string); + + let from_type_class = |type_class: fb::TypeClass| match type_class { + fb::TypeClass::Void => Some(TypeClass::Void), + fb::TypeClass::Boolean => { + let bool = value.class_as_boolean()?; + let class = BooleanClass::from_object(&bool)?; + Some(TypeClass::Boolean(class)) + } + fb::TypeClass::Integer => { + let int = value.class_as_integer()?; + let class = IntegerClass::from_object(&int)?; + Some(TypeClass::Integer(class)) + } + fb::TypeClass::Character => { + let character = value.class_as_character()?; + let class = CharacterClass::from_object(&character)?; + Some(TypeClass::Character(class)) + } + fb::TypeClass::Float => { + let float = value.class_as_float()?; + let class = FloatClass::from_object(&float)?; + Some(TypeClass::Float(class)) + } + fb::TypeClass::Pointer => { + let ptr = value.class_as_pointer()?; + let class = PointerClass::from_object(&ptr)?; + Some(TypeClass::Pointer(class)) + } + fb::TypeClass::Array => { + let array = value.class_as_array()?; + let class = ArrayClass::from_object(&array)?; + Some(TypeClass::Array(class)) + } + fb::TypeClass::Structure => { + let structure = value.class_as_structure()?; + let class = StructureClass::from_object(&structure)?; + Some(TypeClass::Structure(class)) + } + fb::TypeClass::Enumeration => { + let enumeration = value.class_as_enumeration()?; + let class = EnumerationClass::from_object(&enumeration)?; + Some(TypeClass::Enumeration(class)) + } + fb::TypeClass::Union => { + let union = value.class_as_union()?; + let class = UnionClass::from_object(&union)?; + Some(TypeClass::Union(class)) + } + fb::TypeClass::Function => { + let function = value.class_as_function()?; + let class = FunctionClass::from_object(&function)?; + Some(TypeClass::Function(class)) + } + fb::TypeClass::Referrer => { + let referrer = value.class_as_referrer()?; + let class = ReferrerClass::from_object(&referrer)?; + Some(TypeClass::Referrer(class)) + } + // Somehow we got an unknown type class, possibly malformed data. + _ => None, + }; + + let class = from_type_class(value.class_type())?; + let ty = Self { + name, + class, + confidence: value.confidence(), + modifiers: value.modifiers(), + metadata: value + .metadata() + .unwrap_or_default() + .iter() + .flat_map(|meta| TypeMetadata::from_object(&meta)) + .collect(), + alignment: value.alignment().into(), + ancestors: value + .ancestors() + .unwrap_or_default() + .iter() + .map(TypeGUID::from) + .collect(), + }; + + Some(ty) + } +} + +impl Eq for Type {} + +impl Hash for Type { + fn hash(&self, state: &mut H) { + self.name.hash(state); + self.class.hash(state); + self.confidence.hash(state); + // NOTE: Flatbuffers currently do not add Hash impl for bitfields. + self.modifiers.bits().hash(state); + self.alignment.hash(state); + self.ancestors.hash(state); + } +} + +#[derive(Clone, Debug, PartialEq, Hash, Eq)] +pub enum TypeMetadataValue { + Raw(Vec), + String(String), +} + +impl TypeMetadataValue { + pub fn value_type(&self) -> MetadataValueType { + match self { + TypeMetadataValue::Raw(_) => MetadataValueType::Raw, + TypeMetadataValue::String(_) => MetadataValueType::String, + } + } + + pub fn to_bytes(&self) -> Vec { + match self { + TypeMetadataValue::Raw(value) => value.clone(), + TypeMetadataValue::String(value) => value.as_bytes().to_vec(), + } + } +} + +#[derive(Clone, Debug, PartialEq, Hash, Eq)] +pub struct TypeMetadata { + pub key: String, + pub value: TypeMetadataValue, +} + +impl TypeMetadata { + pub fn new_raw(key: String, value: Vec) -> Self { + Self { + key, + value: TypeMetadataValue::Raw(value), + } + } + + pub fn new_string(key: String, value: String) -> Self { + Self { + key, + value: TypeMetadataValue::String(value), + } + } +} + +impl FlatBufferObject for TypeMetadata { + type FbType<'fbb> = fb::TypeMetadata<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let key = builder.create_string(&self.key); + let value_type = self.value.value_type(); + let _value = self.value.to_bytes(); + let value = builder.create_vector(&_value); + fb::TypeMetadata::create( + builder, + &fb::TypeMetadataArgs { + key: Some(key), + value_type, + value: Some(value), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let key = value.key().to_string(); + let value_bytes = value.value().as_ref()?.bytes(); + let value = match value.value_type() { + MetadataValueType::Raw => TypeMetadataValue::Raw(value_bytes.to_vec()), + MetadataValueType::String => { + TypeMetadataValue::String(String::from_utf8(value_bytes.to_vec()).ok()?) + } + // Fallback to raw if unknown type. + _ => TypeMetadataValue::Raw(value_bytes.to_vec()), + }; + Some(Self { key, value }) + } +} diff --git a/rust/src/type/chunk.rs b/rust/src/type/chunk.rs new file mode 100644 index 0000000..2eef826 --- /dev/null +++ b/rust/src/type/chunk.rs @@ -0,0 +1,155 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::chunk::ChunkHandler; +use crate::fb_type as fb; +use crate::r#type::guid::TypeGUID; +use crate::r#type::{ComputedType, Type}; +use crate::FlatBufferObject; +use flatbuffers::VerifierOptions; +use std::borrow::Cow; +use std::collections::HashMap; +use std::fmt::{Debug, Formatter}; + +#[derive(Clone, PartialEq)] +pub struct TypeChunk<'fbb> { + buffer: Cow<'fbb, [u8]>, + lookup: HashMap, +} + +impl<'fbb> TypeChunk<'fbb> { + /// Construct a [`TypeChunk`] using the provided [`CachedFlatBufferBuilder`] and [`Type`] list. + pub fn new(types: &[Type]) -> Option> { + let computed_types: Vec = + types.iter().cloned().map(ComputedType::new).collect(); + Self::new_with_computed(&computed_types) + } + + /// Construct a [`TypeChunk`] using the provided [`CachedFlatBufferBuilder`] and [`ComputedType`] list. + pub fn new_with_computed(types: &[ComputedType]) -> Option> { + let mut builder = CachedFlatBufferBuilder::new(); + // Build the new flatbuffer signature chunk from the given functions. + let _types: Vec<_> = types.iter().map(|f| f.create(&mut builder)).collect(); + let types = builder.create_vector(&_types); + let chunk = fb::TypeChunk::create(&mut builder, &fb::TypeChunkArgs { types: Some(types) }); + + // Round-trip the flatbuffer signature chunk back to a TypeChunk. + // NOTE: The returned TypeChunk does not own the underlying buffer, we clone it to avoid annoying lifetime issues. + builder.finish_minimal(chunk); + let chunk_data = builder.finished_data().to_vec(); + TypeChunk::from_data(Cow::Owned(chunk_data)) + } + + /// Builds the lookup table for type guids. + /// + /// NOTE: Called when constructing the chunk in [`TypeChunk::from_data`]. + fn build_lookup(&mut self) { + self.lookup = self + .raw_types() + .enumerate() + .fold(HashMap::new(), |mut acc, (idx, ty)| { + let guid = TypeGUID::from(*ty.guid()); + acc.insert(guid, idx); + acc + }); + } + + fn get_raw_type(&self, idx: usize) -> Option { + if idx >= self.object().types().len() { + return None; + } + Some(self.object().types().get(idx)) + } + + pub fn object(&self) -> fb::TypeChunk { + // SAFETY: We have already verified the buffer. + unsafe { fb::root_as_type_chunk_unchecked(&self.buffer) } + } + + pub fn raw_types(&self) -> impl Iterator> + '_ { + self.object().types().iter() + } + + /// Retrieve all types as an owned [`ComputedType`]. + /// + /// This function should not be used in hot paths, instead use [`TypeChunk::raw_types`] + /// which you should then filter types off of before creating an owned [`Type`]. An example + /// of a function that does this is [`TypeChunk::type_with_guid`]. + pub fn types(&self) -> impl Iterator + '_ { + self.raw_types() + .flat_map(|ct| ComputedType::from_object(&ct)) + } + + #[must_use] + pub fn raw_type_with_guid(&self, guid: &TypeGUID) -> Option { + self.lookup + .get(guid) + .and_then(|idx| self.get_raw_type(*idx)) + .and_then(|ct| ct.type_()) + } + + #[must_use] + pub fn type_with_guid(&self, guid: &TypeGUID) -> Option { + self.raw_type_with_guid(guid) + .as_ref() + .and_then(Type::from_object) + } + + #[must_use] + pub fn raw_type_with_name(&self, name: &str) -> Vec { + self.raw_types() + .filter_map(|ct| ct.type_().filter(|ty| ty.name() == Some(name)).map(|_| ct)) + .collect() + } + + #[must_use] + pub fn type_with_name(&self, name: &str) -> Vec { + self.raw_type_with_name(name) + .iter() + .flat_map(ComputedType::from_object) + .collect() + } +} + +impl Debug for TypeChunk<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let types: Vec<_> = self.types().collect(); + f.debug_struct("TypeChunk").field("types", &types).finish() + } +} + +impl<'fbb> ChunkHandler<'fbb> for TypeChunk<'fbb> { + const VERSION: u16 = 0; + + fn from_data(data: Cow<'fbb, [u8]>) -> Option { + // We must verify the buffer before we can create a TypeChunk. + // See TypeChunk::object for more details. + let verify_opts = VerifierOptions { + max_tables: 10_000_000, + ..Default::default() + }; + let _verified_object = fb::root_as_type_chunk_with_opts(&verify_opts, &data).ok()?; + let mut chunk = Self { + buffer: data, + lookup: HashMap::new(), + }; + chunk.build_lookup(); + Some(chunk) + } + + fn merge(chunks: &[Self]) -> Option { + let mut types: Vec<_> = chunks.iter().flat_map(|c| c.types()).collect(); + // Sort by the GUID, then remove duplicates by GUID. + types.sort_unstable_by(|a, b| a.guid.cmp(&b.guid)); + types.dedup_by_key(|ty| ty.guid); + Self::new_with_computed(&types) + } + + fn size(&self) -> u32 { + self.buffer.len() as u32 + } +} + +impl AsRef<[u8]> for TypeChunk<'_> { + fn as_ref(&self) -> &[u8] { + &self.buffer + } +} diff --git a/rust/type/class.rs b/rust/src/type/class.rs similarity index 81% rename from rust/type/class.rs rename to rust/src/type/class.rs index c5cbcea..2333846 100644 --- a/rust/type/class.rs +++ b/rust/src/type/class.rs @@ -2,7 +2,7 @@ pub mod array; pub mod boolean; mod character; pub mod enumeration; -mod float; +pub mod float; pub mod function; pub mod integer; pub mod pointer; @@ -11,7 +11,10 @@ pub mod structure; pub mod union; pub mod void; -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_type as fb, FlatBufferObject, FlatBufferUnion}; +use flatbuffers::{UnionWIPOffset, WIPOffset}; + pub use crate::r#type::class::array::ArrayClass; pub use crate::r#type::class::boolean::BooleanClass; pub use crate::r#type::class::character::CharacterClass; @@ -24,9 +27,6 @@ pub use crate::r#type::class::referrer::ReferrerClass; pub use crate::r#type::class::structure::{StructureClass, StructureMember}; pub use crate::r#type::class::union::{UnionClass, UnionMember}; pub use crate::r#type::class::void::VoidClass; -use flatbuffers::{FlatBufferBuilder, UnionWIPOffset, WIPOffset}; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum TypeClass { @@ -62,23 +62,6 @@ impl TypeClass { } } - pub(crate) fn create(&self, builder: &mut FlatBufferBuilder) -> WIPOffset { - match self { - TypeClass::Void => VoidClass.create(builder).as_union_value(), - TypeClass::Boolean(c) => c.create(builder).as_union_value(), - TypeClass::Integer(c) => c.create(builder).as_union_value(), - TypeClass::Character(c) => c.create(builder).as_union_value(), - TypeClass::Float(c) => c.create(builder).as_union_value(), - TypeClass::Pointer(c) => c.create(builder).as_union_value(), - TypeClass::Array(c) => c.create(builder).as_union_value(), - TypeClass::Structure(c) => c.create(builder).as_union_value(), - TypeClass::Enumeration(c) => c.create(builder).as_union_value(), - TypeClass::Union(c) => c.create(builder).as_union_value(), - TypeClass::Function(c) => c.create(builder).as_union_value(), - TypeClass::Referrer(c) => c.create(builder).as_union_value(), - } - } - pub fn size(&self) -> Option { match self { TypeClass::Void => None, @@ -97,23 +80,21 @@ impl TypeClass { } } -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> TypeClass { - // TODO: We need more types than Standard to randomly generate structures. - match rng.gen_range(0..15) { - 0 => TypeClass::Void, - 1 => TypeClass::Boolean(rng.gen()), - 2 => TypeClass::Integer(rng.gen()), - 3 => TypeClass::Character(rng.gen()), - 4 => TypeClass::Float(rng.gen()), - 5 => TypeClass::Array(rng.gen()), - // 6 => TypeClass::Structure(rng.gen()), - 7 => TypeClass::Enumeration(rng.gen()), - // 8 => TypeClass::Union(rng.gen()), - // 9 => TypeClass::Function(rng.gen()), - 10 => TypeClass::Referrer(rng.gen()), - // Pointer is weighted so that we get more nesting. - _ => TypeClass::Pointer(rng.gen()), +impl FlatBufferUnion for TypeClass { + fn create(&self, builder: &mut CachedFlatBufferBuilder) -> WIPOffset { + match self { + TypeClass::Void => VoidClass.create(builder).as_union_value(), + TypeClass::Boolean(c) => c.create(builder).as_union_value(), + TypeClass::Integer(c) => c.create(builder).as_union_value(), + TypeClass::Character(c) => c.create(builder).as_union_value(), + TypeClass::Float(c) => c.create(builder).as_union_value(), + TypeClass::Pointer(c) => c.create(builder).as_union_value(), + TypeClass::Array(c) => c.create(builder).as_union_value(), + TypeClass::Structure(c) => c.create(builder).as_union_value(), + TypeClass::Enumeration(c) => c.create(builder).as_union_value(), + TypeClass::Union(c) => c.create(builder).as_union_value(), + TypeClass::Function(c) => c.create(builder).as_union_value(), + TypeClass::Referrer(c) => c.create(builder).as_union_value(), } } } diff --git a/rust/type/class/array.rs b/rust/src/type/class/array.rs similarity index 55% rename from rust/type/class/array.rs rename to rust/src/type/class/array.rs index 8b296a3..e391285 100644 --- a/rust/type/class/array.rs +++ b/rust/src/type/class/array.rs @@ -1,18 +1,18 @@ use bon::bon; +use std::hash::Hash; -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; use crate::r#type::Type; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::Standard; -use rand::prelude::*; +use crate::{fb_type as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; // We re-export bit flags as there is no need to wrap them. pub use fb::ArrayModifiers; -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq)] pub struct ArrayClass { pub length: Option, - pub member_type: Type, + pub member_type: Box, pub modifiers: ArrayModifiers, } @@ -22,17 +22,25 @@ impl ArrayClass { pub fn new(length: Option, member_type: Type, modifiers: Option) -> Self { Self { length, - member_type, + member_type: Box::new(member_type), modifiers: modifiers.unwrap_or_default(), } } } impl ArrayClass { - pub(crate) fn create<'a>( + pub fn size(&self) -> Option { + Some(self.length? * self.member_type.size()?) + } +} + +impl FlatBufferObject for ArrayClass { + type FbType<'fbb> = fb::Array<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let member_type = self.member_type.create(builder); fb::Array::create( builder, @@ -46,33 +54,27 @@ impl ArrayClass { ) } - pub fn size(&self) -> Option { - Some(self.length? * self.member_type.size()?) - } -} - -impl From> for ArrayClass { - fn from(value: fb::Array<'_>) -> Self { - Self { + fn from_object(value: &Self::FbType<'_>) -> Option { + let class = Self { length: match value.length() { 0 => None, len => Some(len), }, - member_type: value.type_().into(), + member_type: Box::new(Type::from_object(&value.type_())?), modifiers: value.modifiers(), - } + }; + + Some(class) } } -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> ArrayClass { - let mut modifiers = ArrayModifiers::empty(); - // 50% chance array is null terminated. - modifiers.set(ArrayModifiers::NullTerminated, rng.gen_bool(0.5)); - ArrayClass { - length: rng.gen(), - member_type: rng.gen(), - modifiers, - } +impl Eq for ArrayClass {} + +impl Hash for ArrayClass { + fn hash(&self, state: &mut H) { + self.length.hash(state); + self.member_type.hash(state); + // NOTE: Flatbuffers currently do not add Hash impl for bitfields. + self.modifiers.bits().hash(state); } } diff --git a/rust/src/type/class/boolean.rs b/rust/src/type/class/boolean.rs new file mode 100644 index 0000000..52de9cc --- /dev/null +++ b/rust/src/type/class/boolean.rs @@ -0,0 +1,37 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_type as fb, FlatBufferObject}; +use bon::Builder; +use flatbuffers::WIPOffset; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] +pub struct BooleanClass { + pub width: Option, +} + +impl BooleanClass { + pub fn size(&self) -> Option { + self.width.map(|w| w as u64) + } +} + +impl FlatBufferObject for BooleanClass { + type FbType<'fbb> = fb::Boolean<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::Boolean::create( + builder, + &fb::BooleanArgs { + width: self.width.map(Into::into).as_ref(), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + width: value.width().map(Into::into), + }) + } +} diff --git a/rust/src/type/class/character.rs b/rust/src/type/class/character.rs new file mode 100644 index 0000000..b4790f5 --- /dev/null +++ b/rust/src/type/class/character.rs @@ -0,0 +1,38 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_type as fb, FlatBufferObject}; +use bon::Builder; +use flatbuffers::WIPOffset; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] +pub struct CharacterClass { + /// Width in bits + pub width: Option, +} + +impl CharacterClass { + pub fn size(&self) -> Option { + self.width.map(|w| w as u64) + } +} + +impl FlatBufferObject for CharacterClass { + type FbType<'fbb> = fb::Character<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::Character::create( + builder, + &fb::CharacterArgs { + width: self.width.map(Into::into).as_ref(), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + width: value.width().map(Into::into), + }) + } +} diff --git a/rust/type/class/enumeration.rs b/rust/src/type/class/enumeration.rs similarity index 51% rename from rust/type/class/enumeration.rs rename to rust/src/type/class/enumeration.rs index 3112536..e220bb7 100644 --- a/rust/type/class/enumeration.rs +++ b/rust/src/type/class/enumeration.rs @@ -1,10 +1,9 @@ use bon::Builder; -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; use crate::r#type::Type; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Alphanumeric, DistString, Distribution, Standard}; -use rand::Rng; +use crate::{fb_type as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; #[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] #[builder(on(String, into))] @@ -13,11 +12,13 @@ pub struct EnumerationMember { pub constant: u64, } -impl EnumerationMember { - fn create<'a>( +impl FlatBufferObject for EnumerationMember { + type FbType<'fbb> = fb::EnumerationMember<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let name = self.name.as_ref().map(|n| builder.create_string(n)); fb::EnumerationMember::create( builder, @@ -27,46 +28,43 @@ impl EnumerationMember { }, ) } -} -impl From> for EnumerationMember { - fn from(value: fb::EnumerationMember<'_>) -> Self { - Self { + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { name: value.name().map(str::to_string), constant: value.constant(), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> EnumerationMember { - EnumerationMember { - name: Some(Alphanumeric.sample_string(rng, 16)), - constant: rng.gen(), - } + }) } } #[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] pub struct EnumerationClass { - pub member_type: Type, + pub member_type: Box, pub members: Vec, } impl EnumerationClass { pub fn new(member_type: Type, members: Vec) -> Self { Self { - member_type, + member_type: Box::new(member_type), members, } } } impl EnumerationClass { - pub(crate) fn create<'a>( + pub fn size(&self) -> Option { + self.member_type.size() + } +} + +impl FlatBufferObject for EnumerationClass { + type FbType<'fbb> = fb::Enumeration<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let enum_type = self.member_type.create(builder); // Resolve then create all member constants. Take the prior constant when `None`. let created_members: Vec<_> = self @@ -84,26 +82,16 @@ impl EnumerationClass { ) } - pub fn size(&self) -> Option { - self.member_type.size() - } -} - -impl From> for EnumerationClass { - fn from(value: fb::Enumeration<'_>) -> Self { - Self { - member_type: value.member_type().into(), - members: value.members().unwrap().iter().map(Into::into).collect(), - } - } -} + fn from_object(value: &Self::FbType<'_>) -> Option { + let class = Self { + member_type: Box::new(Type::from_object(&value.member_type())?), + members: value + .members()? + .iter() + .flat_map(|member| EnumerationMember::from_object(&member)) + .collect(), + }; -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> EnumerationClass { - let rand_member_len = rng.gen_range(0..20); - EnumerationClass { - member_type: rng.gen(), - members: rng.sample_iter(Standard).take(rand_member_len).collect(), - } + Some(class) } } diff --git a/rust/src/type/class/float.rs b/rust/src/type/class/float.rs new file mode 100644 index 0000000..137db8e --- /dev/null +++ b/rust/src/type/class/float.rs @@ -0,0 +1,37 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_type as fb, FlatBufferObject}; +use bon::Builder; +use flatbuffers::WIPOffset; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] +pub struct FloatClass { + /// Width in bits + pub width: Option, +} + +impl FloatClass { + pub fn size(&self) -> Option { + self.width.map(|w| w as u64) + } +} + +impl FlatBufferObject for FloatClass { + type FbType<'fbb> = fb::Float<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::Float::create( + builder, + &fb::FloatArgs { + width: self.width.map(Into::into).as_ref(), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + width: value.width().map(Into::into), + }) + } +} diff --git a/rust/src/type/class/function.rs b/rust/src/type/class/function.rs new file mode 100644 index 0000000..8f42af7 --- /dev/null +++ b/rust/src/type/class/function.rs @@ -0,0 +1,257 @@ +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::r#type::Type; +use crate::{fb_type as fb, FlatBufferObject, FlatBufferUnion}; +use bon::{bon, Builder}; +use flatbuffers::{UnionWIPOffset, WIPOffset}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct RegisterLocation { + pub id: u64, +} + +impl FlatBufferObject for RegisterLocation { + type FbType<'fbb> = fb::RegisterLocation<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::RegisterLocation::create(builder, &fb::RegisterLocationArgs { id: self.id }) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { id: value.id() }) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct StackLocation { + /// Offset from the stack pointer, in bits. + pub offset: i64, +} + +impl FlatBufferObject for StackLocation { + type FbType<'fbb> = fb::StackLocation<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + fb::StackLocation::create( + builder, + &fb::StackLocationArgs { + offset: Some(&self.offset.into()), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + offset: value.offset().into(), + }) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum Location { + Register(RegisterLocation), + Stack(StackLocation), +} + +impl Location { + pub fn ty(&self) -> fb::LocationClass { + match self { + Location::Register(_) => fb::LocationClass::RegisterLocation, + Location::Stack(_) => fb::LocationClass::StackLocation, + } + } +} + +impl FlatBufferUnion for Location { + fn create(&self, builder: &mut CachedFlatBufferBuilder) -> WIPOffset { + match self { + Location::Register(loc) => loc.create(builder).as_union_value(), + Location::Stack(loc) => loc.create(builder).as_union_value(), + } + } +} + +// TODO: Add Builder derive? +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct FunctionMember { + pub name: Option, + pub ty: Box, + pub location: Option, +} + +#[bon] +impl FunctionMember { + #[builder] + pub fn new>(name: Option, ty: Type, location: Option) -> Self { + Self { + name: name.map(|n| n.into()), + ty: Box::new(ty), + location, + } + } +} + +impl FlatBufferObject for FunctionMember { + type FbType<'fbb> = fb::FunctionMember<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let name = self.name.as_ref().map(|n| builder.create_string(n)); + let member_type = self.ty.create(builder); + let location_type = self.location.as_ref().map(|l| l.ty()).unwrap_or_default(); + let location = self.location.as_ref().map(|l| l.create(builder)); + fb::FunctionMember::create( + builder, + &fb::FunctionMemberArgs { + name, + type_: Some(member_type), + location_type, + location, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let location = match value.location_type() { + fb::LocationClass::RegisterLocation => { + let register_loc = value.location_as_register_location()?; + Some(Location::Register(RegisterLocation::from_object( + ®ister_loc, + )?)) + } + fb::LocationClass::StackLocation => { + let stack_loc = value.location_as_stack_location()?; + Some(Location::Stack(StackLocation::from_object(&stack_loc)?)) + } + _ => None, + }; + + let class = Self { + name: value.name().map(str::to_string), + ty: Box::new(Type::from_object(&value.type_())?), + location, + }; + + Some(class) + } +} + +// TODO: Move calling convention to another crate? +// TODO: It might have a seperate store... we want to refer to the uuid, but that means we have to do whole +// TODO: database updates when the calling convention changes. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] +pub struct CallingConvention { + pub name: String, +} + +impl CallingConvention { + // Currently we only support calling convention by name + pub fn new(name: &str) -> Self { + Self { + name: name.to_string(), + } + } +} + +impl FlatBufferObject for CallingConvention { + type FbType<'fbb> = fb::CallingConvention<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let name = builder.create_string(&self.name); + fb::CallingConvention::create(builder, &fb::CallingConventionArgs { name: Some(name) }) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + name: value.name()?.to_string(), + }) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] +pub struct FunctionClass { + pub calling_convention: Option, + pub in_members: Vec, + pub out_members: Vec, +} + +impl FunctionClass { + pub fn new( + calling_convention: Option, + in_members: Vec, + out_members: Vec, + ) -> Self { + Self { + calling_convention, + in_members, + out_members, + } + } +} + +impl FlatBufferObject for FunctionClass { + type FbType<'fbb> = fb::Function<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let calling_convention = self + .calling_convention + .as_ref() + .map(|cc| cc.create(builder)); + let _created_in_members: Vec<_> = self + .in_members + .iter() + .map(|member| member.create(builder)) + .collect(); + let created_in_members = builder.create_vector(&_created_in_members); + let _created_out_members: Vec<_> = self + .out_members + .iter() + .map(|member| member.create(builder)) + .collect(); + let created_out_members = builder.create_vector(&_created_out_members); + + fb::Function::create( + builder, + &fb::FunctionArgs { + calling_convention, + in_members: Some(created_in_members), + out_members: Some(created_out_members), + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + let class = Self { + calling_convention: value + .calling_convention() + .and_then(|cc| FlatBufferObject::from_object(&cc)), + in_members: value + .in_members() + .unwrap_or_default() + .iter() + .flat_map(|member| FlatBufferObject::from_object(&member)) + .collect(), + out_members: value + .out_members() + .unwrap_or_default() + .iter() + .flat_map(|member| FlatBufferObject::from_object(&member)) + .collect(), + }; + + Some(class) + } +} diff --git a/rust/type/class/integer.rs b/rust/src/type/class/integer.rs similarity index 60% rename from rust/type/class/integer.rs rename to rust/src/type/class/integer.rs index 02c74c9..04fa6ad 100644 --- a/rust/type/class/integer.rs +++ b/rust/src/type/class/integer.rs @@ -1,8 +1,7 @@ -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_type as fb, FlatBufferObject}; use bon::Builder; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; +use flatbuffers::WIPOffset; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] pub struct IntegerClass { @@ -12,10 +11,18 @@ pub struct IntegerClass { } impl IntegerClass { - pub(crate) fn create<'a>( + pub fn size(&self) -> Option { + self.width.map(|w| w as u64) + } +} + +impl FlatBufferObject for IntegerClass { + type FbType<'fbb> = fb::Integer<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { fb::Integer::create( builder, &fb::IntegerArgs { @@ -25,31 +32,11 @@ impl IntegerClass { ) } - pub fn size(&self) -> Option { - self.width.map(|w| w as u64) - } -} - -impl From> for IntegerClass { - fn from(value: fb::Integer<'_>) -> Self { - Self { + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { width: value.width().map(Into::into), signed: value.signed(), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> IntegerClass { - // 90% chance this type will have a width. - let width = match rng.gen_bool(0.9) { - true => Some(rng.gen_range(1..=256)), - false => None, - }; - IntegerClass { - width, - signed: rng.gen_bool(0.5), - } + }) } } @@ -57,7 +44,7 @@ impl Distribution for Standard { mod tests { use crate::r#type::class::{IntegerClass, TypeClass}; use crate::r#type::guid::TypeGUID; - use crate::r#type::{Alignment, Type}; + use crate::r#type::Type; use uuid::{uuid, Uuid}; const INT_TYPE_UUID: Uuid = uuid!("ec8805ad-b101-5d8c-a033-c94610d036c1"); @@ -80,13 +67,14 @@ mod tests { assert_eq!( Type { name: Some("my_int".to_owned()), - class: Box::from(TypeClass::Integer(IntegerClass { + class: TypeClass::Integer(IntegerClass { width: Some(64), signed: true - })), + }), confidence: u8::MAX, - modifiers: vec![], - alignment: Alignment::Access, + modifiers: Default::default(), + metadata: vec![], + alignment: Default::default(), ancestors: vec![], }, built_int_type() diff --git a/rust/type/class/pointer.rs b/rust/src/type/class/pointer.rs similarity index 50% rename from rust/type/class/pointer.rs rename to rust/src/type/class/pointer.rs index c255908..8a6ad09 100644 --- a/rust/type/class/pointer.rs +++ b/rust/src/type/class/pointer.rs @@ -1,9 +1,8 @@ -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; use crate::r#type::Type; +use crate::{fb_type as fb, FlatBufferObject}; use bon::bon; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; +use flatbuffers::WIPOffset; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)] pub enum PointerAddressing { @@ -13,13 +12,16 @@ pub enum PointerAddressing { RelativeSelf, } -impl From for PointerAddressing { - fn from(value: fb::PointerAddressing) -> Self { +impl TryFrom for PointerAddressing { + // TODO: Actual error type + type Error = (); + + fn try_from(value: fb::PointerAddressing) -> Result { match value { - fb::PointerAddressing::Absolute => PointerAddressing::Absolute, - fb::PointerAddressing::RelativeBase => PointerAddressing::RelativeBase, - fb::PointerAddressing::RelativeSelf => PointerAddressing::RelativeSelf, - _ => unreachable!(), + fb::PointerAddressing::Absolute => Ok(PointerAddressing::Absolute), + fb::PointerAddressing::RelativeBase => Ok(PointerAddressing::RelativeBase), + fb::PointerAddressing::RelativeSelf => Ok(PointerAddressing::RelativeSelf), + _ => Err(()), } } } @@ -34,20 +36,10 @@ impl From for fb::PointerAddressing { } } -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> PointerAddressing { - match rng.gen_range(0..3) { - 1 => PointerAddressing::RelativeBase, - 0 => PointerAddressing::RelativeSelf, - _ => PointerAddressing::Absolute, - } - } -} - #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct PointerClass { pub width: Option, - pub child_type: Type, + pub child_type: Box, pub addressing: PointerAddressing, // TODO: Pointer modifiers etc... } @@ -62,17 +54,25 @@ impl PointerClass { ) -> Self { Self { width, - child_type, + child_type: Box::new(child_type), addressing: addressing.unwrap_or_default(), } } } impl PointerClass { - pub(crate) fn create<'a>( + pub fn size(&self) -> Option { + self.width.map(|w| w as u64) + } +} + +impl FlatBufferObject for PointerClass { + type FbType<'fbb> = fb::Pointer<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let child_type = self.child_type.create(builder); fb::Pointer::create( builder, @@ -89,32 +89,13 @@ impl PointerClass { ) } - pub fn size(&self) -> Option { - self.width.map(|w| w as u64) - } -} - -impl From> for PointerClass { - fn from(value: fb::Pointer<'_>) -> Self { - Self { + fn from_object(value: &Self::FbType<'_>) -> Option { + let class = Self { width: value.width().map(Into::into), - child_type: value.child().map(Into::into).unwrap(), - addressing: value.addressing().into(), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> PointerClass { - // 90% chance this type will have a width. - let width = match rng.gen_bool(0.9) { - true => Some(rng.gen_range(1..=256)), - false => None, + child_type: Box::new(Type::from_object(&value.child()?)?), + addressing: value.addressing().try_into().ok()?, }; - PointerClass { - width, - child_type: rng.gen(), - addressing: rng.gen(), - } + + Some(class) } } diff --git a/rust/src/type/class/referrer.rs b/rust/src/type/class/referrer.rs new file mode 100644 index 0000000..d0fa198 --- /dev/null +++ b/rust/src/type/class/referrer.rs @@ -0,0 +1,44 @@ +use bon::Builder; + +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::r#type::guid::TypeGUID; +use crate::{fb_type as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] +pub struct ReferrerClass { + pub guid: Option, + pub name: Option, +} + +impl ReferrerClass { + pub fn new(guid: Option, name: Option) -> Self { + Self { guid, name } + } +} + +impl FlatBufferObject for ReferrerClass { + type FbType<'fbb> = fb::Referrer<'fbb>; + + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { + let guid = self.guid.map(fb::TypeGUID::from); + let name = self.name.as_ref().map(|x| builder.create_string(x)); + fb::Referrer::create( + builder, + &fb::ReferrerArgs { + guid: guid.as_ref(), + name, + }, + ) + } + + fn from_object(value: &Self::FbType<'_>) -> Option { + Some(Self { + guid: value.guid().map(|&s| TypeGUID::from(s)), + name: value.name().map(|x| x.to_owned()), + }) + } +} diff --git a/rust/type/class/structure.rs b/rust/src/type/class/structure.rs similarity index 56% rename from rust/type/class/structure.rs rename to rust/src/type/class/structure.rs index 58e71dc..220da07 100644 --- a/rust/type/class/structure.rs +++ b/rust/src/type/class/structure.rs @@ -1,19 +1,19 @@ use bon::{bon, Builder}; +use std::hash::Hash; -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; use crate::r#type::Type; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Alphanumeric, DistString, Distribution, Standard}; -use rand::Rng; +use crate::{fb_type as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; // We re-export bit flags as there is no need to wrap them. pub use fb::StructureMemberModifiers; -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq)] pub struct StructureMember { pub name: Option, pub offset: u64, - pub ty: Type, + pub ty: Box, pub modifiers: StructureMemberModifiers, } @@ -29,17 +29,25 @@ impl StructureMember { Self { name: name.map(Into::into), offset, - ty, + ty: Box::new(ty), modifiers: modifiers.unwrap_or_default(), } } } impl StructureMember { - fn create<'a>( + fn size(&self) -> Option { + self.ty.size() + } +} + +impl FlatBufferObject for StructureMember { + type FbType<'fbb> = fb::StructureMember<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let name = self.name.as_ref().map(|n| builder.create_string(n)); let member_type = self.ty.create(builder); fb::StructureMember::create( @@ -53,34 +61,27 @@ impl StructureMember { ) } - fn size(&self) -> Option { - self.ty.size() - } -} - -impl From> for StructureMember { - fn from(value: fb::StructureMember<'_>) -> Self { - Self { + fn from_object(value: &Self::FbType<'_>) -> Option { + let member = Self { name: value.name().map(str::to_string), offset: value.offset().into(), - ty: value.type_().into(), + ty: Box::new(Type::from_object(&value.type_())?), modifiers: value.modifiers(), - } + }; + + Some(member) } } -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> StructureMember { - let mut modifiers = StructureMemberModifiers::empty(); - // 50% chance structure member is internal. - modifiers.set(StructureMemberModifiers::Internal, rng.gen_bool(0.5)); - StructureMember { - name: Some(Alphanumeric.sample_string(rng, 16)), - offset: rng.gen(), - // TODO: This is causing a recursion issue... - ty: rng.gen(), - modifiers, - } +impl Eq for StructureMember {} + +impl Hash for StructureMember { + fn hash(&self, state: &mut H) { + self.name.hash(state); + self.offset.hash(state); + self.ty.hash(state); + // NOTE: Flatbuffers currently do not add Hash impl for bitfields. + self.modifiers.bits().hash(state); } } @@ -89,25 +90,26 @@ pub struct StructureClass { pub members: Vec, } -impl From> for StructureClass { - fn from(value: fb::Structure<'_>) -> Self { - Self { - members: value.members().unwrap().iter().map(Into::into).collect(), - } - } -} - impl StructureClass { pub fn new(members: Vec) -> Self { Self { members } } + + pub fn size(&self) -> Option { + self.members.iter().fold(None, |size, member| { + // If an unknown member size is encountered, the structure size has to be unknown. + Some((member.offset + member.size()?).max(size.unwrap_or(0))) + }) + } } -impl StructureClass { - pub(crate) fn create<'a>( +impl FlatBufferObject for StructureClass { + type FbType<'fbb> = fb::Structure<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let created_members: Vec<_> = self .members .iter() @@ -122,22 +124,16 @@ impl StructureClass { ) } - pub fn size(&self) -> Option { - self.members.iter().fold(None, |size, member| { - // If an unknown member size is encountered, the structure size has to be unknown. - Some((member.offset + member.size()?).max(size.unwrap_or(0))) - }) - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> StructureClass { - let rand_in_member_len = rng.gen_range(0..1); - StructureClass { - members: rng - .sample_iter::(Standard) - .take(rand_in_member_len) + fn from_object(value: &Self::FbType<'_>) -> Option { + let class = Self { + members: value + .members() + .unwrap_or_default() + .iter() + .flat_map(|value| FlatBufferObject::from_object(&value)) .collect(), - } + }; + + Some(class) } } diff --git a/rust/type/class/union.rs b/rust/src/type/class/union.rs similarity index 65% rename from rust/type/class/union.rs rename to rust/src/type/class/union.rs index abda063..be70ac5 100644 --- a/rust/type/class/union.rs +++ b/rust/src/type/class/union.rs @@ -1,24 +1,37 @@ use bon::Builder; -use crate::fb_type as fb; +use crate::cached_builder::CachedFlatBufferBuilder; use crate::r#type::Type; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Alphanumeric, DistString, Distribution, Standard}; -use rand::Rng; +use crate::{fb_type as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; #[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] #[builder(on(String, into))] pub struct UnionMember { pub name: String, - pub ty: Type, + pub ty: Box, } impl UnionMember { pub fn new(name: String, ty: Type) -> Self { - Self { name, ty } + Self { + name, + ty: Box::new(ty), + } + } + + fn size(&self) -> Option { + self.ty.size() } +} + +impl FlatBufferObject for UnionMember { + type FbType<'fbb> = fb::UnionMember<'fbb>; - fn create<'a>(&self, builder: &mut FlatBufferBuilder<'a>) -> WIPOffset> { + fn create<'fbb>( + &self, + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let name = builder.create_string(&self.name); let member_type = self.ty.create(builder); fb::UnionMember::create( @@ -30,26 +43,13 @@ impl UnionMember { ) } - fn size(&self) -> Option { - self.ty.size() - } -} - -impl From> for UnionMember { - fn from(value: fb::UnionMember<'_>) -> Self { - Self { - name: value.name().unwrap().to_string(), - ty: value.type_().into(), - } - } -} + fn from_object(value: &Self::FbType<'_>) -> Option { + let member = Self { + name: value.name()?.to_string(), + ty: Box::new(Type::from_object(&value.type_())?), + }; -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> UnionMember { - UnionMember { - name: Alphanumeric.sample_string(rng, 16), - ty: rng.gen(), - } + Some(member) } } @@ -63,10 +63,22 @@ impl UnionClass { Self { members } } - pub(crate) fn create<'a>( + pub fn size(&self) -> Option { + // Get the largest union member. + self.members + .iter() + .max_by(|x, y| x.size().cmp(&y.size())) + .map(|z| z.ty.size())? + } +} + +impl FlatBufferObject for UnionClass { + type FbType<'fbb> = fb::Union<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { let resolved_members: Vec<_> = self .members .iter() @@ -81,29 +93,17 @@ impl UnionClass { ) } - pub fn size(&self) -> Option { - // Get the largest union member. - self.members - .iter() - .max_by(|x, y| x.size().cmp(&y.size())) - .map(|z| z.ty.size())? - } -} - -impl From> for UnionClass { - fn from(value: fb::Union<'_>) -> Self { - Self { - members: value.members().unwrap().iter().map(Into::into).collect(), - } - } -} + fn from_object(value: &Self::FbType<'_>) -> Option { + let class = Self { + members: value + .members() + .unwrap_or_default() + .iter() + .flat_map(|member| FlatBufferObject::from_object(&member)) + .collect(), + }; -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> UnionClass { - let rand_in_member_len = rng.gen_range(0..20); - UnionClass { - members: rng.sample_iter(Standard).take(rand_in_member_len).collect(), - } + Some(class) } } @@ -111,7 +111,7 @@ impl Distribution for Standard { mod tests { use crate::r#type::class::{IntegerClass, TypeClass, UnionClass, UnionMember}; use crate::r#type::guid::TypeGUID; - use crate::r#type::{Alignment, Type}; + use crate::r#type::Type; use uuid::{uuid, Uuid}; const UNION_TYPE_UUID: Uuid = uuid!("1570a765-3626-5c97-a18e-4b4652a77398"); @@ -154,42 +154,45 @@ mod tests { fn union_type() { let int_type = Type { name: Some("my_int".to_owned()), - class: Box::from(TypeClass::Integer(IntegerClass { + class: TypeClass::Integer(IntegerClass { width: Some(64), signed: true, - })), + }), confidence: 255, - modifiers: vec![], - alignment: Alignment::Access, + modifiers: Default::default(), + metadata: vec![], + alignment: Default::default(), ancestors: vec![], }; let void_type = Type { name: Some("my_void".to_owned()), - class: Box::from(TypeClass::Void), + class: TypeClass::Void, confidence: 255, - modifiers: vec![], - alignment: Alignment::Access, + modifiers: Default::default(), + metadata: vec![], + alignment: Default::default(), ancestors: vec![], }; assert_eq!( Type { name: Some("my_union".to_owned()), - class: Box::from(TypeClass::Union(UnionClass { + class: TypeClass::Union(UnionClass { members: vec![ UnionMember { name: "one".to_owned(), - ty: int_type + ty: Box::new(int_type) }, UnionMember { name: "two".to_owned(), - ty: void_type + ty: Box::new(void_type) } ] - })), + }), confidence: 255, - modifiers: vec![], - alignment: Alignment::Access, - ancestors: vec![] + modifiers: Default::default(), + metadata: vec![], + alignment: Default::default(), + ancestors: vec![], }, built_union_type() ) diff --git a/rust/type/class/void.rs b/rust/src/type/class/void.rs similarity index 59% rename from rust/type/class/void.rs rename to rust/src/type/class/void.rs index d561a5d..dd7a517 100644 --- a/rust/type/class/void.rs +++ b/rust/src/type/class/void.rs @@ -1,23 +1,30 @@ -use crate::fb_type as fb; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; +use crate::cached_builder::CachedFlatBufferBuilder; +use crate::{fb_type as fb, FlatBufferObject}; +use flatbuffers::WIPOffset; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct VoidClass; -impl VoidClass { - pub(crate) fn create<'a>( +impl FlatBufferObject for VoidClass { + type FbType<'fbb> = fb::Void<'fbb>; + + fn create<'fbb>( &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { + builder: &mut CachedFlatBufferBuilder<'fbb>, + ) -> WIPOffset> { fb::Void::create(builder, &fb::VoidArgs {}) } + + fn from_object(_value: &Self::FbType<'_>) -> Option { + Some(Self) + } } #[cfg(test)] mod tests { use crate::r#type::class::TypeClass; use crate::r#type::guid::TypeGUID; - use crate::r#type::{Alignment, Type}; + use crate::r#type::Type; use uuid::{uuid, Uuid}; const VOID_TYPE_UUID: Uuid = uuid!("c37a394d-750b-5e89-b09e-539859c7a9bd"); @@ -39,10 +46,11 @@ mod tests { assert_eq!( Type { name: Some("my_void".to_owned()), - class: Box::from(TypeClass::Void), + class: TypeClass::Void, confidence: u8::MAX, - modifiers: vec![], - alignment: Alignment::Access, + modifiers: Default::default(), + metadata: vec![], + alignment: Default::default(), ancestors: vec![], }, built_void_type() diff --git a/rust/type/guid.rs b/rust/src/type/guid.rs similarity index 64% rename from rust/type/guid.rs rename to rust/src/type/guid.rs index 7cf43cb..787d95e 100644 --- a/rust/type/guid.rs +++ b/rust/src/type/guid.rs @@ -1,12 +1,13 @@ +use crate::fb_type as fb; use crate::r#type::Type; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; use uuid::{uuid, Uuid}; pub const NAMESPACE_TYPEBIN: Uuid = uuid!("01929b90-72e6-73e6-9da1-2b6462e407a6"); +/// This type is marked `repr(transparent)` to the underlying `[u8; 16]` type, so it is safe to use in FFI. +#[repr(transparent)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct TypeGUID { guid: Uuid, @@ -40,15 +41,28 @@ impl From for TypeGUID { } } -impl Display for TypeGUID { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - Display::fmt(&self.guid, f) +impl From for TypeGUID { + fn from(value: fb::TypeGUID) -> Self { + Self { + guid: Uuid::from_bytes(value.0), + } + } +} + +impl From<&fb::TypeGUID> for TypeGUID { + fn from(value: &fb::TypeGUID) -> Self { + Self::from(*value) + } +} + +impl From for fb::TypeGUID { + fn from(value: TypeGUID) -> Self { + Self(value.guid.into_bytes()) } } -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> TypeGUID { - let rand_ty: Type = rng.gen(); - TypeGUID::from(rand_ty) +impl Display for TypeGUID { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.guid, f) } } diff --git a/rust/symbol.rs b/rust/symbol.rs deleted file mode 100644 index ef1e3f8..0000000 --- a/rust/symbol.rs +++ /dev/null @@ -1,83 +0,0 @@ -pub mod class; - -use crate::fb_symbol as fb; -use crate::symbol::class::SymbolClass; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; - -pub use fb::SymbolModifiers; - -#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub struct Symbol { - pub name: String, - pub modifiers: SymbolModifiers, - pub class: SymbolClass, -} - -impl Symbol { - pub fn new(name: impl Into, class: SymbolClass, modifiers: SymbolModifiers) -> Self { - Self { - name: name.into(), - modifiers, - class, - } - } - - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let name = builder.create_string(&self.name); - let class_type = self.class.ty(); - let class = self.class.create(builder); - - fb::Symbol::create( - builder, - &fb::SymbolArgs { - name: Some(name), - modifiers: self.modifiers, - class_type, - class: Some(class), - }, - ) - } -} - -impl From> for Symbol { - fn from(value: fb::Symbol<'_>) -> Self { - let name = value.name().unwrap().to_string(); - // TODO: I would like this conversion to be on `SymbolClass` instead. - let class = match value.class_type() { - fb::SymbolClass::FunctionSymbolClass => { - SymbolClass::from(value.class_as_function_symbol_class().unwrap()) - } - fb::SymbolClass::DataSymbolClass => { - SymbolClass::from(value.class_as_data_symbol_class().unwrap()) - } - _ => unreachable!(), - }; - - Self { - name, - modifiers: value.modifiers(), - class, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use flatbuffers::FlatBufferBuilder; - - #[test] - fn it_works() { - let mut builder = FlatBufferBuilder::with_capacity(100); - let symbol = Symbol { - name: "".to_string(), - modifiers: SymbolModifiers::empty(), - class: SymbolClass::Data, - }; - let _created_symbol = symbol.create(&mut builder); - // TODO: Add actual tests. - } -} diff --git a/rust/symbol/class.rs b/rust/symbol/class.rs deleted file mode 100644 index 4196102..0000000 --- a/rust/symbol/class.rs +++ /dev/null @@ -1,67 +0,0 @@ -use flatbuffers::{FlatBufferBuilder, UnionWIPOffset, WIPOffset}; - -#[derive(Clone, Debug, Default)] -pub struct FunctionSymbolClass; - -impl FunctionSymbolClass { - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - crate::gen_flatbuffers::symbol_bin::FunctionSymbolClass::create( - builder, - &crate::gen_flatbuffers::symbol_bin::FunctionSymbolClassArgs {}, - ) - } -} - -#[derive(Clone, Debug, Default)] -pub struct DataSymbolClass; - -impl DataSymbolClass { - fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - crate::gen_flatbuffers::symbol_bin::DataSymbolClass::create( - builder, - &crate::gen_flatbuffers::symbol_bin::DataSymbolClassArgs {}, - ) - } -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub enum SymbolClass { - Function, - Data, -} - -impl SymbolClass { - pub fn ty(&self) -> crate::gen_flatbuffers::symbol_bin::SymbolClass { - match self { - SymbolClass::Function => { - crate::gen_flatbuffers::symbol_bin::SymbolClass::FunctionSymbolClass - } - SymbolClass::Data => crate::gen_flatbuffers::symbol_bin::SymbolClass::DataSymbolClass, - } - } - - pub fn create(&self, builder: &mut FlatBufferBuilder) -> WIPOffset { - match self { - SymbolClass::Function => FunctionSymbolClass.create(builder).as_union_value(), - SymbolClass::Data => DataSymbolClass.create(builder).as_union_value(), - } - } -} - -impl From> for SymbolClass { - fn from(_value: crate::gen_flatbuffers::symbol_bin::FunctionSymbolClass<'_>) -> Self { - Self::Function - } -} - -impl From> for SymbolClass { - fn from(_value: crate::gen_flatbuffers::symbol_bin::DataSymbolClass<'_>) -> Self { - Self::Data - } -} diff --git a/rust/tests/chunk.rs b/rust/tests/chunk.rs new file mode 100644 index 0000000..3564f1b --- /dev/null +++ b/rust/tests/chunk.rs @@ -0,0 +1,237 @@ +use warp::chunk::{Chunk, ChunkHandler, ChunkHeader, ChunkKind, ChunkType, CompressionType}; +use warp::mock::{ + mock_constraint, mock_enum_type_class, mock_float_type_class, mock_function, + mock_int_type_class, mock_type, +}; +use warp::r#type::chunk::TypeChunk; +use warp::r#type::guid::TypeGUID; +use warp::signature::chunk::SignatureChunk; +use warp::target::Target; + +#[test] +fn test_signature_chunk() { + let function_0 = mock_function("function_0"); + let function_1 = mock_function("function_1"); + let function_2 = mock_function("function_2"); + let functions = vec![function_0, function_1, function_2]; + let chunk = SignatureChunk::new(&functions).expect("Failed to create signature chunk"); + for function in functions { + let chunk_functions: Vec<_> = chunk.functions_with_guid(&function.guid).collect(); + assert_eq!(chunk_functions.len(), 1); + assert_eq!(chunk_functions[0], function); + } +} + +#[test] +fn test_type_chunk() { + let type_0 = mock_type("type_0", mock_int_type_class(None, false)); + let type_1 = mock_type("type_1", mock_float_type_class(None)); + let type_2 = mock_type("type_2", mock_enum_type_class(&type_0, &[("member", 0x10)])); + let types = vec![type_0, type_1, type_2]; + let chunk = TypeChunk::new(&types).expect("Failed to create type chunk"); + for ty in types { + let guid = TypeGUID::from(&ty); + let chunk_ty = chunk.type_with_guid(&guid).expect("Failed to get type"); + assert_eq!(chunk_ty, ty); + } +} + +#[test] +fn test_chunk_header() { + let signature_chunk = SignatureChunk::new(&vec![]).expect("Failed to create signature chunk"); + let chunk_kind = ChunkKind::Signature(signature_chunk); + let chunk_header = + ChunkHeader::from_chunk_kind(&chunk_kind, CompressionType::None, Target::default()); + assert_eq!(chunk_header.chunk_type, ChunkType::Signatures); + assert_eq!(chunk_header.version, chunk_kind.version()); + assert_eq!(chunk_header.compression_type, CompressionType::None); + assert_eq!(chunk_header.size, 24); +} + +#[test] +fn test_chunk_compression() { + let signature_chunk = SignatureChunk::new(&vec![]).expect("Failed to create signature chunk"); + let chunk_kind = ChunkKind::Signature(signature_chunk); + let chunk_header = + ChunkHeader::from_chunk_kind(&chunk_kind, CompressionType::Zstd, Target::default()); + assert_eq!(chunk_header.compression_type, CompressionType::Zstd); + assert_eq!( + chunk_header.size, 24, + "This should be the size of the uncompressed chunk" + ); + let data = chunk_kind.as_bytes(); + + // Compress the data using the chunk header's compression type. + let encoded_data = chunk_header + .encode_data(&data) + .expect("Failed to encode chunk data"); + assert_eq!( + encoded_data.len(), + 22, + "This should be the size of the compressed chunk" + ); + + // Decompress the data using the chunk header's compression type. + let decoded_data = chunk_header + .decode_data(&encoded_data) + .expect("Failed to decode chunk data"); + assert_eq!(decoded_data, data); +} + +#[test] +fn test_type_chunk_merging() { + let type_0 = mock_type("type_0", mock_int_type_class(None, false)); + let type_1 = mock_type("type_1", mock_float_type_class(None)); + let type_2 = mock_type("type_2", mock_enum_type_class(&type_0, &[("member", 0x10)])); + let types_3 = vec![type_0.clone(), type_1.clone(), type_2]; + let chunk_0 = TypeChunk::new(&types_3).expect("Failed to create type chunk"); + + let types_2 = vec![type_0, type_1]; + let chunk_1 = TypeChunk::new(&types_2).expect("Failed to create type chunk"); + + let type_3 = mock_type("type_3", mock_float_type_class(None)); + let types_1 = vec![type_3]; + let chunk_2 = TypeChunk::new(&types_1).expect("Failed to create type chunk"); + + let merged_chunk = + TypeChunk::merge(&[chunk_0, chunk_1, chunk_2]).expect("Failed to merge chunks"); + let merged_chunk_types: Vec<_> = merged_chunk.types().collect(); + assert_eq!( + merged_chunk_types.len(), + 4, + "Merging should eliminate duplicates" + ); +} + +#[test] +fn test_signature_chunk_merging() { + let function_0 = mock_function("function_0"); + let function_1 = mock_function("function_1"); + let function_2 = mock_function("function_2"); + let functions_3 = vec![function_0.clone(), function_1.clone(), function_2.clone()]; + let chunk_0 = SignatureChunk::new(&functions_3).expect("Failed to create signature chunk"); + + // Add a constraint to duplicate function_0 so we can make sure it is kept. + let mut function_0_with_constraint = function_0.clone(); + function_0_with_constraint + .constraints + .insert(mock_constraint("constraint_0", None)); + let functions_2 = vec![function_0_with_constraint.clone(), function_1]; + let chunk_1 = SignatureChunk::new(&functions_2).expect("Failed to create signature chunk"); + + let function_3 = mock_function("function_3"); + let functions_1 = vec![function_3]; + let chunk_2 = SignatureChunk::new(&functions_1).expect("Failed to create signature chunk"); + + let merged_chunk = SignatureChunk::merge(&[chunk_0, chunk_1, chunk_2.clone()]) + .expect("Failed to merge chunks"); + let merged_chunk_funcs: Vec<_> = merged_chunk.functions().collect(); + assert_eq!( + merged_chunk_funcs.len(), + 4, + "Merging should eliminate duplicates" + ); + + // We should have function_0 with the constraint, if it is missing, then the merging failed to preserve constraints. + merged_chunk_funcs + .into_iter() + .find(|f| f == &function_0_with_constraint) + .expect("Failed to find function_0 with constraint"); + + // Make sure functions with differing types are not merged. + let mut unique_function_3 = mock_function("function_3"); + unique_function_3.ty = Some(mock_type("test", mock_int_type_class(None, true))); + let unique_functions_1 = vec![unique_function_3]; + let unique_chunk_2 = + SignatureChunk::new(&unique_functions_1).expect("Failed to create signature chunk"); + + let merged_chunk = + SignatureChunk::merge(&[chunk_2.clone(), unique_chunk_2]).expect("Failed to merge chunks"); + let merged_chunk_funcs: Vec<_> = merged_chunk.functions().collect(); + assert_eq!( + merged_chunk_funcs.len(), + 2, + "Merging should keep same functions with different types" + ); + + // Make sure functions without a type are merged. + let mut untyped_function_3 = mock_function("function_3"); + untyped_function_3.ty = None; + let untyped_functions_1 = vec![untyped_function_3]; + let untyped_chunk_2 = + SignatureChunk::new(&untyped_functions_1).expect("Failed to create signature chunk"); + + let merged_chunk = SignatureChunk::merge(&[ + untyped_chunk_2.clone(), + chunk_2.clone(), + untyped_chunk_2.clone(), + ]) + .expect("Failed to merge chunks"); + let merged_chunk_funcs: Vec<_> = merged_chunk.functions().collect(); + assert_eq!( + merged_chunk_funcs.len(), + 1, + "Merging should merge same functions if missing type" + ); + assert!( + merged_chunk_funcs[0].ty.is_some(), + "Merged function missing type" + ); + + // Make sure functions with the same name but different GUID are not merged. + let mut guid_2_function_3 = mock_function("function_3"); + guid_2_function_3.guid = function_2.guid.clone(); + let guid_2_functions_1 = vec![guid_2_function_3]; + let guid_2_chunk_2 = + SignatureChunk::new(&guid_2_functions_1).expect("Failed to create signature chunk"); + + let merged_chunk = SignatureChunk::merge(&[ + guid_2_chunk_2.clone(), + chunk_2, + untyped_chunk_2, + guid_2_chunk_2, + ]) + .expect("Failed to merge chunks"); + let merged_chunk_funcs: Vec<_> = merged_chunk.functions().collect(); + println!("{:#?}", merged_chunk_funcs); + assert_eq!( + merged_chunk_funcs.len(), + 2, + "Merging should merge same functions if same guid" + ); +} + +#[test] +fn test_chunk_merging() { + // Test to make sure that chunks with different targets do not merge. + let function_0 = mock_function("function_0"); + let function_1 = mock_function("function_1"); + let function_2 = mock_function("function_2"); + let functions_3 = vec![function_0.clone(), function_1.clone(), function_2]; + let signature_chunk_0 = + SignatureChunk::new(&functions_3).expect("Failed to create signature chunk"); + let signature_chunk_1 = + SignatureChunk::new(&functions_3).expect("Failed to create signature chunk"); + let signature_chunk_2 = + SignatureChunk::new(&functions_3).expect("Failed to create signature chunk"); + let chunk_0 = Chunk::new( + ChunkKind::Signature(signature_chunk_0), + CompressionType::None, + ); + // Different compressions are ignored since we adjust the compression type when merging. + let chunk_1 = Chunk::new( + ChunkKind::Signature(signature_chunk_1), + CompressionType::Zstd, + ); + let chunk_2 = Chunk::new_with_target( + ChunkKind::Signature(signature_chunk_2), + CompressionType::None, + Target { + architecture: Some("hexagon".to_string()), + platform: None, + }, + ); + let merged_chunks = Chunk::merge(&[chunk_0, chunk_1, chunk_2], CompressionType::None); + println!("{:#?}", merged_chunks); + assert_eq!(merged_chunks.len(), 2); +} diff --git a/rust/tests/file.rs b/rust/tests/file.rs new file mode 100644 index 0000000..4425bc5 --- /dev/null +++ b/rust/tests/file.rs @@ -0,0 +1,61 @@ +use warp::chunk::{Chunk, ChunkKind, CompressionType}; +use warp::mock::mock_function; +use warp::signature::chunk::SignatureChunk; +use warp::{WarpFile, WarpFileHeader}; + +#[test] +fn test_file_creation() { + // Construct a signature chunk to check for on file creation. + let func_0 = mock_function("func_0"); + let func_1 = mock_function("func_1"); + let func_2 = mock_function("func_2"); + let funcs = vec![func_0, func_1, func_2]; + let signature_chunk = SignatureChunk::new(&funcs).expect("Failed to create signature chunk"); + let chunk_kind = ChunkKind::Signature(signature_chunk.clone()); + let chunk = Chunk::new(chunk_kind.clone(), CompressionType::None); + let compressed_chunk = Chunk::new(chunk_kind, CompressionType::Zstd); + let chunks = vec![chunk, compressed_chunk]; + + // Create the file and check the contents. + let file_header = WarpFileHeader::new(); + let file = WarpFile::new(file_header, chunks); + assert_eq!(file.header.version, 1); + assert_eq!(file.chunks.len(), 2); + assert_eq!( + file.chunks[0].kind, + ChunkKind::Signature(signature_chunk.clone()) + ); + assert_eq!( + file.chunks[1].kind, + ChunkKind::Signature(signature_chunk.clone()) + ); + + // Read the file back and check the contents. + let file_bytes = file.to_bytes(); + let file_read = WarpFile::from_bytes(&file_bytes).expect("Failed to read file"); + assert_eq!(file_read.header.version, 1); + assert_eq!( + file_read.chunks.len(), + 2, + "Both uncompressed and compressed chunk should have been read" + ); + assert_eq!( + file_read.chunks[0].kind, + ChunkKind::Signature(signature_chunk.clone()) + ); + assert_eq!( + file_read.chunks[1].kind, + ChunkKind::Signature(signature_chunk.clone()) + ); +} + +#[test] +fn test_file_format_regression() { + // Test that the "../fixtures/random.warp" file can be read. + // This file was created with a previous version of Warp and should still be readable. + // If this test fails, it means the format has changed in a backwards incompatible way. + let file_bytes = include_bytes!("../fixtures/random.warp"); + let _file_read = + WarpFile::from_bytes(file_bytes).expect("Failed to read file, format must have changed!"); + insta::assert_debug_snapshot!(_file_read); +} diff --git a/rust/tests/signature.rs b/rust/tests/signature.rs new file mode 100644 index 0000000..93407d1 --- /dev/null +++ b/rust/tests/signature.rs @@ -0,0 +1,16 @@ +use uuid::uuid; +use warp::signature::basic_block::BasicBlockGUID; +use warp::signature::function::FunctionGUID; + +#[test] +fn function_guid_creation() { + // Convert a set of basic blocks into a function guid. This should always be the same. + let bb_guid_0 = BasicBlockGUID::from(uuid!("e930c560-7b77-4f73-8b59-2ef6da75dcd4")); + let bb_guid_1 = BasicBlockGUID::from(uuid!("3a4bf915-666f-44ad-8a7e-a2fea8f3a62a")); + let bb_guid_2 = BasicBlockGUID::from(uuid!("0ffbfcd4-ac77-4b47-9696-006fa040167c")); + let basic_block_guids = [bb_guid_0, bb_guid_1, bb_guid_2]; + + let correct_func_guid = FunctionGUID::from(uuid!("1bef6187-74d9-5ebe-a0eb-4dbe6a97e578")); + let function_guid = FunctionGUID::from_basic_blocks(&basic_block_guids); + assert_eq!(function_guid, correct_func_guid); +} diff --git a/rust/tests/snapshots/file__file_format_regression.snap b/rust/tests/snapshots/file__file_format_regression.snap new file mode 100644 index 0000000..07d1f39 --- /dev/null +++ b/rust/tests/snapshots/file__file_format_regression.snap @@ -0,0 +1,6047 @@ +--- +source: rust/tests/file.rs +expression: _file_read +--- +WarpFile { + header: WarpFileHeader { + version: 1, + }, + chunks: [ + Chunk { + header: ChunkHeader { + version: 0, + chunk_type: Signatures, + compression_type: None, + size: 10884, + target: Target { + architecture: None, + platform: None, + }, + }, + kind: Signature( + SignatureChunk { + functions: [ + Function { + guid: FunctionGUID { + guid: 47e5c366-11e8-5acc-bb40-da91eae06fbd, + }, + symbol: Symbol { + name: "function_0", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_0", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: e550d12f-3d6b-5855-8b3a-a0c1bda3b48e, + }, + symbol: Symbol { + name: "function_1", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_1", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 0e9b8437-a86e-5228-8343-41ebe4ce05cf, + }, + symbol: Symbol { + name: "function_2", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_2", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: fc94532f-ed44-51d5-882a-aa5c4980496e, + }, + symbol: Symbol { + name: "function_3", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_3", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 20a29206-4520-53ca-9f4c-d394d5c4bfda, + }, + symbol: Symbol { + name: "function_4", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_4", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 7c00b3f9-177a-5de7-94ef-41ec082180d4, + }, + symbol: Symbol { + name: "function_5", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_5", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 2b14ea52-2ab4-5ee8-a571-79c9ea3711d0, + }, + symbol: Symbol { + name: "function_6", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_6", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 701b888b-a79d-5199-a1ea-3b192ca17707, + }, + symbol: Symbol { + name: "function_7", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_7", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 0f40101a-bf36-514d-86ae-f5e5b3bee204, + }, + symbol: Symbol { + name: "function_8", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_8", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 5d866bc0-04cb-5e97-8ad4-4822f232dff1, + }, + symbol: Symbol { + name: "function_9", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_9", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: cfd2b1b7-e309-5a5d-8242-44bc0dc6ea13, + }, + symbol: Symbol { + name: "function_10", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_10", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: f54be7f8-f209-5a11-80ab-41fddfc97091, + }, + symbol: Symbol { + name: "function_11", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_11", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 64882409-e03b-5865-af11-8749875a6912, + }, + symbol: Symbol { + name: "function_12", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_12", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: f985b081-39c1-5f33-bf4f-c6b08c51130b, + }, + symbol: Symbol { + name: "function_13", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_13", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 3ed101e1-14ab-53a7-a93b-113ef9a0f6c7, + }, + symbol: Symbol { + name: "function_14", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_14", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a094c60d-1f02-5902-8121-bb2702879f36, + }, + symbol: Symbol { + name: "function_15", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_15", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 9d693975-5b0f-599f-ae8a-2f55c5d7c0e0, + }, + symbol: Symbol { + name: "function_16", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_16", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: b37ace33-c367-56d2-94de-d45126d51f4a, + }, + symbol: Symbol { + name: "function_17", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_17", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 2a515920-ef5a-5c8e-b178-3f4c1ded59dd, + }, + symbol: Symbol { + name: "function_18", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_18", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 6582540b-5c8b-5f7b-b3d1-71f915c0f9b9, + }, + symbol: Symbol { + name: "function_19", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_19", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 5f874806-0e19-597b-a6db-36350ebbf94a, + }, + symbol: Symbol { + name: "function_20", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_20", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: b36f7c40-e634-5cc7-8b0f-bb2783049554, + }, + symbol: Symbol { + name: "function_21", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_21", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: e798c7b9-f35d-55a3-bea7-c1dda5bd358c, + }, + symbol: Symbol { + name: "function_22", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_22", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 89f4f527-9bac-57f6-8024-9bd61cb87cdc, + }, + symbol: Symbol { + name: "function_23", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_23", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 334e9f61-b413-5290-904c-c52df27c4390, + }, + symbol: Symbol { + name: "function_24", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_24", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 4e0890d0-7fc7-57ff-bd2e-d15ed73c8a23, + }, + symbol: Symbol { + name: "function_25", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_25", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 86ba8b42-0543-5567-98b3-7839676ed443, + }, + symbol: Symbol { + name: "function_26", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_26", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a9d91c54-b8b3-56ea-b698-0a81c814ad39, + }, + symbol: Symbol { + name: "function_27", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_27", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 7e58bb85-4424-5996-9a98-1df9b80f4a03, + }, + symbol: Symbol { + name: "function_28", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_28", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 000e8fb3-dde5-55a6-bb79-8178e98418c5, + }, + symbol: Symbol { + name: "function_29", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_29", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: f70a0325-f405-5300-b8d3-2d31d624440c, + }, + symbol: Symbol { + name: "function_30", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_30", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 787088c4-e3b9-5130-b8cf-d2024dcf5f0d, + }, + symbol: Symbol { + name: "function_31", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_31", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 3a571acf-fa2f-5675-af0c-1bb6315f5664, + }, + symbol: Symbol { + name: "function_32", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_32", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 0f68fb73-aab8-5742-908e-f5530f280688, + }, + symbol: Symbol { + name: "function_33", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_33", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: c5a40181-8dbe-5677-83d3-b86f3caffde2, + }, + symbol: Symbol { + name: "function_34", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_34", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 4e7d9c1a-1d1d-5542-b9af-f969e047f00d, + }, + symbol: Symbol { + name: "function_35", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_35", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 6656967d-3bf9-520f-9b2a-98c90789330a, + }, + symbol: Symbol { + name: "function_36", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_36", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: d456c4e2-1e3c-57e2-818e-87360e920ce2, + }, + symbol: Symbol { + name: "function_37", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_37", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 918c0b25-e41d-5155-8559-a6419cd35135, + }, + symbol: Symbol { + name: "function_38", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_38", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: ac7572d4-1d9e-5e11-8b8d-25f2ecb0f734, + }, + symbol: Symbol { + name: "function_39", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_39", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 50c41935-43df-5091-b08a-683cbcc87759, + }, + symbol: Symbol { + name: "function_40", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_40", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 4cbe95a3-4488-5bd8-94e1-8a6faf560fe9, + }, + symbol: Symbol { + name: "function_41", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_41", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 5adbc198-d1bf-5ec5-80b8-c256e3cee1c6, + }, + symbol: Symbol { + name: "function_42", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_42", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 63751c34-f074-5edf-8480-c89abe2ffc24, + }, + symbol: Symbol { + name: "function_43", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_43", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: ecddfc14-d136-5010-a256-2982279c5951, + }, + symbol: Symbol { + name: "function_44", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_44", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 4771f0e2-b929-54bf-8826-2401e5c662e1, + }, + symbol: Symbol { + name: "function_45", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_45", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 0c3f9a09-d142-5c0d-9165-cd08e46bb944, + }, + symbol: Symbol { + name: "function_46", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_46", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 8f45780e-2b07-5f60-af8d-80b7596ef596, + }, + symbol: Symbol { + name: "function_47", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_47", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 3685c0ae-6504-5559-b60a-d942bc8acb8d, + }, + symbol: Symbol { + name: "function_48", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_48", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 02cda7d8-b653-537a-a37c-a3374836ea58, + }, + symbol: Symbol { + name: "function_49", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_49", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 20b21abf-00c0-58ef-a8a5-800ea7b8f062, + }, + symbol: Symbol { + name: "function_50", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_50", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: ac430b9b-2929-59d6-99f9-32ac125701c5, + }, + symbol: Symbol { + name: "function_51", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_51", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: eb54ce6c-9700-549e-9b6e-95649d0ceeae, + }, + symbol: Symbol { + name: "function_52", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_52", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 85bfb1f0-a002-5c82-aa16-b2d0fee88ddd, + }, + symbol: Symbol { + name: "function_53", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_53", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: ad020d6a-6ade-5f8f-a5da-dd1eb3f7ffd2, + }, + symbol: Symbol { + name: "function_54", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_54", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 440caf4a-6fb4-5ea6-8386-f8aaffdca9b8, + }, + symbol: Symbol { + name: "function_55", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_55", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 1b081eba-1a18-594d-9bdf-db6ebf14b8ae, + }, + symbol: Symbol { + name: "function_56", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_56", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 6cfdf935-199f-53bb-b6ab-1a45b3d61c31, + }, + symbol: Symbol { + name: "function_57", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_57", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: fa8ab85c-b0fc-5a04-9029-8bac0be4b21a, + }, + symbol: Symbol { + name: "function_58", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_58", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 36a95ff0-5034-5e31-8ffa-a343140beb3c, + }, + symbol: Symbol { + name: "function_59", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_59", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 11c5242d-3251-5f3c-a055-580a2f20dd60, + }, + symbol: Symbol { + name: "function_60", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_60", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a9ea6de6-6e64-5270-8616-1ed189723093, + }, + symbol: Symbol { + name: "function_61", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_61", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 19afb645-71c3-5c08-a5fa-91486b22bd09, + }, + symbol: Symbol { + name: "function_62", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_62", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 91de36f5-e740-5c9b-a90c-41680d18b27d, + }, + symbol: Symbol { + name: "function_63", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_63", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 4cade36b-285f-58a1-b5f7-79d45962d7eb, + }, + symbol: Symbol { + name: "function_64", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_64", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 20bec564-2611-5b71-b396-b860cd86a7a4, + }, + symbol: Symbol { + name: "function_65", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_65", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: e439e9df-22ce-5d1d-907f-7fef18930e09, + }, + symbol: Symbol { + name: "function_66", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_66", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 0ea00cae-7dd3-5497-a1f5-013489ccf6e1, + }, + symbol: Symbol { + name: "function_67", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_67", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a10d925e-0e6c-5677-8478-19ec59ff802c, + }, + symbol: Symbol { + name: "function_68", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_68", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 64043f2d-cf4d-5736-a946-1f44a27fa82b, + }, + symbol: Symbol { + name: "function_69", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_69", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 62ff9387-fd9d-548d-abda-ea769945b7e4, + }, + symbol: Symbol { + name: "function_70", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_70", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 26588fd8-1ff3-51ed-8956-f569ca5347fc, + }, + symbol: Symbol { + name: "function_71", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_71", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: f6666a88-1a8c-54c6-bd02-92fce92c185f, + }, + symbol: Symbol { + name: "function_72", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_72", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 73b70c19-620d-5ace-9bd8-f9076f37acbb, + }, + symbol: Symbol { + name: "function_73", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_73", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 86bbe490-2bef-55b3-8c0d-6846dd00b22e, + }, + symbol: Symbol { + name: "function_74", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_74", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: af25b768-8cdd-5f7b-b08b-531ce2a93816, + }, + symbol: Symbol { + name: "function_75", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_75", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a0c873b3-d48e-5249-9637-c1a89674393a, + }, + symbol: Symbol { + name: "function_76", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_76", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 6b6c1d09-9097-57f0-a875-c7212ccd36e4, + }, + symbol: Symbol { + name: "function_77", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_77", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 673b9c33-38be-598a-9ed3-45e43271a41a, + }, + symbol: Symbol { + name: "function_78", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_78", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 46b61cd5-154e-5819-be81-2e37f405c531, + }, + symbol: Symbol { + name: "function_79", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_79", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a303e0de-fb79-5f10-bb32-ef8f633e1a8d, + }, + symbol: Symbol { + name: "function_80", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_80", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 8bd2ffa4-2677-5974-b8aa-6602f1c8e69d, + }, + symbol: Symbol { + name: "function_81", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_81", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: a7bdc76e-b8c7-5584-be8a-a1b0abfaa254, + }, + symbol: Symbol { + name: "function_82", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_82", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: ae76ddcb-d408-5853-81a3-87063a49d851, + }, + symbol: Symbol { + name: "function_83", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_83", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: f11338e2-2577-59f0-87c5-47e5b911f08b, + }, + symbol: Symbol { + name: "function_84", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_84", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: ba0566fb-dab7-5d6d-8e47-e53160e3e348, + }, + symbol: Symbol { + name: "function_85", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_85", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 0eff8295-4f93-5457-a8d6-779167473e1e, + }, + symbol: Symbol { + name: "function_86", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_86", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: e249c10b-b0d5-5a0b-a4f7-eb165f1248c9, + }, + symbol: Symbol { + name: "function_87", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_87", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 8bdacf7b-eaf1-54b6-8add-622a8fa7798b, + }, + symbol: Symbol { + name: "function_88", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_88", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: d6bb22c0-ea48-575e-8612-0f1dfdaf9735, + }, + symbol: Symbol { + name: "function_89", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_89", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 461e7aa4-c954-5a62-a9db-9705a5e7c6b0, + }, + symbol: Symbol { + name: "function_90", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_90", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 3c0c7c36-025c-5087-9c84-c86b1a6779b8, + }, + symbol: Symbol { + name: "function_91", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_91", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 5728b6b9-7e60-52e8-b01b-d956e74e3689, + }, + symbol: Symbol { + name: "function_92", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_92", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: b866d4ec-5364-5d53-a600-3e645474cb84, + }, + symbol: Symbol { + name: "function_93", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_93", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: d12a5396-f7c4-5342-b866-247054dd3317, + }, + symbol: Symbol { + name: "function_94", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_94", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: d5da0413-a020-5db8-b838-4d0ea8bd3dcb, + }, + symbol: Symbol { + name: "function_95", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_95", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: fd871881-d973-5357-ac62-5abf9184ea2b, + }, + symbol: Symbol { + name: "function_96", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_96", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 8f6ceb6b-3b4b-5a66-a509-ebc5a3c1c38e, + }, + symbol: Symbol { + name: "function_97", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_97", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: e1ce2148-c4ff-52e9-8f77-ec67e0ead8a0, + }, + symbol: Symbol { + name: "function_98", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_98", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + Function { + guid: FunctionGUID { + guid: 4d6f3841-7b22-521a-99fe-fe320ee60d7b, + }, + symbol: Symbol { + name: "function_99", + modifiers: SymbolModifiers( + 0x0, + ), + class: Function, + }, + ty: Some( + Type { + name: Some( + "function_99", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + ), + constraints: {}, + comments: [], + variables: [], + }, + ], + }, + ), + }, + Chunk { + header: ChunkHeader { + version: 0, + chunk_type: Types, + compression_type: Zstd, + size: 7676, + target: Target { + architecture: None, + platform: None, + }, + }, + kind: Type( + TypeChunk { + types: [ + ComputedType { + guid: TypeGUID { + guid: 73391967-a387-5826-892f-96ac3402aaa0, + }, + ty: Type { + name: Some( + "type_0", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 84566260-9dd3-5494-a9c8-8a76ea49c044, + }, + ty: Type { + name: Some( + "type_1", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: f2c818eb-ef9f-5851-8d46-cf39b98a42ca, + }, + ty: Type { + name: Some( + "type_2", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 9748cee6-c47c-55c4-93fe-7fdf4b7b3aaf, + }, + ty: Type { + name: Some( + "type_3", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: edd60b28-e1a9-51ff-a9a7-566ececc217c, + }, + ty: Type { + name: Some( + "type_4", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 64081c88-8351-52df-860e-53aa290d9d21, + }, + ty: Type { + name: Some( + "type_5", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: c9c6bd72-5e64-522a-8df3-75ff97b7f30a, + }, + ty: Type { + name: Some( + "type_6", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e2ddd732-f01e-5368-8443-d552a23921c7, + }, + ty: Type { + name: Some( + "type_7", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 11ef4aec-e0d6-523e-87ea-4ce44e687075, + }, + ty: Type { + name: Some( + "type_8", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 1ac716e0-9d7f-5361-924f-f6f37a631268, + }, + ty: Type { + name: Some( + "type_9", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 2f6d2876-ec42-5ca1-bee3-f12fe91d7e13, + }, + ty: Type { + name: Some( + "type_10", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 657f88df-4822-5393-86c8-014ef9c01018, + }, + ty: Type { + name: Some( + "type_11", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e63110a6-4603-5b46-964c-e635159a3c89, + }, + ty: Type { + name: Some( + "type_12", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 79cdabbe-837f-56c6-8c64-76c920e6e9bf, + }, + ty: Type { + name: Some( + "type_13", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 9ac4e81c-6b74-5d46-941b-ec1155931fa6, + }, + ty: Type { + name: Some( + "type_14", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d8a52afc-1488-55b4-9a47-47e080c6cf13, + }, + ty: Type { + name: Some( + "type_15", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: dffe7b1a-0583-50bb-8475-d51b99208e45, + }, + ty: Type { + name: Some( + "type_16", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d6dc5b20-e232-53d5-98c3-f52a4748a5c4, + }, + ty: Type { + name: Some( + "type_17", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 2a0a4780-5170-5249-ae90-6dea387d1e1a, + }, + ty: Type { + name: Some( + "type_18", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 51d79dc5-9a06-5489-8c35-c2150a1a65ad, + }, + ty: Type { + name: Some( + "type_19", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d90ad165-9cfc-552c-8df6-8c11ef8bdeaa, + }, + ty: Type { + name: Some( + "type_20", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d5444661-fa24-55fb-a439-1de4301cd078, + }, + ty: Type { + name: Some( + "type_21", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 80a982f3-8c49-5960-8814-12dd233ab14b, + }, + ty: Type { + name: Some( + "type_22", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 939a2d70-0121-5916-9f18-d9e69364318e, + }, + ty: Type { + name: Some( + "type_23", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 78d6d50b-a45c-5bbf-9898-0c4b32f833e0, + }, + ty: Type { + name: Some( + "type_24", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: a67eb15a-d4cb-5118-b3a7-8d705726054c, + }, + ty: Type { + name: Some( + "type_25", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: fd181b20-4a6a-51b3-9e6a-cb9cb3698d9b, + }, + ty: Type { + name: Some( + "type_26", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 1c033abd-e9fa-55ac-9be4-65539722c2f9, + }, + ty: Type { + name: Some( + "type_27", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 8f232a46-baf1-5478-9aba-79a52198cd88, + }, + ty: Type { + name: Some( + "type_28", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d2cbdd16-3439-5ca8-b156-151c9b474f74, + }, + ty: Type { + name: Some( + "type_29", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 55ad2a41-7670-5ed0-a679-e2d132c694b0, + }, + ty: Type { + name: Some( + "type_30", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 2f66f763-1085-583f-bed3-a05c2d13e89f, + }, + ty: Type { + name: Some( + "type_31", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d8433e83-ddb1-5400-a623-c4637c44599e, + }, + ty: Type { + name: Some( + "type_32", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 328345a7-0eef-54bc-8e53-19824c813cfa, + }, + ty: Type { + name: Some( + "type_33", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e3b0a960-9993-5f42-ba5c-19210cbdede3, + }, + ty: Type { + name: Some( + "type_34", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: a6db066c-20de-5445-a56b-346ae47a1db0, + }, + ty: Type { + name: Some( + "type_35", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 412505bd-be31-5eb9-a6a9-01f8d9eaa1ca, + }, + ty: Type { + name: Some( + "type_36", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e7d27d61-2f85-5e77-978e-2d5e75b3dc1f, + }, + ty: Type { + name: Some( + "type_37", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 5808d16d-d421-5d7d-ab39-6df5823580c0, + }, + ty: Type { + name: Some( + "type_38", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 32d5aec0-a08c-54ce-9fd8-2d86213136f2, + }, + ty: Type { + name: Some( + "type_39", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 71737490-6519-5970-aa9b-9bd2cb2b5e56, + }, + ty: Type { + name: Some( + "type_40", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 312b84f7-29b4-5ba1-8da5-b783a7cc7f27, + }, + ty: Type { + name: Some( + "type_41", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 729632e0-1431-534c-8f3f-ba560218e68a, + }, + ty: Type { + name: Some( + "type_42", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 586da437-c0ee-5f60-a470-484b0f8388a6, + }, + ty: Type { + name: Some( + "type_43", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 7268eb3a-0c2d-5444-9ee0-248eacf44f9b, + }, + ty: Type { + name: Some( + "type_44", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 6501dba2-6f24-5d5d-8f16-d29c458a4447, + }, + ty: Type { + name: Some( + "type_45", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 3ee4ccc4-e612-5e2f-ad46-7916e05ecbce, + }, + ty: Type { + name: Some( + "type_46", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 1542a6e7-4ed5-5ae7-8671-dded99b5bcf6, + }, + ty: Type { + name: Some( + "type_47", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 7192092c-145c-50c8-911b-f2dc806b03e8, + }, + ty: Type { + name: Some( + "type_48", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 67d94c59-08bb-584e-be87-68a2afd338c6, + }, + ty: Type { + name: Some( + "type_49", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: aa8df21e-d3db-5465-a3bc-1899b60cb4be, + }, + ty: Type { + name: Some( + "type_50", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 5662e675-9385-51c1-a035-a4c5f0a28ea7, + }, + ty: Type { + name: Some( + "type_51", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 08d5db3d-8b56-5d1d-9410-f34fd08cc811, + }, + ty: Type { + name: Some( + "type_52", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: b447b7a0-0fa6-5706-8876-008f955fc592, + }, + ty: Type { + name: Some( + "type_53", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 8366a5de-156b-5a13-a742-fb10efb8a464, + }, + ty: Type { + name: Some( + "type_54", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: c65e6e4d-5c9b-5888-98b1-49ef9992d083, + }, + ty: Type { + name: Some( + "type_55", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 6c4786cd-a875-5c1f-98c6-9c0e8d0d0e65, + }, + ty: Type { + name: Some( + "type_56", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 839e47be-d25d-59d9-bbc1-ee46675bd73b, + }, + ty: Type { + name: Some( + "type_57", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 75dc53a5-dfa3-5eff-9098-34be216979a1, + }, + ty: Type { + name: Some( + "type_58", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: bd20c401-9e5f-5978-a4b6-1ce7a69f4c57, + }, + ty: Type { + name: Some( + "type_59", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: c6109878-f25a-537b-85e5-549db2bd1de4, + }, + ty: Type { + name: Some( + "type_60", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 21ef683c-9227-52f3-b326-f1b9157f3303, + }, + ty: Type { + name: Some( + "type_61", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: fa0519f3-9455-5503-83e7-e9a00945c1dd, + }, + ty: Type { + name: Some( + "type_62", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e943347c-c5d5-5905-87e2-627a48e4be8f, + }, + ty: Type { + name: Some( + "type_63", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e3e9717c-a085-536d-8e99-5322cbab2e7a, + }, + ty: Type { + name: Some( + "type_64", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: bf7ba333-8225-521c-abe6-a42d758979bd, + }, + ty: Type { + name: Some( + "type_65", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d947721a-a781-551c-8077-2bb531c9d752, + }, + ty: Type { + name: Some( + "type_66", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 7f94bf30-01ac-5b4a-b18e-8ab714e6494c, + }, + ty: Type { + name: Some( + "type_67", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e95e40bf-c6f5-58ca-b18c-7d79617ea1d3, + }, + ty: Type { + name: Some( + "type_68", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: d9120371-efda-5296-8afb-b3ddadacbd31, + }, + ty: Type { + name: Some( + "type_69", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 42474d34-9691-54d0-8979-c35cc1032927, + }, + ty: Type { + name: Some( + "type_70", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 297b1454-a72a-5154-95d1-cc8ca2419b3c, + }, + ty: Type { + name: Some( + "type_71", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 52b0292a-c668-5327-8d76-d31c5cd9da79, + }, + ty: Type { + name: Some( + "type_72", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: a0f5518f-3b3a-5fb7-b812-6e8f284d7ae2, + }, + ty: Type { + name: Some( + "type_73", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: f8cea3b0-ee48-5d4c-b4ad-3c794edbb968, + }, + ty: Type { + name: Some( + "type_74", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 8e7a2a84-d808-5345-9b1d-08f0b3748039, + }, + ty: Type { + name: Some( + "type_75", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 34177383-610e-594d-bb7e-629fd0c16270, + }, + ty: Type { + name: Some( + "type_76", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: c3d6b55d-77c0-5147-b33a-5c3472714a04, + }, + ty: Type { + name: Some( + "type_77", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 180be010-1b39-5912-867f-611de9b33294, + }, + ty: Type { + name: Some( + "type_78", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: ba7905bd-2ebb-568b-8861-7ff2ec360102, + }, + ty: Type { + name: Some( + "type_79", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 2126e136-935f-5171-a261-78d82f5fa9fb, + }, + ty: Type { + name: Some( + "type_80", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 98a3ad85-2a8e-5ac2-9a76-fa5c36a6314e, + }, + ty: Type { + name: Some( + "type_81", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 8c84eb9a-51c5-5756-820b-16c3f6bf461e, + }, + ty: Type { + name: Some( + "type_82", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 591fce93-db36-5937-9da8-386e9ae65d24, + }, + ty: Type { + name: Some( + "type_83", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 13b382e7-a0f9-5bf3-924f-74d8b62aeabb, + }, + ty: Type { + name: Some( + "type_84", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: cc967754-8085-5b37-814e-fb89051ce27e, + }, + ty: Type { + name: Some( + "type_85", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 8b679a57-b0d7-5313-b04e-ea1113c32b2c, + }, + ty: Type { + name: Some( + "type_86", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 9e843f37-a18e-5d4d-8b60-7f4f10ddaa41, + }, + ty: Type { + name: Some( + "type_87", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 8ee691db-7b21-5c75-84ea-cb7b5a90b7ae, + }, + ty: Type { + name: Some( + "type_88", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: e7ef0db0-8a0c-5f57-8a8f-1f1fd015966a, + }, + ty: Type { + name: Some( + "type_89", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 93eedb28-6acd-502b-86cc-65c9de2ee6a2, + }, + ty: Type { + name: Some( + "type_90", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 6c87ae1b-fe42-59de-b4c7-583c171d9547, + }, + ty: Type { + name: Some( + "type_91", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: fd700cba-0df5-57a2-b973-44f269e2b962, + }, + ty: Type { + name: Some( + "type_92", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 89874887-6ae5-53c2-ab5d-3c15ef0eb094, + }, + ty: Type { + name: Some( + "type_93", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: b39dd264-c9f1-5fd1-902d-b43cbf3814a9, + }, + ty: Type { + name: Some( + "type_94", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: bf649a42-6506-5d2d-bba1-feb32aaa3501, + }, + ty: Type { + name: Some( + "type_95", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: c9bfa6eb-58f1-52c2-96a0-c667047e2bcd, + }, + ty: Type { + name: Some( + "type_96", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 6ec1258d-3f02-50f2-8712-0b4db372b182, + }, + ty: Type { + name: Some( + "type_97", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: 1e611de4-52f3-5cbc-b72e-b1b9ba0906ee, + }, + ty: Type { + name: Some( + "type_98", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ComputedType { + guid: TypeGUID { + guid: b03953bb-69f5-5258-a373-e31500ffcd27, + }, + ty: Type { + name: Some( + "type_99", + ), + class: Function( + FunctionClass { + calling_convention: None, + in_members: [], + out_members: [], + }, + ), + confidence: 255, + modifiers: TypeModifiers( + 0x0, + ), + metadata: [], + alignment: Access, + ancestors: [], + }, + }, + ], + }, + ), + }, + ], +} diff --git a/rust/tests/types.rs b/rust/tests/types.rs new file mode 100644 index 0000000..8ffdcb4 --- /dev/null +++ b/rust/tests/types.rs @@ -0,0 +1,142 @@ +use uuid::uuid; +use warp::mock::{ + mock_array_type_class, mock_bool_type_class, mock_char_type_class, mock_enum_type_class, + mock_float_type_class, mock_function_type_class, mock_int_type_class, mock_ptr_type_class, + mock_struct_type_class, mock_type, mock_type_metadata, mock_type_ref_type_class, + mock_union_type_class, +}; +use warp::r#type::guid::TypeGUID; +use warp::r#type::{Alignment, ComputedType, Type, TypeModifiers}; + +#[test] +fn test_type_creation() { + let bool_type = mock_type("bool", mock_bool_type_class()); + let int_type = mock_type("int", mock_int_type_class(None, true)); + let char_type = mock_type("char", mock_char_type_class(None)); + let float_type = mock_type("float", mock_float_type_class(None)); + let array_type = mock_type("array", mock_array_type_class(&float_type, 3)); + let ptr_type = mock_type("ptr", mock_ptr_type_class(&int_type, None)); + let ref_type = mock_type("ref", mock_type_ref_type_class(&int_type)); + let func_type = mock_type("func", mock_function_type_class()); + let struct_type = mock_type( + "struct", + mock_struct_type_class(&[(0, "field_0", &bool_type), (32, "field_4", &array_type)]), + ); + let union_type = mock_type( + "union", + mock_union_type_class(&[("member_0", &int_type), ("member_1", &array_type)]), + ); + let enum_type = mock_type( + "enum", + mock_enum_type_class(&int_type, &[("item_0", 0), ("item_1", 1)]), + ); + + // Take all of these types and create the flatbuffer object for them, then check that the flatbuffer object is valid. + let types = [ + bool_type, + int_type, + char_type, + float_type, + array_type, + ptr_type, + ref_type, + func_type, + struct_type, + union_type, + enum_type, + ]; + for ty in types { + let ty_bytes = ty.to_bytes(); + let ty_from_bytes = Type::from_bytes(&ty_bytes).expect("Valid type from bytes"); + assert_eq!(ty, ty_from_bytes); + } +} + +#[test] +fn test_type_sizing() { + let int_type = mock_type("int", mock_int_type_class(None, true)); + assert_eq!(int_type.size(), None); + let int32_type = mock_type("int32", mock_int_type_class(Some(32), true)); + assert_eq!(int32_type.size(), Some(32)); + let float16_type = mock_type("float16", mock_float_type_class(Some(16))); + assert_eq!(float16_type.size(), Some(16)); + let char8 = mock_type("char8", mock_char_type_class(Some(8))); + assert_eq!(char8.size(), Some(8)); + let array_type = mock_type("array", mock_array_type_class(&float16_type, 3)); + assert_eq!(array_type.size(), Some(16 * 3)); + let ptr64_type = mock_type("ptr64", mock_ptr_type_class(&int_type, Some(64))); + assert_eq!(ptr64_type.size(), Some(64)); + let ref_type = mock_type("ref", mock_type_ref_type_class(&int_type)); + assert_eq!(ref_type.size(), None); + let func_type = mock_type("func", mock_function_type_class()); + assert_eq!(func_type.size(), None); + let struct_type = mock_type( + "struct", + mock_struct_type_class(&[(0, "field_0", &int32_type), (32, "field_4", &array_type)]), + ); + assert_eq!(struct_type.size(), Some(32 + 16 * 3)); + let union_type = mock_type( + "union", + mock_union_type_class(&[("member_0", &int32_type), ("member_1", &array_type)]), + ); + assert_eq!(union_type.size(), array_type.size()); + let enum_type = mock_type( + "enum", + mock_enum_type_class(&int32_type, &[("item_0", 0), ("item_1", 1)]), + ); + assert_eq!(enum_type.size(), Some(32)); +} + +#[test] +fn test_type_metadata() { + let mut int_type = mock_type("int", mock_int_type_class(None, true)); + // We should never implicitly store metadata. + assert!(int_type.metadata.is_empty()); + int_type.metadata.push(mock_type_metadata("my_metadata")); + assert_eq!(int_type.metadata.len(), 1); + + // Round-trip it through flatbuffers to make sure the metadata is kept. + let ty_bytes = int_type.to_bytes(); + let ty_from_bytes = Type::from_bytes(&ty_bytes).expect("Valid type from bytes"); + assert_eq!(ty_from_bytes, int_type); +} + +#[test] +fn test_type_modifiers() { + let mut int_type = mock_type("int", mock_int_type_class(None, true)); + // We should never implicitly add modifiers. + assert!(!int_type.is_const()); + assert!(!int_type.is_volatile()); + int_type.modifiers.set(TypeModifiers::Constant, true); + assert!(int_type.is_const()); + int_type.modifiers.set(TypeModifiers::Volatile, true); + assert!(int_type.is_volatile()); + + // Round-trip it through flatbuffers to make sure the modifiers are kept. + let ty_bytes = int_type.to_bytes(); + let ty_from_bytes = Type::from_bytes(&ty_bytes).expect("Valid type from bytes"); + assert_eq!(ty_from_bytes, int_type); +} + +#[test] +fn test_type_alignment() { + let mut int_type = mock_type("int", mock_int_type_class(None, true)); + // We should always be naturally aligned by default. + assert_eq!(int_type.alignment, Alignment::Access); + // Fixed with 8 bits is considered __packed. + int_type.alignment = Alignment::Fixed(8); + + // Round-trip it through flatbuffers to make sure alignment is kept. + let ty_bytes = int_type.to_bytes(); + let ty_from_bytes = Type::from_bytes(&ty_bytes).expect("Valid type from bytes"); + assert_eq!(ty_from_bytes, int_type); +} + +#[test] +fn test_computed_type() { + let int_type = mock_type("int", mock_int_type_class(None, true)); + let computed_int_type = ComputedType::new(int_type.clone()); + assert_eq!(computed_int_type.ty, int_type); + let correct_type_guid = TypeGUID::from(uuid!("9f5eb7e0-986a-5af2-aa37-798b2bafae10")); + assert_eq!(computed_int_type.guid, correct_type_guid); +} diff --git a/rust/type.rs b/rust/type.rs deleted file mode 100644 index 9321dcf..0000000 --- a/rust/type.rs +++ /dev/null @@ -1,293 +0,0 @@ -use bon::bon; - -use crate::fb_type as fb; -use crate::r#type::class::TypeClass; -use crate::r#type::guid::TypeGUID; -use crate::r#type::modifier::{TypeModifier, TypeModifierClass}; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Alphanumeric, DistString, Distribution, Standard}; -use rand::Rng; - -pub mod class; -pub mod guid; -pub mod modifier; - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct ComputedType { - pub guid: TypeGUID, - pub ty: Type, -} - -impl ComputedType { - pub fn new(ty: Type) -> ComputedType { - let guid = TypeGUID::from(&ty); - Self::new_with_guid(ty, guid) - } - - pub fn new_with_guid(ty: Type, guid: TypeGUID) -> ComputedType { - ComputedType { guid, ty } - } - - pub fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let created_ty = self.ty.create(builder); - let guid_str = builder.create_string(&self.guid.to_string()); - fb::ComputedType::create( - builder, - &fb::ComputedTypeArgs { - guid: Some(guid_str), - type_: Some(created_ty), - }, - ) - } -} - -// TODO: Clearly this might fail, we should make this TryFrom. -impl From> for ComputedType { - fn from(value: fb::ComputedType<'_>) -> Self { - let ty: Type = value.type_().unwrap().into(); - let guid = value.guid().parse::().unwrap(); - Self::new_with_guid(ty, guid) - } -} - -#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub enum Alignment { - #[default] - Access, - Fixed(u16), -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Type { - pub name: Option, - pub class: Box, - // TODO: Type confidence? - pub confidence: u8, - pub modifiers: Vec, - pub alignment: Alignment, - pub ancestors: Vec, -} - -#[bon] -impl Type { - #[builder] - pub fn new>( - name: Option, - class: impl Into, - confidence: Option, - modifiers: Option>, - alignment: Option, - ancestors: Option>, - ) -> Self { - Self { - name: name.map(|n| n.into()), - class: Box::new(class.into()), - confidence: confidence.unwrap_or(u8::MAX), - modifiers: modifiers.unwrap_or_default(), - alignment: alignment.unwrap_or_default(), - ancestors: ancestors.unwrap_or_default(), - } - } -} - -impl Type { - /// Copy a type and make it an ancestor, effectively allowing a mutation of the type. - pub fn from_ancestor(ancestor: &Type) -> Self { - let mut new_type = ancestor.clone(); - new_type.ancestors.push(TypeGUID::from(ancestor)); - new_type - } - - pub fn from_bytes(buf: &[u8]) -> Option { - flatbuffers::root::(buf).ok().map(Into::into) - } - - pub fn to_bytes(&self) -> Vec { - let mut builder = FlatBufferBuilder::new(); - let fb_type = self.create(&mut builder); - builder.finish_minimal(fb_type); - builder.finished_data().to_vec() - } - - pub fn is_const(&self) -> bool { - self.modifiers - .contains(&TypeModifier::new(TypeModifierClass::Constant)) - } - - pub fn is_volatile(&self) -> bool { - self.modifiers - .contains(&TypeModifier::new(TypeModifierClass::Volatile)) - } - - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let name = self.name.as_ref().map(|n| builder.create_string(n)); - let class_type = self.class.ty(); - let class = self.class.create(builder); - - let mut ancestors = None; - if !self.ancestors.is_empty() { - let _ancestors = self - .ancestors - .iter() - .map(|a| builder.create_string(&a.to_string())) - .collect::>(); - ancestors = Some(builder.create_vector(&_ancestors)); - } - - let mut modifiers = None; - if !self.modifiers.is_empty() { - let _modifiers = self - .modifiers - .iter() - .map(|modifier| modifier.create(builder)) - .collect::>(); - modifiers = Some(builder.create_vector(&_modifiers)); - } - - fb::Type::create( - builder, - &fb::TypeArgs { - name, - class_type, - class: Some(class), - confidence: self.confidence, - ancestors, - modifiers, - // TODO: Alignment - alignment_type: Default::default(), - alignment_: None, - }, - ) - } - - pub fn size(&self) -> Option { - self.class.size() - } -} - -impl From> for Type { - fn from(value: fb::Type<'_>) -> Self { - let name = value.name().map(str::to_string); - - let from_type_class = |type_class: fb::TypeClass| match type_class { - fb::TypeClass::Void => Some(TypeClass::Void), - fb::TypeClass::Boolean => { - let bool = value.class_as_boolean()?; - Some(TypeClass::Boolean(bool.into())) - } - fb::TypeClass::Integer => { - let int = value.class_as_integer()?; - Some(TypeClass::Integer(int.into())) - } - fb::TypeClass::Character => { - let charcter = value.class_as_character()?; - Some(TypeClass::Character(charcter.into())) - } - fb::TypeClass::Float => { - let float = value.class_as_float()?; - Some(TypeClass::Float(float.into())) - } - fb::TypeClass::Pointer => { - let ptr = value.class_as_pointer()?; - Some(TypeClass::Pointer(ptr.into())) - } - fb::TypeClass::Array => { - let array = value.class_as_array()?; - Some(TypeClass::Array(array.into())) - } - fb::TypeClass::Structure => { - let structure = value.class_as_structure()?; - Some(TypeClass::Structure(structure.into())) - } - fb::TypeClass::Enumeration => { - let enumeration = value.class_as_enumeration()?; - Some(TypeClass::Enumeration(enumeration.into())) - } - fb::TypeClass::Union => { - let union = value.class_as_union()?; - Some(TypeClass::Union(union.into())) - } - fb::TypeClass::Function => { - let function = value.class_as_function()?; - Some(TypeClass::Function(function.into())) - } - fb::TypeClass::Referrer => { - let referrer = value.class_as_referrer()?; - Some(TypeClass::Referrer(referrer.into())) - } - _ => unreachable!(), - }; - - let class = from_type_class(value.class_type()).unwrap(); - - Self { - name, - class: Box::new(class), - confidence: value.confidence(), - // TODO: Get modifiers - modifiers: vec![], - // TODO: Get alignment - alignment: Default::default(), - ancestors: value - .ancestors() - .unwrap_or_default() - .iter() - .filter_map(|a| a.parse().ok()) - .collect(), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> Type { - // 90% chance this type will have a name. - let name = match rng.gen_bool(0.9) { - true => Some(Alphanumeric.sample_string(rng, 16)), - false => None, - }; - Type { - name, - class: Box::new(rng.gen()), - // class: Box::new(TypeClass::Void), - confidence: rng.gen(), - // TODO: Modifiers - modifiers: vec![], - // TODO: Alignment - alignment: Default::default(), - // TODO: Ancestors - ancestors: vec![], - } - } -} - -#[cfg(test)] -mod tests { - use crate::r#type::guid::TypeGUID; - use crate::r#type::Type; - use rand::Rng; - use std::collections::HashSet; - - #[test] - fn test_determinism() { - let mut rng = rand::thread_rng(); - // Test to make sure that for any given type the uuid will always be the same. - for _ in 0..1000 { - let random_type: Type = rng.gen(); - let mut guids: HashSet = HashSet::new(); - for _ in 0..100 { - guids.insert(random_type.to_owned().into()); - } - assert_eq!(guids.len(), 1, "{:?}", guids); - let buf = random_type.to_bytes(); - let fb_rand_type = Type::from_bytes(buf.as_slice()).unwrap(); - assert_eq!(random_type, fb_rand_type); - assert_eq!(TypeGUID::from(random_type), TypeGUID::from(fb_rand_type)); - } - } -} diff --git a/rust/type/class/boolean.rs b/rust/type/class/boolean.rs deleted file mode 100644 index bed1c5e..0000000 --- a/rust/type/class/boolean.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::fb_type as fb; -use bon::Builder; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct BooleanClass { - pub width: Option, -} - -impl BooleanClass { - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - fb::Boolean::create( - builder, - &fb::BooleanArgs { - width: self.width.map(Into::into).as_ref(), - }, - ) - } - - pub fn size(&self) -> Option { - self.width.map(|w| w as u64) - } -} - -impl From> for BooleanClass { - fn from(value: fb::Boolean<'_>) -> Self { - Self { - width: value.width().map(Into::into), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> BooleanClass { - // TODO: Maybe we should restrict this to "normal" widths? - BooleanClass { width: rng.gen() } - } -} diff --git a/rust/type/class/character.rs b/rust/type/class/character.rs deleted file mode 100644 index fe1bdd9..0000000 --- a/rust/type/class/character.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::fb_type as fb; -use bon::Builder; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct CharacterClass { - /// Width in bits - pub width: Option, -} - -impl CharacterClass { - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - fb::Character::create( - builder, - &fb::CharacterArgs { - width: self.width.map(Into::into).as_ref(), - }, - ) - } - - pub fn size(&self) -> Option { - self.width.map(|w| w as u64) - } -} - -impl From> for CharacterClass { - fn from(value: fb::Character<'_>) -> Self { - Self { - width: value.width().map(Into::into), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> CharacterClass { - // 90% chance this type will have a width. - let width = match rng.gen_bool(0.9) { - true => Some(rng.gen_range(1..=256)), - false => None, - }; - CharacterClass { width } - } -} diff --git a/rust/type/class/float.rs b/rust/type/class/float.rs deleted file mode 100644 index 86bb1b7..0000000 --- a/rust/type/class/float.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::fb_type as fb; -use bon::Builder; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Distribution, Standard}; -use rand::Rng; - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct FloatClass { - /// Width in bits - pub width: Option, -} - -impl FloatClass { - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - fb::Float::create( - builder, - &fb::FloatArgs { - width: self.width.map(Into::into).as_ref(), - }, - ) - } - - pub fn size(&self) -> Option { - self.width.map(|w| w as u64) - } -} - -impl From> for FloatClass { - fn from(value: fb::Float<'_>) -> Self { - Self { - width: value.width().map(Into::into), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> FloatClass { - // 90% chance this type will have a width. - let width = match rng.gen_bool(0.9) { - true => Some(rng.gen_range(1..=256)), - false => None, - }; - FloatClass { width } - } -} diff --git a/rust/type/class/function.rs b/rust/type/class/function.rs deleted file mode 100644 index 23c7fab..0000000 --- a/rust/type/class/function.rs +++ /dev/null @@ -1,233 +0,0 @@ -use crate::fb_type as fb; -use crate::r#type::Type; -use bon::{bon, Builder}; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Alphanumeric, DistString, Distribution, Standard}; -use rand::Rng; - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct RegisterLocation; - -impl From> for RegisterLocation { - fn from(_value: fb::RegisterLocation<'_>) -> Self { - Self - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct StackLocation { - offset: i64, -} - -impl From> for StackLocation { - fn from(_value: fb::StackLocation<'_>) -> Self { - Self { - offset: _value.offset().into(), - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum Location { - Register(RegisterLocation), - Stack(StackLocation), -} - -impl From> for Location { - fn from(value: fb::FunctionMemberLocation<'_>) -> Self { - match value.class_type() { - fb::LocationClass::RegisterLocation => { - let register_loc = value.class_as_register_location().unwrap(); - Self::Register(register_loc.into()) - } - fb::LocationClass::StackLocation => { - let stack_loc = value.class_as_stack_location().unwrap(); - Self::Stack(stack_loc.into()) - } - _ => unreachable!(), - } - } -} - -// TODO: Add Builder derive? -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct FunctionMember { - pub name: Option, - pub ty: Type, - // TODO: Technically optional. - pub locations: Vec, -} - -impl From> for FunctionMember { - fn from(value: fb::FunctionMember<'_>) -> Self { - Self { - name: value.name().map(str::to_string), - ty: value.type_().into(), - locations: value - .locations() - .unwrap_or_default() - .iter() - .map(Into::into) - .collect(), - } - } -} - -#[bon] -impl FunctionMember { - #[builder] - pub fn new>( - name: Option, - ty: Type, - locations: Option>, - ) -> Self { - Self { - name: name.map(|n| n.into()), - ty, - locations: locations.unwrap_or_default(), - } - } -} - -impl FunctionMember { - fn create<'a>(&self, builder: &mut FlatBufferBuilder<'a>) -> WIPOffset> { - let name = self.name.as_ref().map(|n| builder.create_string(n)); - let member_type = self.ty.create(builder); - fb::FunctionMember::create( - builder, - &fb::FunctionMemberArgs { - name, - type_: Some(member_type), - // TODO: Location. - ..Default::default() - }, - ) - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> FunctionMember { - FunctionMember { - name: Some(Alphanumeric.sample_string(rng, 16)), - ty: rng.gen(), - // TODO: Generate locations randomly? I don't know... - locations: vec![], - } - } -} - -// TODO: Move calling convention to another crate? -// TODO: It might have a seperate store... we want to refer to the uuid, but that means we have to do whole -// TODO: database updates when the calling convention changes. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct CallingConvention { - pub name: String, -} - -impl CallingConvention { - // Currently we only support calling convention by name - pub fn new(name: &str) -> Self { - Self { - name: name.to_string(), - } - } - - fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let name = builder.create_string(&self.name); - fb::CallingConvention::create(builder, &fb::CallingConventionArgs { name: Some(name) }) - } -} - -impl From> for CallingConvention { - fn from(_value: fb::CallingConvention<'_>) -> Self { - Self { - name: _value.name().unwrap().to_string(), - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct FunctionClass { - pub calling_convention: Option, - pub in_members: Vec, - pub out_members: Vec, -} - -impl FunctionClass { - pub fn new( - calling_convention: Option, - in_members: Vec, - out_members: Vec, - ) -> Self { - Self { - calling_convention, - in_members, - out_members, - } - } - - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let calling_convention = self - .calling_convention - .as_ref() - .map(|cc| cc.create(builder)); - let _created_in_members: Vec<_> = self - .in_members - .iter() - .map(|member| member.create(builder)) - .collect(); - let created_in_members = builder.create_vector(&_created_in_members); - let _created_out_members: Vec<_> = self - .out_members - .iter() - .map(|member| member.create(builder)) - .collect(); - let created_out_members = builder.create_vector(&_created_out_members); - - fb::Function::create( - builder, - &fb::FunctionArgs { - calling_convention, - in_members: Some(created_in_members), - out_members: Some(created_out_members), - }, - ) - } -} - -impl From> for FunctionClass { - fn from(value: fb::Function<'_>) -> Self { - Self { - calling_convention: value.calling_convention().map(Into::into), - in_members: value.in_members().unwrap().iter().map(Into::into).collect(), - out_members: value - .out_members() - .unwrap() - .iter() - .map(Into::into) - .collect(), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> FunctionClass { - let rand_in_member_len = rng.gen_range(0..8); - // TODO: Generate functions with multiple out? - let rand_out_member_len = rng.gen_range(0..1); - FunctionClass { - calling_convention: None, - in_members: rng.sample_iter(Standard).take(rand_in_member_len).collect(), - out_members: rng - .sample_iter(Standard) - .take(rand_out_member_len) - .collect(), - } - } -} diff --git a/rust/type/class/referrer.rs b/rust/type/class/referrer.rs deleted file mode 100644 index cac4793..0000000 --- a/rust/type/class/referrer.rs +++ /dev/null @@ -1,50 +0,0 @@ -use bon::Builder; - -use crate::fb_type as fb; -use crate::r#type::guid::TypeGUID; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use rand::distributions::{Alphanumeric, DistString, Distribution, Standard}; -use rand::Rng; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct ReferrerClass { - pub guid: Option, - pub name: Option, -} - -impl ReferrerClass { - pub fn new(guid: Option, name: Option) -> Self { - Self { guid, name } - } - - pub(crate) fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let guid = self - .guid - .as_ref() - .map(|x| builder.create_string(&x.to_string())); - let name = self.name.as_ref().map(|x| builder.create_string(x)); - fb::Referrer::create(builder, &fb::ReferrerArgs { guid, name }) - } -} - -// TODO: We really should make this TryFrom -impl From> for ReferrerClass { - fn from(value: fb::Referrer<'_>) -> Self { - Self { - guid: value.guid().map(|s| s.parse().unwrap()), - name: value.name().map(|x| x.to_owned()), - } - } -} - -impl Distribution for Standard { - fn sample(&self, rng: &mut R) -> ReferrerClass { - ReferrerClass { - guid: rng.gen(), - name: Some(Alphanumeric.sample_string(rng, 16)), - } - } -} diff --git a/rust/type/modifier.rs b/rust/type/modifier.rs deleted file mode 100644 index 81f3f98..0000000 --- a/rust/type/modifier.rs +++ /dev/null @@ -1,129 +0,0 @@ -use bon::Builder; - -use crate::fb_type as fb; -use flatbuffers::{FlatBufferBuilder, UnionWIPOffset, WIPOffset}; - -#[derive(Clone, Debug, PartialEq, Hash, Eq)] -pub struct DescriptorModifierClass { - pub description: String, -} - -impl DescriptorModifierClass { - pub fn new(description: String) -> Self { - Self { description } - } -} - -impl DescriptorModifierClass { - fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let description = builder.create_string(&self.description); - fb::DescriptorModifierClass::create( - builder, - &fb::DescriptorModifierClassArgs { - description: Some(description), - }, - ) - } -} - -#[derive(Clone, Debug, PartialEq, Hash, Eq)] -pub struct MetadataModifierClass { - pub key: String, - pub value: T, -} - -impl MetadataModifierClass { - pub fn new(key: String, value: T) -> Self { - Self { key, value } - } -} - -impl> MetadataModifierClass { - fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let key = builder.create_string(&self.key); - let value = builder.create_vector(self.value.as_ref()); - fb::MetadataModifierClass::create( - builder, - &fb::MetadataModifierClassArgs { - key: Some(key), - value: Some(value), - }, - ) - } -} - -#[derive(Clone, Debug, PartialEq, Hash, Eq)] -pub enum TypeModifierClass { - Constant, - Volatile, - Descriptor(DescriptorModifierClass), - StringMetadata(MetadataModifierClass), - RawMetadata(MetadataModifierClass>), -} - -impl TypeModifierClass { - pub fn ty(&self) -> fb::TypeModifierClass { - match self { - TypeModifierClass::Constant => fb::TypeModifierClass::ConstantModifierClass, - TypeModifierClass::Volatile => fb::TypeModifierClass::VolatileModifierClass, - TypeModifierClass::Descriptor(_) => fb::TypeModifierClass::DescriptorModifierClass, - TypeModifierClass::StringMetadata(_) | TypeModifierClass::RawMetadata(_) => { - fb::TypeModifierClass::MetadataModifierClass - } - } - } - - fn create_constant<'a>( - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - fb::ConstantModifierClass::create(builder, &fb::ConstantModifierClassArgs {}) - } - - fn create_volatile<'a>( - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - fb::VolatileModifierClass::create(builder, &fb::VolatileModifierClassArgs {}) - } - - fn create(&self, builder: &mut FlatBufferBuilder) -> WIPOffset { - match self { - TypeModifierClass::Constant => Self::create_constant(builder).as_union_value(), - TypeModifierClass::Volatile => Self::create_volatile(builder).as_union_value(), - TypeModifierClass::Descriptor(class) => class.create(builder).as_union_value(), - TypeModifierClass::StringMetadata(class) => class.create(builder).as_union_value(), - TypeModifierClass::RawMetadata(class) => class.create(builder).as_union_value(), - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Builder)] -pub struct TypeModifier { - pub class: TypeModifierClass, -} - -impl TypeModifier { - pub fn new(class: TypeModifierClass) -> Self { - Self { class } - } - - pub fn create<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> WIPOffset> { - let class_type = self.class.ty(); - let class = self.class.create(builder); - fb::TypeModifier::create( - builder, - &fb::TypeModifierArgs { - class_type, - class: Some(class), - }, - ) - } -} diff --git a/signature.fbs b/signature.fbs index 1cf901e..c3ef576 100644 --- a/signature.fbs +++ b/signature.fbs @@ -3,44 +3,58 @@ include "symbol.fbs"; namespace SigBin; -file_identifier "SBIN"; -file_extension "sbin"; +struct BasicBlockGUID { + value:[ubyte:16]; +} + +struct ConstraintGUID { + value:[ubyte:16]; +} + +struct FunctionGUID { + value:[ubyte:16]; +} table BasicBlock { - guid:string (required); - // TODO: successors:[string]; - // TODO: predecessors:[string]; + guid:BasicBlockGUID (required); + // TODO: successors:[BasicBlockGUID]; + // TODO: predecessors:[BasicBlockGUID]; } -table FunctionConstraint { - guid:string; - // In cases where a function guid was not able to be generated, we can match on symbol. - symbol:SymbolBin.Symbol; +table Constraint { + guid:ConstraintGUID (required); // The byte offset from the start of the constrained function. // A negative number would indicate that the constraint occurs before the start of the function. offset:long; } -table FunctionConstraints { - // Adjacent functions. - adjacent:[FunctionConstraint]; - // Call sites within the function. - call_sites:[FunctionConstraint]; - // Callers to the function. - caller_sites:[FunctionConstraint]; +table FunctionComment { + offset:int64; + text:string (required); +} + +// TODO: This is extremely naive, cant handle stack slot re-use. +table FunctionVariable { + offset:int64; + name:string; + location:TypeBin.LocationClass (required); + type:TypeBin.Type; + // TODO: Possible value set. (to assert a value) } table Function { // TODO: Add architecture, this is required to support multi-arch binaries... - guid:string (required); + // TODO: Make guid a key when https://github.com/google/flatbuffers/issues/8603 is fixed. + guid:FunctionGUID (required); symbol:SymbolBin.Symbol; type:TypeBin.Type; - constraints:FunctionConstraints; + constraints:[Constraint]; + comments:[FunctionComment]; + variables:[FunctionVariable]; } -table Data { - functions:[Function]; - types:[TypeBin.ComputedType]; +table SignatureChunk { + functions:[Function] (required); } -root_type Data; \ No newline at end of file +root_type SignatureChunk; \ No newline at end of file diff --git a/sigview/Cargo.toml b/sigview/Cargo.toml deleted file mode 100644 index aa13230..0000000 --- a/sigview/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "sigview" -version = "0.1.0" -edition = "2021" - -[dependencies] -warp = { path = "../" } -log = "0.4" -env_logger = "0.11.5" -eframe = "0.29.1" -egui_extras = "0.29.1" -rfd = "0.15.0" -egui_graphs = "0.22.0" -egui_virtual_list = "0.5.0" -petgraph = "0.6.5" \ No newline at end of file diff --git a/sigview/src/graph.rs b/sigview/src/graph.rs deleted file mode 100644 index 0142e65..0000000 --- a/sigview/src/graph.rs +++ /dev/null @@ -1,96 +0,0 @@ -use eframe::egui; -use eframe::egui::Ui; -use egui_graphs::{Graph, GraphView, SettingsInteraction, SettingsNavigation, SettingsStyle}; -use petgraph::prelude::StableGraph; -use warp::signature::function::{Function, FunctionGUID}; - -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub struct FunctionNode { - pub name: String, - pub guid: FunctionGUID, -} - -impl From for FunctionNode { - fn from(value: Function) -> Self { - Self::from(&value) - } -} - -impl From<&Function> for FunctionNode { - fn from(value: &Function) -> Self { - Self { - name: value.symbol.name.to_owned(), - guid: value.guid, - } - } -} - -#[derive(Debug, Clone)] -pub struct FunctionGraph { - graph: Graph, -} - -impl FunctionGraph { - pub fn from_function(func: &Function) -> Self { - let mut graph = StableGraph::new(); - let func_node = FunctionNode::from(func); - let func_node_idx = graph.add_node(func_node); - - for caller_func in &func.constraints.call_sites { - let name = caller_func - .symbol - .as_ref() - .map(|sym| sym.name.to_owned()) - .unwrap_or_default(); - if let Some(guid) = caller_func.guid { - let caller_func_node = FunctionNode { name, guid }; - let caller_func_node_idx = graph.add_node(caller_func_node); - graph.add_edge(caller_func_node_idx, func_node_idx, ()); - } - } - - FunctionGraph { - graph: Graph::from(&graph), - } - } - - pub fn add(&mut self, ui: &mut Ui) { - let interaction_settings = &SettingsInteraction::new(); - let style_settings = &SettingsStyle::new().with_labels_always(true); - let nav_settings = &SettingsNavigation::new() - .with_fit_to_screen_enabled(false) - .with_zoom_and_pan_enabled(true); - ui.add( - &mut GraphView::new(&mut self.graph) - .with_styles(style_settings) - .with_interactions(interaction_settings) - .with_navigations(nav_settings), - ); - } - - pub fn add_viewport(&mut self, ctx: &egui::Context) -> bool { - let mut requested_close = false; - ctx.show_viewport_immediate( - egui::ViewportId::from_hash_of("function_graph_viewport"), - egui::ViewportBuilder::default() - .with_title("Function Graph") - .with_inner_size([400.0, 400.0]), - |ctx, class| { - assert!( - class == egui::ViewportClass::Immediate, - "This egui backend doesn't support multiple viewports" - ); - - egui::CentralPanel::default().show(ctx, |ui| { - self.add(ui); - }); - - if ctx.input(|i| i.viewport().close_requested()) { - // Tell parent viewport that we should not show next frame: - requested_close = true; - } - }, - ); - requested_close - } -} diff --git a/sigview/src/main.rs b/sigview/src/main.rs deleted file mode 100644 index 58921f0..0000000 --- a/sigview/src/main.rs +++ /dev/null @@ -1,173 +0,0 @@ -mod graph; - -use std::path::Path; -// ui design is my passion -use crate::graph::FunctionGraph; -use eframe::egui; -use eframe::egui::{Direction, Layout, ScrollArea, Ui}; -use egui_virtual_list::VirtualList; -use warp::signature::Data; -use warp::signature::function::Function; -// TODO: Add some collision viewer and graph viewer -// TODO: Load multiple Data for collision. -// TODO: Type viewer (data.types) - -fn main() -> eframe::Result { - env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). - let options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default().with_inner_size([520.0, 540.0]), - ..Default::default() - }; - eframe::run_native( - "sigview", - options, - Box::new(|_cc| Ok(Box::::default())), - ) -} - -#[derive(Default)] -struct SigView { - data: Option, - virtual_list: VirtualList, - selected_graph: Option, - selected_function_info: Option, - search_query: String, -} - -impl SigView { - #[allow(unused)] - pub fn from_data(data: Data) -> Self { - Self { - data: Some(data), - selected_graph: None, - selected_function_info: None, - virtual_list: VirtualList::new(), - search_query: "".to_string(), - } - } - - pub fn rebuild_from_file(&mut self, path: &Path) { - if let Ok(buf) = std::fs::read(path) { - if let Some(data) = Data::from_bytes(&buf) { - self.data = Some(data); - } else { - log::error!("Could not get data from file: {:?}", path); - } - } else { - log::error!("Could not read file: {:?}", path); - } - } - - pub fn file_selector_btn(&mut self, ui: &mut Ui) { - if ui.button("Open File or Drop File").clicked() { - if let Some(path) = rfd::FileDialog::new().pick_file() { - self.rebuild_from_file(&path); - } - } - } - - pub fn file_dropper_handler(&mut self, ui: &mut Ui) { - // Handle dropped files. - ui.ctx().input(|i| { - for file in &i.raw.dropped_files { - if let Some(path) = &file.path { - self.rebuild_from_file(path); - } - } - }); - } -} - -impl eframe::App for SigView { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - if let Some(mut graph) = self.selected_graph.clone() { - if graph.add_viewport(ctx) { - self.selected_graph = None; - } - } - - if let Some(function) = self.selected_function_info.clone() { - ctx.show_viewport_immediate( - egui::ViewportId::from_hash_of("function_info_viewport"), - egui::ViewportBuilder::default() - .with_title("Function Info") - .with_inner_size([400.0, 400.0]), - |ctx, class| { - assert!( - class == egui::ViewportClass::Immediate, - "This egui backend doesn't support multiple viewports" - ); - - egui::CentralPanel::default().show(ctx, |ui| { - egui::ScrollArea::vertical().show(ui, |ui| { - ui.label(format!("Name: {}", function.symbol.name)); - ui.separator(); - ui.label(format!("GUID: {}", function.guid)); - ui.separator(); - ui.label(format!("{:#?}", function.ty)); - ui.separator(); - ui.label(format!("{:#?}", function.constraints)); - ui.separator(); - }); - }); - - if ctx.input(|i| i.viewport().close_requested()) { - // Tell parent viewport that we should not show next frame: - self.selected_function_info = None; - } - }, - ); - } - - egui::CentralPanel::default().show(ctx, |ui| { - self.file_dropper_handler(ui); - if let Some(data) = &self.data { - ui.label(format!("Data with {} functions...", data.functions.len())); - - egui::TextEdit::singleline(&mut self.search_query) - .hint_text("Search...") - .show(ui); - - ui.separator(); - - let filtered_functions = data - .functions - .iter() - .filter(|f| { - f.symbol - .name - .to_lowercase() - .contains(&self.search_query.to_lowercase()) - || f.guid.to_string().contains(&self.search_query) - }) - .collect::>(); - - ScrollArea::vertical().show(ui, |ui| { - ui.set_width(ui.available_width()); - self.virtual_list.ui_custom_layout( - ui, - filtered_functions.len(), - |ui, start_index| { - let function = filtered_functions[start_index]; - ui.horizontal(|ui| { - ui.label(format!("Function: {}", function.symbol.name)); - if ui.button("View Graph").clicked() { - self.selected_graph = - Some(FunctionGraph::from_function(function)); - } - if ui.button("View Info").clicked() { - self.selected_function_info = Some(function.clone()); - } - }); - 1 - }, - ); - }); - } else { - ui.with_layout(Layout::centered_and_justified(Direction::TopDown), |ui| { - self.file_selector_btn(ui); - }); - } - }); - } -} diff --git a/symbol.fbs b/symbol.fbs index 5d01409..e34978a 100644 --- a/symbol.fbs +++ b/symbol.fbs @@ -1,12 +1,9 @@ namespace SymbolBin; -table FunctionSymbolClass {} - -table DataSymbolClass {} - -union SymbolClass { - FunctionSymbolClass, - DataSymbolClass +enum SymbolClass : ubyte { + Function, + Data, + Bare } enum SymbolModifiers : ubyte (bit_flags) { @@ -18,9 +15,7 @@ enum SymbolModifiers : ubyte (bit_flags) { } table Symbol { - // TODO: We should be able to store metadata on this... - // TODO: Metadata could include raw names and long names. name:string; modifiers:SymbolModifiers; - class:SymbolClass (required); + class:SymbolClass; } \ No newline at end of file diff --git a/target.fbs b/target.fbs new file mode 100644 index 0000000..b2aa188 --- /dev/null +++ b/target.fbs @@ -0,0 +1,10 @@ +namespace TargetBin; + +table Target { + // TODO: Further integration with other tools will likely need a actual mapping for target names. + // The architecture name for the target, this can be implementation specific. + architecture:string; + // The platform name for the target, this can be implementation specific. + platform:string; + // TODO: Extend with target specific information, calling conventions etc... +} \ No newline at end of file diff --git a/type.fbs b/type.fbs index 16ecaae..dd411c0 100644 --- a/type.fbs +++ b/type.fbs @@ -1,7 +1,10 @@ +include "target.fbs"; + namespace TypeBin; -file_identifier "TBIN"; -file_extension "tbin"; +struct TypeGUID { + value:[ubyte:16]; +} struct UnsignedBitOffset { value:ulong; @@ -23,44 +26,21 @@ struct BitWidth { value:ushort; } -table ConstantModifierClass {} -table VolatileModifierClass {} - -table DescriptorModifierClass { - description:string; -} - -table MetadataModifierClass { - key:string; - value:[ubyte]; -} - -union TypeModifierClass { - ConstantModifierClass, - VolatileModifierClass, - DescriptorModifierClass, - // Used for tooling specific metadata. - // If the metadata can be generic create a new modifier class. - MetadataModifierClass +enum TypeModifiers : ubyte (bit_flags) { + Constant = 0, + Volatile = 1, } -table TypeModifier { - // TODO: Add modifier confidence? - class:TypeModifierClass; +enum MetadataValueType : ubyte { + Raw = 0, + String = 1, } -table AccessAlignment {} - -table FixedAlignment { - width:BitWidth; -} - -union TypeAlignment { - // TODO: Document wording - // Alignment is "natural" to the access width. - AccessAlignment, - // Alignment is fixed to a width, i.e. __packed is 8 bits - FixedAlignment +// Used for tooling specific metadata. +table TypeMetadata { + key:string (key, required); + value_type:MetadataValueType; + value:[ubyte]; } // A zero sized type with no information. @@ -187,20 +167,13 @@ union LocationClass { StackLocation, } -table FunctionMemberLocation { - // TODO: Instead of saying register or stack, we should say positional or variadic - // TODO: Then with the positional index we can associate it with the calling convention... - class:LocationClass; -} - table FunctionMember { // The name of the function member, optional in cases where one is not observed. name:string; - // TODO: What if function members did not have a type? use whole register? stack with zero size? + // TODO: What if function members did not have a type? use whole register? stack with zero size? (access sized type) type:Type (required); // If the location is not available then default to the location specified by the member index. - // NOTE: The locations must be equal to or greater than the size of `type`. - locations:[FunctionMemberLocation]; + location:LocationClass; } table Function { @@ -228,7 +201,7 @@ table Function { // a. In the event of a self reference we could reference based off name? table Referrer { // Unique GUID, can either be in-memory, on-disk, or networked. - guid:string; + guid:TypeGUID; name:string; } @@ -254,22 +227,23 @@ table Type { class:TypeClass (required); // Confidence is assumed to be maximal if not specified. Any type with a lesser confidence can be assumed to be less truthy. confidence:ubyte = 255; - // TODO: Change docs. - // Alignment of type, if not present assume AccessAlignment. - alignment:TypeAlignment; - // Modifiers for the type, can store arbitrary data as well. - modifiers:[TypeModifier]; + // Alignment of type in bits, a value of 0 is the "natural" access alignment. + // A C type that is marked __packed would be a value of 8, as in, byte aligned. + alignment:ushort = 0; + modifiers:TypeModifiers; + // Metadata for the type, store arbitrary data, useful for tooling specific stuff like comments. + metadata:[TypeMetadata]; // A list of older versions of the type, this is used to update references to the latest. - ancestors:[string]; + ancestors:[TypeGUID]; } table ComputedType { - guid:string (required); + guid:TypeGUID (required); type:Type; } -table Data { - types:[ComputedType]; +table TypeChunk { + types:[ComputedType] (required); } -root_type Data; \ No newline at end of file +root_type TypeChunk; \ No newline at end of file diff --git a/warp.fbs b/warp.fbs new file mode 100644 index 0000000..4f9fcf1 --- /dev/null +++ b/warp.fbs @@ -0,0 +1,51 @@ +include "type.fbs"; +include "symbol.fbs"; +include "signature.fbs"; +include "target.fbs"; + +namespace Warp; + +file_identifier "WARP"; +file_extension "warp"; + +enum ChunkType : ubyte { + Signatures = 0, + Types = 1, +} + +enum CompressionType : ubyte { + None = 0, + Zstd = 1, +} + +table ChunkHeader { + version:ushort; + type:ChunkType; + compression_type:CompressionType; + // Size in bytes of the uncompressed data. + // This is provided so that readers can allocate allocate the size of the chunk before reading. + // Because the size of flatbuffers cannot exceed 2GB we limit size to 32 bits. + size:uint; + // The "target" of the chunk, this is used currently only used as a key for architecture & platform. + target:TargetBin.Target; +} + +table Chunk { + header:ChunkHeader (required); + // TODO: To support more than 2gb we need to make this offset64, however rust fb codegen does not support currently. + data:[ubyte]; +} + +table FileHeader { + version:ushort; + // TODO: Analysis information may want to be guarded behind some metadata. + // TODO: For example, we might want to store the compiler or language here to guard from this information from being read. +} + +// The file format used to store analysis data. +table File { + header:FileHeader (required); + chunks:[Chunk]; +} + +root_type File; \ No newline at end of file diff --git a/warp_cli/Cargo.toml b/warp_cli/Cargo.toml new file mode 100644 index 0000000..6f2daf7 --- /dev/null +++ b/warp_cli/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "warp_cli" +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" + +[dependencies] +warp = { workspace = true } +clap = { version = "4.5", features = ["derive"] } \ No newline at end of file diff --git a/warp_cli/src/main.rs b/warp_cli/src/main.rs new file mode 100644 index 0000000..fc0a442 --- /dev/null +++ b/warp_cli/src/main.rs @@ -0,0 +1,24 @@ +pub mod operation; +mod utility; + +use crate::operation::Operation; +use clap::Parser; +use std::path::PathBuf; + +/// Command line tools for reading and writing WARP files. +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// Path of the file to perform the operation on. + #[arg(short, long)] + path: PathBuf, + + /// Operation to perform on the file. + #[command(subcommand)] + operation: Operation, +} + +fn main() { + let args = Args::parse(); + args.operation.run(&args.path); +} diff --git a/warp_cli/src/operation.rs b/warp_cli/src/operation.rs new file mode 100644 index 0000000..bfd5ee5 --- /dev/null +++ b/warp_cli/src/operation.rs @@ -0,0 +1,24 @@ +use clap::Subcommand; +use std::path::Path; + +pub mod find; +pub mod merge; + +pub trait OperationHandler { + fn run(&self, path: &Path); +} + +#[derive(Clone, Debug, Subcommand)] +pub enum Operation { + Find(find::FindOp), + Merge(merge::MergeOp), +} + +impl Operation { + pub fn run(&self, path: &Path) { + match self { + Operation::Find(op) => op.run(path), + Operation::Merge(op) => op.run(path), + } + } +} diff --git a/warp_cli/src/operation/find.rs b/warp_cli/src/operation/find.rs new file mode 100644 index 0000000..38983dd --- /dev/null +++ b/warp_cli/src/operation/find.rs @@ -0,0 +1,81 @@ +use crate::operation::OperationHandler; +use crate::utility::open_file; +use clap::Parser; +use std::path::Path; +use warp::chunk::{Chunk, ChunkKind}; +use warp::r#type::chunk::TypeChunk; +use warp::r#type::ComputedType; +use warp::signature::chunk::SignatureChunk; +use warp::signature::function::Function; + +// TODO: Filter by chunk type. +/// Find an item in the file given a set of filters like name. +#[derive(Clone, Debug, Parser)] +pub struct FindOp { + /// Find any item with the given string. + /// + /// NOTE: This lookup is currently done + #[arg(index = 1)] + any: Option, +} + +impl FindOp { + pub fn dump_function(&self, function: &Function) { + println!("Function: {:?}", function); + } + + pub fn dump_type(&self, ty: &ComputedType) { + println!("Type: {:?}", ty); + } + + pub fn find_in_signature(&self, func: &Function) -> bool { + let str = format!("{:?}", func); + str.contains(self.any.as_deref().unwrap_or("")) + } + + pub fn find_in_signature_chunk(&self, sc: &SignatureChunk) -> Vec { + sc.functions() + .filter(|f| self.find_in_signature(f)) + .collect() + } + + pub fn find_in_computed_type(&self, computed_ty: &ComputedType) -> bool { + let str = format!("{:?}", computed_ty); + str.contains(self.any.as_deref().unwrap_or("")) + } + + pub fn find_in_type_chunk(&self, tc: &TypeChunk) -> Vec { + tc.types() + .filter(|ct| self.find_in_computed_type(ct)) + .collect() + } + + pub fn find_in_chunk(&self, chunk: &Chunk) { + match &chunk.kind { + ChunkKind::Signature(sc) => { + for found_func in self.find_in_signature_chunk(sc) { + self.dump_function(&found_func) + } + } + ChunkKind::Type(tc) => { + for found_ty in self.find_in_type_chunk(tc) { + self.dump_type(&found_ty) + } + } + } + } +} + +impl OperationHandler for FindOp { + fn run(&self, path: &Path) { + let file = open_file(path); + for chunk in file.chunks { + println!( + "Searching in chunk ({}, 0x{:x} bytes)", + chunk.header.chunk_type.variant_name().unwrap_or_default(), + chunk.header.size + ); + self.find_in_chunk(&chunk); + } + } +} diff --git a/warp_cli/src/operation/merge.rs b/warp_cli/src/operation/merge.rs new file mode 100644 index 0000000..7542c0f --- /dev/null +++ b/warp_cli/src/operation/merge.rs @@ -0,0 +1,29 @@ +use crate::operation::OperationHandler; +use crate::utility::open_file; +use clap::Parser; +use std::path::{Path, PathBuf}; +use warp::chunk::{Chunk, CompressionType}; +use warp::{WarpFile, WarpFileHeader}; + +/// Merge all other files into the provided path. +#[derive(Clone, Debug, Parser)] +pub struct MergeOp { + /// Files to be merged into the given path. + #[arg(index = 1)] + unmerged_files: Vec, +} + +impl OperationHandler for MergeOp { + fn run(&self, path: &Path) { + let files: Vec<_> = self + .unmerged_files + .iter() + .map(PathBuf::as_path) + .map(open_file) + .collect(); + let chunks: Vec = files.iter().flat_map(|f| f.chunks.clone()).collect(); + let merged_chunks = Chunk::merge(&chunks, CompressionType::Zstd); + let merged_file = WarpFile::new(WarpFileHeader::new(), merged_chunks); + std::fs::write(path, merged_file.to_bytes()).expect("Failed to write file"); + } +} diff --git a/warp_cli/src/utility.rs b/warp_cli/src/utility.rs new file mode 100644 index 0000000..a169dfc --- /dev/null +++ b/warp_cli/src/utility.rs @@ -0,0 +1,9 @@ +use std::path::Path; +use warp::WarpFile; + +/// Construct an owned file from a path, this means the file owns the buffer, and we have no problems passing it to-from. +pub fn open_file<'fbb>(path: &Path) -> WarpFile<'fbb> { + let file = std::fs::read(path).expect("Unable to read file"); + let file = WarpFile::from_owned_bytes(file).expect("Invalid WARP file"); + file +}