Skip to content

Commit 4fb9a32

Browse files
dkcummingjberthold
andauthored
Initial Ptr Offset semantics binOpOffset (#746)
Support for `binOpOffset` - `binOpOffset` is applied to a `PtrLocal` but must come from a `Range` of some kind (e.g. `[u8; 2]`, `&[u8]`) in which case the offset is applied to a pointer to the element e.g. `*const u8`; - Both `Reference` and `PtrLocal` has the same `Metadata` that tracks and offset; - In order to ensure that pointers are not out of range when the offset is applied, `Metadata` has an `OriginSize` field for `PtrLocal` and `Reference` for the necessary bounds checking in the external `Range`; - After an offset is applied to a `PtrLocal` it can be turned back into a `Reference`, which essentially is an index into the `Range` but it does not return the element type but the `Range` type (with smaller bounds); - The bulk of the change is in `#traverseProjection` that now needs to account for an offset when a `projectionDeref` occurs; - When a non-zero offset is encountered a `ProjectionElem::PointerOffset` is appended to the place projections, later this will be turned into a `CtxPointerOffset` when the contexts are being processed; - `CtxPointerOffset` is essentially the same as a subslice as we must have a `Range` to be offsetting through Test cases for read and write are added --------- Co-authored-by: Jost Berthold <jost.berthold@gmail.com>
1 parent 206880e commit 4fb9a32

33 files changed

Lines changed: 460 additions & 209 deletions

kmir/src/kmir/decoding.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from pyk.kast import KInner
4444

4545
from .ty import FieldsShape, IntegerLength, LayoutShape, MachineSize, Scalar, TagEncoding, Ty, TypeMetadata, UintTy
46-
from .value import Metadata
46+
from .value import MetadataSize
4747

4848

4949
@dataclass
@@ -145,7 +145,7 @@ def _pointee_ty(type_info: TypeMetadata) -> Ty | None:
145145
return None
146146

147147

148-
def _metadata(type_info: TypeMetadata) -> Metadata:
148+
def _metadata(type_info: TypeMetadata) -> MetadataSize:
149149
match type_info:
150150
case ArrayT(length=None):
151151
return DynamicSize(1) # 1 is a placeholder, the actual size is inferred from the slice data

kmir/src/kmir/kast.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
from .smir import SMIRInfo
2525
from .ty import TypeMetadata
26-
from .value import Metadata, Value
26+
from .value import MetadataSize, Value
2727

2828

2929
_LOGGER: Final = logging.getLogger(__name__)
@@ -312,6 +312,14 @@ def _fresh_var(self, prefix: str) -> KVariable:
312312

313313
def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInner], KInner | None]:
314314
# returns: symbolic value of given type, related constraints, related pointer metadata
315+
316+
no_metadata = KApply(
317+
'Metadata',
318+
KApply('noMetadataSize', ()),
319+
token(0),
320+
KApply('noMetadataSize', ()),
321+
)
322+
315323
match self.types.get(ty):
316324
case IntT(info):
317325
val, constraints = int_var(self._fresh_var('ARG_INT'), info.value, True)
@@ -359,7 +367,14 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
359367
return (
360368
KApply('Value::Range', (elems,)),
361369
[mlEqualsTrue(eqInt(KApply('sizeList', (elems,)), l))],
362-
KApply('dynamicSize', (l,)),
370+
KApply(
371+
'Metadata',
372+
(
373+
KApply('dynamicSize', (l,)),
374+
token(0),
375+
KApply('dynamicSize', (l,)),
376+
),
377+
),
363378
)
364379

365380
case ArrayT(element_type, size) if size is not None:
@@ -372,7 +387,14 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
372387
return (
373388
KApply('Value::Range', (list_of(elem_vars),)),
374389
elem_constraints,
375-
KApply('staticSize', (token(size),)),
390+
KApply(
391+
'Metadata',
392+
(
393+
KApply('staticSize', (token(size),)),
394+
token(0),
395+
KApply('staticSize', (token(size),)),
396+
),
397+
),
376398
)
377399

378400
case TupleT(components):
@@ -397,10 +419,10 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
397419
KApply(
398420
'Value::Reference',
399421
(
400-
token(0),
422+
token(0), # Stack OFFSET field
401423
KApply('place', (KApply('local', (token(ref),)), KApply('ProjectionElems::empty', ()))),
402424
KApply('Mutability::Mut', ()) if mutable else KApply('Mutability::Not', ()),
403-
metadata if metadata is not None else KApply('noMetadata', ()),
425+
metadata if metadata is not None else no_metadata,
404426
),
405427
),
406428
pointee_constraints,
@@ -418,7 +440,7 @@ def _symbolic_value(self, ty: Ty, mutable: bool) -> tuple[KInner, Iterable[KInne
418440
token(0),
419441
KApply('place', (KApply('local', (token(ref),)), KApply('ProjectionElems::empty', ()))),
420442
KApply('Mutability::Mut', ()) if mutable else KApply('Mutability::Not', ()),
421-
KApply('PtrEmulation', (metadata if metadata is not None else KApply('noMetadata', ()),)),
443+
metadata if metadata is not None else no_metadata,
422444
),
423445
),
424446
pointee_constraints,
@@ -479,7 +501,7 @@ class SimpleRes(NamedTuple):
479501

480502
class ArrayRes(NamedTuple):
481503
value: TypedValue
482-
metadata: Metadata
504+
metadata: MetadataSize
483505

484506

485507
class PointerRes(NamedTuple):

0 commit comments

Comments
 (0)