Skip to content

Commit b90dc47

Browse files
authored
Model GlobalAllocs (#677)
This PR adds the missing cases for `SMIR.allocs`
1 parent 1cccdc0 commit b90dc47

File tree

1 file changed

+237
-1
lines changed

1 file changed

+237
-1
lines changed

kmir/src/kmir/alloc.py

Lines changed: 237 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
from __future__ import annotations
22

3+
import logging
34
from abc import ABC
45
from dataclasses import dataclass
56
from typing import TYPE_CHECKING, NamedTuple, NewType
67

78
from .ty import Ty
89

910
if TYPE_CHECKING:
10-
from typing import Any
11+
from typing import Any, Final
12+
13+
14+
_LOGGER: Final = logging.getLogger(__name__)
1115

1216

1317
AllocId = NewType('AllocId', int)
18+
DefId = NewType('DefId', int)
19+
InstanceDef = NewType('InstanceDef', int)
1420

1521

1622
@dataclass
@@ -32,12 +38,242 @@ class GlobalAlloc(ABC): # noqa: B024
3238
@staticmethod
3339
def from_dict(dct: dict[str, Any]) -> GlobalAlloc:
3440
match dct:
41+
case {'Function': _}:
42+
return Function.from_dict(dct)
43+
case {'VTable': _}:
44+
return VTable.from_dict(dct)
45+
case {'Static': _}:
46+
return Static.from_dict(dct)
3547
case {'Memory': _}:
3648
return Memory.from_dict(dct)
3749
case _:
3850
raise ValueError(f'Unsupported or invalid GlobalAlloc data: {dct}')
3951

4052

53+
@dataclass
54+
class Function(GlobalAlloc):
55+
instance: Instance
56+
57+
@staticmethod
58+
def from_dict(dct: dict[str, Any]) -> Function:
59+
return Function(
60+
instance=Instance.from_dict(dct['Function']),
61+
)
62+
63+
64+
@dataclass
65+
class Instance:
66+
kind: InstanceKind
67+
deff: InstanceDef
68+
69+
@staticmethod
70+
def from_dict(dct: dict[str, Any]) -> Instance:
71+
return Instance(
72+
kind=InstanceKind.from_dict(dct['kind']),
73+
deff=InstanceDef(dct['def']),
74+
)
75+
76+
77+
class InstanceKind(ABC): # noqa: B024
78+
@staticmethod
79+
def from_dict(obj: Any) -> InstanceKind:
80+
match obj:
81+
case 'Item':
82+
return Item()
83+
case 'Intrinsic':
84+
return Intrinsic()
85+
case {'Virtual': _}:
86+
return Virtual.from_dict(obj)
87+
case 'Shim':
88+
return Shim()
89+
case _:
90+
raise ValueError(f'Invalid InstanceKind data: {obj}')
91+
92+
93+
@dataclass
94+
class Item(InstanceKind): ...
95+
96+
97+
@dataclass
98+
class Intrinsic(InstanceKind): ...
99+
100+
101+
@dataclass
102+
class Virtual(InstanceKind):
103+
idx: int
104+
105+
@staticmethod
106+
def from_dict(obj: Any) -> Virtual:
107+
match obj:
108+
case {'Virtual': {'idx': idx}}:
109+
return Virtual(idx=idx)
110+
case _:
111+
raise ValueError(f'Invalid Virtual data: {obj}')
112+
113+
114+
@dataclass
115+
class Shim(InstanceKind): ...
116+
117+
118+
@dataclass
119+
class VTable(GlobalAlloc):
120+
ty: Ty
121+
binder: ExistentialTraitRefBinder | None
122+
123+
@staticmethod
124+
def from_dict(dct: dict[str, Any]) -> VTable:
125+
return VTable(
126+
ty=Ty(dct['VTable'][0]),
127+
binder=ExistentialTraitRefBinder.from_dict(dct['VTable'][1]) if dct['VTable'][1] is not None else None,
128+
)
129+
130+
131+
@dataclass
132+
class ExistentialTraitRefBinder:
133+
value: ExistentialTraitRef
134+
bound_vars: list[BoundVariableKind]
135+
136+
@staticmethod
137+
def from_dict(dct: dict[str, Any]) -> ExistentialTraitRefBinder:
138+
return ExistentialTraitRefBinder(
139+
value=ExistentialTraitRef.from_dict(dct['value']),
140+
bound_vars=[BoundVariableKind.from_dict(var) for var in dct['bound_vars']],
141+
)
142+
143+
144+
@dataclass
145+
class ExistentialTraitRef:
146+
def_id: DefId
147+
generic_args: list[GenericArgKind]
148+
149+
@staticmethod
150+
def from_dict(dct: dict[str, Any]) -> ExistentialTraitRef:
151+
return ExistentialTraitRef(
152+
def_id=DefId(dct['def_id']),
153+
generic_args=[GenericArgKind.from_dict(arg) for arg in dct['generic_args']],
154+
)
155+
156+
157+
@dataclass
158+
class BoundVariableKind(ABC): # noqa: B024
159+
@staticmethod
160+
def from_dict(dct: Any) -> BoundVariableKind:
161+
match dct:
162+
case {'Ty': _}:
163+
return BVTy.from_dict(dct)
164+
case {'Region': _}:
165+
return BVRegion.from_dict(dct)
166+
case 'Const':
167+
return BVConst()
168+
case _:
169+
raise ValueError(f'Invalid BoundBariableKind data: {dct}')
170+
171+
172+
@dataclass
173+
class BVTy(BoundVariableKind):
174+
kind: BoundTyKind
175+
176+
@staticmethod
177+
def from_dict(dct: Any) -> BVTy:
178+
return BVTy(kind=BoundTyKind.from_dict(dct['Ty']))
179+
180+
181+
class BoundTyKind(ABC): # noqa: B024
182+
@staticmethod
183+
def from_dict(dct: Any) -> BoundTyKind:
184+
match dct:
185+
case 'Anon':
186+
return BTAnon()
187+
case {'Param': _}:
188+
return BTParam.from_dict(dct)
189+
case _:
190+
raise ValueError(f'Invalid BoundTyKind data: {dct}')
191+
192+
193+
@dataclass
194+
class BTAnon(BoundTyKind): ...
195+
196+
197+
@dataclass
198+
class BTParam(BoundTyKind):
199+
def_id: DefId
200+
name: str
201+
202+
@staticmethod
203+
def from_dict(dct: Any) -> BTParam:
204+
return BTParam(
205+
def_id=DefId(dct['Param'][0]),
206+
name=str(dct['Param'][1]),
207+
)
208+
209+
210+
@dataclass
211+
class BVRegion(BoundVariableKind):
212+
kind: BoundRegionKind
213+
214+
@staticmethod
215+
def from_dict(dct: Any) -> BVRegion:
216+
return BVRegion(kind=BoundRegionKind.from_dict(dct['Region']))
217+
218+
219+
class BoundRegionKind(ABC): # noqa: B024
220+
@staticmethod
221+
def from_dict(dct: Any) -> BoundRegionKind:
222+
match dct:
223+
case 'BrAnon':
224+
return BRAnon()
225+
case {'BrNamed': _}:
226+
return BRNamed.from_dict(dct)
227+
case 'BrEnv':
228+
return BREnv()
229+
case _:
230+
raise ValueError(f'Invalid BoundRegionKind data: {dct}')
231+
232+
233+
@dataclass
234+
class BRAnon(BoundRegionKind): ...
235+
236+
237+
@dataclass
238+
class BRNamed(BoundRegionKind):
239+
def_id: DefId
240+
name: str
241+
242+
@staticmethod
243+
def from_dict(dct: Any) -> BRNamed:
244+
return BRNamed(
245+
def_id=DefId(dct['BrNamed'][0]),
246+
name=str(dct['BrNamed'][1]),
247+
)
248+
249+
250+
@dataclass
251+
class BREnv(BoundRegionKind): ...
252+
253+
254+
@dataclass
255+
class BVConst(BoundVariableKind): ...
256+
257+
258+
@dataclass
259+
class GenericArgKind:
260+
@staticmethod
261+
def from_dict(dct: dict[str, Any]) -> GenericArgKind:
262+
_LOGGER.warning(f'Unparsed GenericArgKind data encountered: {dct}')
263+
return GenericArgKind()
264+
265+
266+
@dataclass
267+
class Static(GlobalAlloc):
268+
def_id: DefId
269+
270+
@staticmethod
271+
def from_dict(dct: dict[str, Any]) -> Static:
272+
return Static(
273+
def_id=DefId(dct['Static']),
274+
)
275+
276+
41277
@dataclass
42278
class Memory(GlobalAlloc):
43279
allocation: Allocation

0 commit comments

Comments
 (0)