Skip to content

Commit 414cac3

Browse files
committed
Implement random generation for PtrT and RefT
1 parent 1ba2769 commit 414cac3

23 files changed

+1098
-477
lines changed

kmir/src/kmir/kast.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,20 @@
1212
from pyk.kast.prelude.utils import token
1313

1414
from .ty import ArrayT, BoolT, EnumT, IntT, PtrT, RefT, StructT, TupleT, Ty, UintT, UnionT
15-
from .value import AggregateValue, BoolValue, DynamicSize, IntValue, RangeValue, StaticSize
15+
from .value import (
16+
NO_SIZE,
17+
AggregateValue,
18+
BoolValue,
19+
DynamicSize,
20+
IntValue,
21+
Local,
22+
Metadata,
23+
Place,
24+
PtrLocalValue,
25+
RangeValue,
26+
RefValue,
27+
StaticSize,
28+
)
1629

1730
if TYPE_CHECKING:
1831
from collections.abc import Iterable, Iterator, Mapping, Sequence
@@ -557,6 +570,13 @@ def _random_value(self, local: _Local) -> RandomValueRes:
557570
),
558571
metadata_size=metadata_size,
559572
)
573+
case PtrT() | RefT():
574+
return SimpleRes(
575+
value=TypedValue.from_local(
576+
value=self._random_ptr_value(mut=local.mut, type_info=type_info),
577+
local=local,
578+
),
579+
)
560580
case _:
561581
raise ValueError(f'Type unsupported for random value generator: {type_info}')
562582

@@ -598,3 +618,37 @@ def _random_array_value(self, *, mut: bool, elem_ty: Ty, length: int | None) ->
598618
elems = tuple(self._random_value(local=_Local(ty=elem_ty, mut=mut)).value.value for _ in range(length))
599619
value = RangeValue(elems)
600620
return value, metadata_size
621+
622+
def _random_ptr_value(self, mut: bool, type_info: PtrT | RefT) -> PtrLocalValue | RefValue:
623+
pointee_local = _Local(ty=type_info.pointee_type, mut=mut)
624+
pointee_res = self._random_value(pointee_local)
625+
self._pointees.append(pointee_res.value)
626+
627+
metadata_size: MetadataSize
628+
match pointee_res:
629+
case ArrayRes(metadata_size=metadata_size):
630+
pass
631+
case _:
632+
metadata_size = NO_SIZE
633+
634+
metadata = Metadata(size=metadata_size, pointer_offset=0, origin_size=metadata_size)
635+
636+
ref = next(self._ref)
637+
638+
match type_info:
639+
case PtrT():
640+
return PtrLocalValue(
641+
stack_depth=0,
642+
place=Place(local=Local(ref)),
643+
mut=mut,
644+
metadata=metadata,
645+
)
646+
case RefT():
647+
return RefValue(
648+
stack_depth=0,
649+
place=Place(local=Local(ref)),
650+
mut=mut,
651+
metadata=metadata,
652+
)
653+
case _:
654+
raise AssertionError()

kmir/src/kmir/value.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from abc import ABC, abstractmethod
44
from dataclasses import dataclass
5-
from typing import TYPE_CHECKING
5+
from typing import TYPE_CHECKING, NewType
66

77
from pyk.kast.inner import KApply
88
from pyk.kast.prelude.collections import list_of
@@ -19,6 +19,9 @@
1919
from .alloc import AllocId
2020

2121

22+
Local = NewType('Local', int)
23+
24+
2225
class Value(ABC):
2326
@abstractmethod
2427
def to_kast(self) -> KInner: ...
@@ -86,6 +89,40 @@ def to_kast(self) -> KInner:
8689
)
8790

8891

92+
@dataclass
93+
class RefValue(Value):
94+
stack_depth: int
95+
place: Place
96+
mut: bool
97+
metadata: Metadata
98+
99+
def to_kast(self) -> KInner:
100+
return KApply(
101+
'Value::Reference',
102+
intToken(self.stack_depth),
103+
self.place.to_kast(),
104+
KApply('Mutability::Mut') if self.mut else KApply('Mutability::Not'),
105+
self.metadata.to_kast(),
106+
)
107+
108+
109+
@dataclass
110+
class PtrLocalValue(Value):
111+
stack_depth: int
112+
place: Place
113+
mut: bool
114+
metadata: Metadata
115+
116+
def to_kast(self) -> KInner:
117+
return KApply(
118+
'Value::PtrLocal',
119+
intToken(self.stack_depth),
120+
self.place.to_kast(),
121+
KApply('Mutability::Mut') if self.mut else KApply('Mutability::Not'),
122+
self.metadata.to_kast(),
123+
)
124+
125+
89126
@dataclass
90127
class AllocRefValue(Value):
91128
alloc_id: AllocId
@@ -101,6 +138,19 @@ def to_kast(self) -> KInner:
101138
)
102139

103140

141+
@dataclass
142+
class Place:
143+
local: Local
144+
# projection_elems: tuple[ProjectionElem, ...]
145+
146+
def to_kast(self) -> KInner:
147+
return KApply(
148+
'place',
149+
KApply('local', intToken(self.local)),
150+
KApply('ProjectionElems::empty'), # TODO
151+
)
152+
153+
104154
@dataclass
105155
class Metadata:
106156
size: MetadataSize

kmir/src/tests/integration/data/run-smir-random/complex-types/final-0.expected

Lines changed: 68 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-1.expected

Lines changed: 68 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-2.expected

Lines changed: 72 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-3.expected

Lines changed: 74 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-4.expected

Lines changed: 87 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-5.expected

Lines changed: 86 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-6.expected

Lines changed: 93 additions & 45 deletions
Large diffs are not rendered by default.

kmir/src/tests/integration/data/run-smir-random/complex-types/final-7.expected

Lines changed: 78 additions & 49 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)