@@ -329,7 +329,7 @@ In contrast to regular write operations, the value does not have to be _mutable_
329
329
330
330
rule <k> VAL:TypedLocal ~> #markMoved(OLDLOCAL, local(I), PROJECTIONS) ~> CONT
331
331
=>
332
- #projectedUpdate(makeProjectedUpdate (toLocal(I), OLDLOCAL, PROJECTIONS, .Contexts, STACK, LOCALS), Moved, true)
332
+ #projectedUpdate(#readProjection (toLocal(I), OLDLOCAL, PROJECTIONS, .Contexts, STACK, LOCALS), Moved, true)
333
333
~> VAL
334
334
~> CONT
335
335
</k>
@@ -403,11 +403,9 @@ Write operations to places that include (a chain of) projections are handled by
403
403
404
404
``` k
405
405
syntax KItem ::= #projectedUpdate ( ProjectedUpdate , TypedLocal , Bool )
406
- syntax ProjectedUpdate ::= makeProjectedUpdate(WriteTo, TypedLocal, ProjectionElems, Contexts, List, List) [function] // total
407
- | ProjectedUpdate(WriteTo, Contexts)
408
406
409
407
rule <k> #setLocalValue(place(local(I), PROJ), VAL)
410
- => #projectedUpdate(makeProjectedUpdate (toLocal(I), {LOCALS[I]}:>TypedLocal, PROJ, .Contexts, STACK, LOCALS), VAL, false)
408
+ => #projectedUpdate(#readProjection (toLocal(I), {LOCALS[I]}:>TypedLocal, PROJ, .Contexts, STACK, LOCALS), VAL, false)
411
409
...
412
410
</k>
413
411
<stack> STACK </stack>
@@ -430,33 +428,48 @@ The solution is to use rewrite operations in a downward pass through the project
430
428
| toStack ( Int , Local )
431
429
432
430
// retains information about the value that was deconstructed by a projection
433
- syntax Context ::= CtxField( Ty, VariantIdx, List, Int )
434
- | CtxIndex( Ty, List , Int ) // array index constant or has been read before
431
+ syntax Context ::= CtxField( Ty, VariantIdx, List, Int, Mutability )
432
+ | CtxIndex( Ty, List, Int, Mutability ) // array index constant or has been read before
435
433
436
434
syntax Contexts ::= List{Context, ""}
437
435
438
436
syntax TypedLocal ::= #buildUpdate ( TypedLocal, Contexts ) [function]
439
-
437
+ // -------------------------------------------------------------------
440
438
rule #buildUpdate(VAL, .Contexts) => VAL
441
439
[preserves-definedness]
442
440
443
- rule #buildUpdate(VAL, CtxField(TY, IDX, ARGS, I) CTXS)
444
- => #buildUpdate(typedValue(Aggregate(IDX, ARGS[I <- VAL]), TY, mutabilityMut ), CTXS)
441
+ rule #buildUpdate(VAL, CtxField(TY, IDX, ARGS, I, MUT ) CTXS)
442
+ => #buildUpdate(typedValue(Aggregate(IDX, ARGS[I <- VAL]), TY, MUT ), CTXS)
445
443
[preserves-definedness] // valid list indexing checked upon context construction
446
444
447
- rule #buildUpdate(VAL, CtxIndex(TY, ELEMS, I) CTXS)
448
- => #buildUpdate(typedValue(Range(ELEMS[I <- VAL]), TY, mutabilityMut ), CTXS)
445
+ rule #buildUpdate(VAL, CtxIndex(TY, ELEMS, I, MUT ) CTXS)
446
+ => #buildUpdate(typedValue(Range(ELEMS[I <- VAL]), TY, MUT ), CTXS)
449
447
[preserves-definedness] // valid list indexing checked upon context construction
450
448
451
- rule makeProjectedUpdate(DEST, typedValue(Aggregate(IDX, ARGS), TY, _), projectionElemField(fieldIdx(I), _) PROJS, CTXTS, STACK, LOCALS)
452
- => makeProjectedUpdate(DEST, {ARGS[I]}:>TypedLocal, PROJS, CtxField(TY, IDX, ARGS, I) CTXTS, STACK, LOCALS)
449
+ syntax ProjectedUpdate ::= #readProjection(WriteTo, TypedLocal, ProjectionElems, Contexts, List, List) [function] // total
450
+ | ProjectedUpdate(WriteTo, Contexts)
451
+ // ----------------------------------------------------------
452
+ rule #readProjection(
453
+ _DEST,
454
+ typedValue(Aggregate(IDX, ARGS), TY, MUT) => {ARGS[I]}:>TypedLocal,
455
+ projectionElemField(fieldIdx(I), TY) PROJS => PROJS,
456
+ CTXTS => CtxField(TY, IDX, ARGS, I, MUT) CTXTS,
457
+ _STACK,
458
+ _LOCALS
459
+ )
453
460
requires 0 <=Int I
454
461
andBool I <Int size(ARGS)
455
462
andBool isTypedLocal(ARGS[I])
456
463
[preserves-definedness] // valid list indexing checked
457
464
458
- rule makeProjectedUpdate(DEST, typedValue(Range(ELEMENTS), TY, _), projectionElemIndex(local(LOCAL)) PROJS, CTXTS, STACK, LOCALS)
459
- => makeProjectedUpdate(DEST, {ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)]}:>TypedValue, PROJS, CtxIndex(TY, ELEMENTS, #expectUsize({LOCALS[LOCAL]}:>TypedValue)) CTXTS, STACK, LOCALS)
465
+ rule #readProjection(
466
+ _DEST,
467
+ typedValue(Range(ELEMENTS), TY, MUT) => {ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)]}:>TypedValue,
468
+ projectionElemIndex(local(LOCAL)) PROJS => PROJS,
469
+ CTXTS => CtxIndex(TY, ELEMENTS, #expectUsize({LOCALS[LOCAL]}:>TypedValue), MUT) CTXTS,
470
+ _STACK,
471
+ LOCALS
472
+ )
460
473
requires 0 <=Int LOCAL
461
474
andBool LOCAL <Int size(LOCALS)
462
475
andBool isTypedValue(LOCALS[LOCAL])
@@ -466,36 +479,60 @@ The solution is to use rewrite operations in a downward pass through the project
466
479
andBool isTypedValue(ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)])
467
480
[preserves-definedness] // index checked, valid Int can be read, ELEMENT indexable and writeable or forced
468
481
469
- rule makeProjectedUpdate(DEST, typedValue(Range(ELEMENTS), TY, _), projectionElemConstantIndex(OFFSET:Int, _MINLEN, false) PROJS, CTXTS, STACK, LOCALS)
470
- => makeProjectedUpdate(DEST, {ELEMENTS[OFFSET]}:>TypedValue, PROJS, CtxIndex(TY, ELEMENTS, OFFSET) CTXTS, STACK, LOCALS)
482
+ rule #readProjection(
483
+ _DEST,
484
+ typedValue(Range(ELEMENTS), TY, MUT) => {ELEMENTS[OFFSET]}:>TypedValue,
485
+ projectionElemConstantIndex(OFFSET:Int, _MINLEN, false) PROJS => PROJS,
486
+ CTXTS => CtxIndex(TY, ELEMENTS, OFFSET, MUT) CTXTS,
487
+ _STACK,
488
+ _LOCALS
489
+ )
471
490
requires 0 <=Int OFFSET
472
491
andBool OFFSET <Int size(ELEMENTS)
473
492
andBool isTypedValue(ELEMENTS[OFFSET])
474
493
[preserves-definedness] // ELEMENT indexable and writeable or forced
475
494
476
- rule makeProjectedUpdate(DEST, typedValue(Range(ELEMENTS), TY, _), projectionElemConstantIndex(OFFSET:Int, MINLEN, true) PROJS, CTXTS, STACK, LOCALS)
477
- => makeProjectedUpdate(DEST, {ELEMENTS[OFFSET]}:>TypedValue, PROJS, CtxIndex(TY, ELEMENTS, MINLEN -Int OFFSET) CTXTS, STACK, LOCALS)
495
+ rule #readProjection(
496
+ _DEST,
497
+ typedValue(Range(ELEMENTS), TY, MUT) => {ELEMENTS[OFFSET]}:>TypedValue,
498
+ projectionElemConstantIndex(OFFSET:Int, MINLEN, true) PROJS => PROJS,
499
+ CTXTS => CtxIndex(TY, ELEMENTS, MINLEN -Int OFFSET, MUT) CTXTS,
500
+ _STACK,
501
+ _LOCALS
502
+ )
478
503
requires 0 <Int OFFSET
479
504
andBool OFFSET <=Int MINLEN
480
505
andBool MINLEN ==Int size(ELEMENTS) // assumed for valid MIR code
481
506
andBool isTypedValue(ELEMENTS[MINLEN -Int OFFSET])
482
507
[preserves-definedness] // ELEMENT indexable and writeable or forced
483
508
484
- rule makeProjectedUpdate(_DEST, typedValue(Reference(OFFSET, place(LOCAL, PLACEPROJ), _), _, _), projectionElemDeref PROJS, _CTXTS, STACK, LOCALS)
485
- => makeProjectedUpdate(toStack(OFFSET, LOCAL), #localFromFrame({STACK[OFFSET -Int 1]}:>StackFrame, LOCAL, OFFSET), appendP(PLACEPROJ, PROJS), .Contexts, STACK, LOCALS)
509
+ rule #readProjection(
510
+ _DEST => toStack(OFFSET, LOCAL),
511
+ typedValue(Reference(OFFSET, place(LOCAL, PLACEPROJ), _), _, _),
512
+ projectionElemDeref PROJS => appendP(PLACEPROJ, PROJS),
513
+ _CTXTS => .Contexts,
514
+ STACK,
515
+ _LOCALS
516
+ )
486
517
requires 0 <Int OFFSET
487
518
andBool OFFSET <=Int size(STACK)
488
519
andBool isStackFrame(STACK[OFFSET -Int 1])
489
520
[preserves-definedness]
490
521
491
- rule makeProjectedUpdate(_DEST, typedValue(Reference(OFFSET, place(local(I), PLACEPROJ), _), _, _), projectionElemDeref PROJS, _CTXTS, STACK, LOCALS)
492
- => makeProjectedUpdate(toLocal(I), {LOCALS[I]}:>TypedLocal, appendP(PLACEPROJ, PROJS), .Contexts, STACK, LOCALS)
522
+ rule #readProjection(
523
+ _DEST => toLocal(I),
524
+ typedValue(Reference(OFFSET, place(local(I), PLACEPROJ), _), _, _) => {LOCALS[I]}:>TypedLocal,
525
+ projectionElemDeref PROJS => appendP(PLACEPROJ, PROJS),
526
+ _CTXTS => .Contexts,
527
+ _STACK,
528
+ LOCALS
529
+ )
493
530
requires OFFSET ==Int 0
494
531
andBool 0 <=Int I
495
532
andBool I <Int size(LOCALS)
496
533
[preserves-definedness]
497
534
498
- rule makeProjectedUpdate (DEST, _:TypedValue, .ProjectionElems, CONTEXTS, _, _)
535
+ rule #readProjection (DEST, _:TypedValue, .ProjectionElems, CONTEXTS, _, _)
499
536
=> ProjectedUpdate(DEST, CONTEXTS)
500
537
501
538
rule <k> #projectedUpdate(ProjectedUpdate(toLocal(I), CONTEXTS), NEW, false)
0 commit comments