Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Improve the decompiler #16

Merged
merged 2 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@
resolver = "2"
members = [
"sierra-decompiler",
]
]

[profile.dev]
opt-level = 0

[profile.release]
opt-level = 3
19 changes: 14 additions & 5 deletions lib/src/decompiler/decompiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::decompiler::cfg::EdgeType;
use crate::decompiler::function::Function;
use crate::decompiler::function::SierraStatement;
use crate::decompiler::libfuncs_patterns::IS_ZERO_REGEX;
use crate::decompiler::utils::decrypt_user_defined_type_id;
use crate::decompiler::utils::decode_user_defined_type_id;
use crate::decompiler::utils::replace_types_id;
use crate::graph::callgraph::process_callgraph;
use crate::parse_element_name;
Expand Down Expand Up @@ -117,11 +117,19 @@ impl<'a> Decompiler<'a> {
if let Some(name) = &t.debug_name {
format!("ut@{}", name)
}
// use id
// Convert it to string if possible
// User defined typed ids are the 250 first bits of the id name Keccak hash
// use ID
else {
decrypt_user_defined_type_id(t.id.clone())
// We first format as ut@[<type_id] it and then decode the user-defined types ID part in it if needed
if !self.verbose {
decode_user_defined_type_id(format!(
"ut@[{}]",
t.id.clone().to_string()
))
}
// Don't decode the user-defined types IDs in verbose mode
else {
format!("ut@[{}]", t.id.clone().to_string())
}
}
}
// Builtin type
Expand Down Expand Up @@ -622,6 +630,7 @@ impl<'a> Decompiler<'a> {
}

/// Generate a callgraph representation in DOT Format
#[inline]
pub fn generate_callgraph(&mut self) -> String {
process_callgraph(&self.functions)
}
Expand Down
4 changes: 4 additions & 0 deletions lib/src/decompiler/libfuncs_patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ lazy_static! {
// Used to match and replace them in remote contracts
pub static ref TYPE_ID_REGEX: Regex = Regex::new(r"(?<type_id>\[[0-9]+\])").unwrap();

// User defined types IDs are the 250 first bits of the id name Keccak hash
// https://github.com/starkware-libs/cairo/blob/b29f639c2090822914f52db6696d71748a8b93a6/crates/cairo-lang-sierra/src/ids.rs#L118
pub static ref USER_DEFINED_TYPE_ID_REGEX: Regex = Regex::new(r"ut@\[(?<type_id>[0-9]+)\]").unwrap();

/// Irrelevant callgraph functions regexes
pub static ref IRRELEVANT_CALLGRAPH_FUNCTIONS_REGEXES: Vec<Regex> = {
let mut regexes = vec![
Expand Down
27 changes: 19 additions & 8 deletions lib/src/decompiler/utils.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use num_bigint::{BigInt, BigUint};
use num_bigint::BigInt;
use std::str;

use crate::decompiler::libfuncs_patterns::TYPE_ID_REGEX;
use crate::decompiler::libfuncs_patterns::USER_DEFINED_TYPE_ID_REGEX;

/// Convert an integer to it's string value or hex value
/// Used to decode consts
#[inline]
pub fn decode_hex_bigint(bigint: &BigInt) -> Option<String> {
// Convert the BigInt to a hexadecimal string
let hex_string = format!("{:x}", bigint);
Expand Down Expand Up @@ -59,11 +61,20 @@ pub fn replace_types_id(declared_types_names: &Vec<String>, invocation: &str) ->
.to_string()
}

/// Decrypts a user-defined type ID and returns the corresponding type name
/// If the type ID is not found, returns the string "ut@[<type id>]" where <type id> is the integer value of the type ID
pub fn decrypt_user_defined_type_id(type_id: BigUint) -> String {
// TODO: Implement the decryption logic here

// For now, return the string "ut@[<type id>]" where <type id> is the integer value of the type ID
format!("ut@[{}]", type_id)
/// "Decode" (simplify) a user-defined type ID by truncating it to the 4th character
/// or return the type_id if it does not match the USER_DEFINED_TYPE_ID_REGEX regex pattern
pub fn decode_user_defined_type_id(type_id: String) -> String {
if let Some(captures) = USER_DEFINED_TYPE_ID_REGEX.captures(&type_id) {
// If the type ID matches the regex pattern, truncate it to the 4th character
if let Some(type_id_match) = captures.name("type_id") {
let truncated_type_id = &type_id_match.as_str()[..4];
format!("ut@[{}...]", truncated_type_id)
} else {
// If the type ID does not match the regex pattern, return the original input string
type_id
}
} else {
// If the input string does not match the regex pattern, return the original input string
type_id
}
}
Loading