pyrograph 0.1.0

GPU-accelerated taint analysis for supply chain malware detection
Documentation
diff a/libs/performance/analysis/pyrograph/src/parse/js/expressions.rs b/libs/performance/analysis/pyrograph/src/parse/js/expressions.rs	(rejected hunks)
@@ -24,6 +24,31 @@ fn network_tainted_param_indices(call_name: &str) -> Vec<usize> {
 }
 
 impl JsParser {
+
+    pub(super) fn try_infer_numeric_literal(&self, expr: &Expr) -> Option<f64> {
+        match expr {
+            Expr::Lit(Lit::Num(n)) => Some(n.value),
+            Expr::Bin(b) => {
+                let l = self.try_infer_numeric_literal(&b.left)?;
+                let r = self.try_infer_numeric_literal(&b.right)?;
+                match b.op {
+                    BinaryOp::Add => Some(l + r),
+                    BinaryOp::Sub => Some(l - r),
+                    BinaryOp::Mul => Some(l * r),
+                    BinaryOp::Div => if r != 0.0 { Some(l / r) } else { None },
+                    BinaryOp::BitOr => Some(((l as i64) | (r as i64)) as f64),
+                    BinaryOp::BitAnd => Some(((l as i64) & (r as i64)) as f64),
+                    BinaryOp::BitXor => Some(((l as i64) ^ (r as i64)) as f64),
+                    BinaryOp::LShift => Some(((l as i64) << (r as i64)) as f64),
+                    BinaryOp::RShift => Some(((l as i64) >> (r as i64)) as f64),
+                    _ => None,
+                }
+            }
+            Expr::Paren(p) => self.try_infer_numeric_literal(&p.expr),
+            _ => None,
+        }
+    }
+
     pub(super) fn try_infer_string_literal(&self, expr: &Expr) -> Option<String> {
         match expr {
             Expr::Lit(Lit::Str(s)) => Some(s.value.to_string()),
@@ -41,7 +66,7 @@ impl JsParser {
                 for (i, q) in t.quasis.iter().enumerate() {
                     s.push_str(q.raw.as_ref());
                     if let Some(expr) = t.exprs.get(i) {
-                        s.push_str(&self.try_infer_string_literal(&expr.expr)?);
+                        s.push_str(&self.try_infer_string_literal(&expr)?);
                     }
                 }
                 Some(s)
@@ -58,8 +83,8 @@ impl JsParser {
                                     if prop.sym == "fromCharCode" {
                                         let mut s = String::new();
                                         for arg in &c.args {
-                                            if let Expr::Lit(Lit::Num(n)) = &*arg.expr {
-                                                if let Some(ch) = std::char::from_u32(n.value as u32) {
+                                            if let Some(n) = self.try_infer_numeric_literal(&arg.expr) {
+                                                if let Some(ch) = std::char::from_u32(n as u32) {
                                                     s.push(ch);
                                                 } else {
                                                     return None;