Match vtables with virtual inheritance (#717)

* Match vtables with virtual inheritance

* Simplify vtable name check

* Thunk alert
This commit is contained in:
MS
2024-03-23 18:01:40 -04:00
committed by GitHub
parent b279e8b8b9
commit 3f03940fcb
11 changed files with 350 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
import re
from typing import Optional
from typing import Optional, Tuple
from enum import Enum
@@ -29,18 +29,20 @@ class MarkerType(Enum):
markerRegex = re.compile(
r"\s*//\s*(?P<type>\w+):\s*(?P<module>\w+)\s+(?P<offset>0x[a-f0-9]+)",
r"\s*//\s*(?P<type>\w+):\s*(?P<module>\w+)\s+(?P<offset>0x[a-f0-9]+) *(?P<extra>\S.+\S)?",
flags=re.I,
)
markerExactRegex = re.compile(
r"\s*// (?P<type>[A-Z]+): (?P<module>[A-Z0-9]+) (?P<offset>0x[a-f0-9]+)$"
r"\s*// (?P<type>[A-Z]+): (?P<module>[A-Z0-9]+) (?P<offset>0x[a-f0-9]+)(?: (?P<extra>\S.+\S))?\n?$"
)
class DecompMarker:
def __init__(self, marker_type: str, module: str, offset: int) -> None:
def __init__(
self, marker_type: str, module: str, offset: int, extra: Optional[str] = None
) -> None:
try:
self._type = MarkerType[marker_type.upper()]
except KeyError:
@@ -51,6 +53,7 @@ class DecompMarker:
# we will emit a syntax error.
self._module: str = module.upper()
self._offset: int = offset
self._extra: Optional[str] = extra
@property
def type(self) -> MarkerType:
@@ -64,6 +67,10 @@ class DecompMarker:
def offset(self) -> int:
return self._offset
@property
def extra(self) -> Optional[str]:
return self._extra
@property
def category(self) -> MarkerCategory:
if self.is_vtable():
@@ -81,6 +88,11 @@ class DecompMarker:
return MarkerCategory.ADDRESS
@property
def key(self) -> Tuple[str, str, Optional[str]]:
"""For use with the MarkerDict. To detect/avoid marker collision."""
return (self.category, self.module, self.extra)
def is_regular_function(self) -> bool:
"""Regular function, meaning: not an explicit byname lookup. FUNCTION
markers can be _implicit_ byname.
@@ -126,6 +138,7 @@ def match_marker(line: str) -> Optional[DecompMarker]:
marker_type=match.group("type"),
module=match.group("module"),
offset=int(match.group("offset"), 16),
extra=match.group("extra"),
)

View File

@@ -55,7 +55,7 @@ class ParserVariable(ParserSymbol):
@dataclass
class ParserVtable(ParserSymbol):
pass
base_class: Optional[str] = None
@dataclass

View File

@@ -47,15 +47,16 @@ class MarkerDict:
def insert(self, marker: DecompMarker) -> bool:
"""Return True if this insert would overwrite"""
key = (marker.category, marker.module)
if key in self.markers:
if marker.key in self.markers:
return True
self.markers[key] = marker
self.markers[marker.key] = marker
return False
def query(self, category: MarkerCategory, module: str) -> Optional[DecompMarker]:
return self.markers.get((category, module))
def query(
self, category: MarkerCategory, module: str, extra: Optional[str] = None
) -> Optional[DecompMarker]:
return self.markers.get((category, module, extra))
def iter(self) -> Iterator[DecompMarker]:
for _, marker in self.markers.items():
@@ -275,6 +276,7 @@ class DecompParser:
module=marker.module,
offset=marker.offset,
name=self.curly.get_prefix(class_name),
base_class=marker.extra,
)
)