You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement Subslice projection and RawPtr aggregate value (#646)
* Aggregate kind `RawPtr` (`RValue`) takes two arguments, a pointer and
metadata, and creates a new pointer.
No test program (yet).
* Subslice (`ProjectionElem`) : operates on arrays and slices, extracts
a shorter (possibly empty) slice.
Tested using a small program that matches the tail of a slice using `let
[a, b, c, rest @ ..] = input_slice`.
Both are required for the P-token proofs to progress.
Also copied the description of all projections from the docs into the
actual semantics.
Copy file name to clipboardExpand all lines: kmir/src/kmir/kdist/mir-semantics/rt/data.md
+94Lines changed: 94 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -211,6 +211,29 @@ A variant `#forceSetLocal` is provided for setting the local value without check
211
211
212
212
### Traversing Projections for Reads and Writes
213
213
214
+
A `Place` to read from or write to is a `Local` variable (actually just its index), and a (potentially empty) vector of `ProjectionElem`ents.
215
+
216
+
There are different kinds of `ProjectionElem`s:
217
+
-`Deref`erencing references or pointers (or `Box`es allocated in the heap)
218
+
- read data at the address given in the local
219
+
- operates on a value that is a pointer or reference to another
220
+
-`Field` access in struct.s and tuples
221
+
- fields are numbered from zero (in source order). The field type is also given.
222
+
- operates on structs and tuples
223
+
-`Index`ing into arrays or slices
224
+
- operates on a value that is an array (statically-known size) or slice (variable size)
225
+
- indexes zero-based from the front
226
+
- the index is provided in another local
227
+
-`ConstantIndex`ing with a constant offset
228
+
- operates on a value that is an array (statically-known size) or slice (variable size)
229
+
- the index was statically known and is therefore a `u64`
230
+
- the `min_length` of the object to index into is provided as another `u64`
231
+
- when `from_end` is true, this is taken to be exact, and indexing happens from the end
232
+
-`Subslice`
233
+
- a slice from `from` to `to` (the latter either from start or `from_end`)
234
+
- operates on a value that is an array (statically-known size) or slice (variable size)
235
+
- Casting values (`OpaqueCast` or `Downcast` - variant narrowing) and `Subtype`ing
236
+
214
237
Read and write operations to places that include (a chain of) projections are handled by a special rewrite symbol `#traverseProjection`.
215
238
This helper does the projection lookup and maintains the context chain along the lookup path, then passes control back to `#readProjection` and `#writeProjection`/`#setMoved`.
216
239
A `Deref` projection in the projections list changes the target of the write operation, while `Field` updates change the value that is being written (updating just one field of it), recursively.
@@ -278,6 +301,7 @@ These helpers mark down, as we traverse the projection, what `Place` we are curr
278
301
// retains information about the value that was deconstructed by a projection
279
302
syntax Context ::= CtxField( VariantIdx, List, Int )
280
303
| CtxIndex( List , Int ) // array index constant or has been read before
304
+
| CtxSubslice( List , Int , Int ) // start and end always counted from beginning
281
305
282
306
syntax Contexts ::= List{Context, ""}
283
307
@@ -294,6 +318,12 @@ These helpers mark down, as we traverse the projection, what `Place` we are curr
294
318
=> #buildUpdate(Range(ELEMS[I <- VAL]), CTXS)
295
319
[preserves-definedness] // valid list indexing checked upon context construction
296
320
321
+
// we don't expect an update to happen on an entire _subslice_ but define a rule for it anyway
requires size(INNER) ==Int END -Int START // ensures updateList is defined
325
+
[preserves-definedness] // START,END indexes checked before, length check for update here
326
+
297
327
syntax StackFrame ::= #updateStackLocal ( StackFrame, Int, Value ) [function]
298
328
299
329
rule #updateStackLocal(StackFrame(CALLER, DEST, TARGET, UNWIND, LOCALS), I, VAL)
@@ -460,6 +490,52 @@ In case of a `ConstantIndex`, the index is provided as an immediate value, toget
460
490
rule #expectUsize(Integer(I, 64, false)) => I
461
491
```
462
492
493
+
A `Subslice` projection operates on an array or slice (`Range`) value to extract a slice of the array from a start index to an end index (exclusive) [^subslice].
494
+
Start and end index are given as immediate values.
495
+
Similar to `ConstantIndex`, the slice _end_ index may count from the _end_ or the start of the array if flagged as such.
0 commit comments