69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
from typing import Dict, List, Any, Tuple
|
||
|
|
|
||
|
|
from .common import trace
|
||
|
|
|
||
|
|
|
||
|
|
def collect_produced_stringish(blocks: List[Dict[str, Any]]) -> Dict[int, bool]:
|
||
|
|
produced_str: Dict[int, bool] = {}
|
||
|
|
for block_data in blocks:
|
||
|
|
for inst in block_data.get("instructions", []) or []:
|
||
|
|
try:
|
||
|
|
opx = inst.get("op")
|
||
|
|
dstx = inst.get("dst")
|
||
|
|
if dstx is None:
|
||
|
|
continue
|
||
|
|
is_str = False
|
||
|
|
if opx == "const":
|
||
|
|
v = inst.get("value", {}) or {}
|
||
|
|
t = v.get("type")
|
||
|
|
if t == "string" or (
|
||
|
|
isinstance(t, dict)
|
||
|
|
and t.get("kind") in ("handle", "ptr")
|
||
|
|
and t.get("box_type") == "StringBox"
|
||
|
|
):
|
||
|
|
is_str = True
|
||
|
|
elif opx in ("binop", "boxcall", "externcall"):
|
||
|
|
t = inst.get("dst_type")
|
||
|
|
if (
|
||
|
|
isinstance(t, dict)
|
||
|
|
and t.get("kind") == "handle"
|
||
|
|
and t.get("box_type") == "StringBox"
|
||
|
|
):
|
||
|
|
is_str = True
|
||
|
|
if is_str:
|
||
|
|
produced_str[int(dstx)] = True
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
return produced_str
|
||
|
|
|
||
|
|
|
||
|
|
def analyze_incomings(blocks: List[Dict[str, Any]]) -> Dict[int, Dict[int, List[Tuple[int, int]]]]:
|
||
|
|
"""Return block_phi_incomings: block_id -> { dst_vid -> [(decl_b, v_src), ...] }"""
|
||
|
|
result: Dict[int, Dict[int, List[Tuple[int, int]]]] = {}
|
||
|
|
for block_data in blocks:
|
||
|
|
bid0 = block_data.get("id", 0)
|
||
|
|
for inst in block_data.get("instructions", []) or []:
|
||
|
|
if inst.get("op") == "phi":
|
||
|
|
try:
|
||
|
|
dst0 = int(inst.get("dst"))
|
||
|
|
incoming0 = inst.get("incoming", []) or []
|
||
|
|
except Exception:
|
||
|
|
dst0 = None
|
||
|
|
incoming0 = []
|
||
|
|
if dst0 is None:
|
||
|
|
continue
|
||
|
|
try:
|
||
|
|
pairs = [(int(b), int(v)) for (v, b) in incoming0]
|
||
|
|
result.setdefault(int(bid0), {})[dst0] = pairs
|
||
|
|
trace({
|
||
|
|
"phi": "analyze",
|
||
|
|
"block": int(bid0),
|
||
|
|
"dst": dst0,
|
||
|
|
"incoming": pairs,
|
||
|
|
})
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
return result
|
||
|
|
|