@@ -219,9 +219,10 @@ NB that a stack height of `0` cannot occur here, because the compiler prevents l
219219If the local ` _0 ` does not have a value (i.e., it remained uninitialised), the function returns unit and writing the value is skipped.
220220
221221``` k
222- // `place(local(-1), .ProjectionElems)` is a sentinel destination meaning that the caller
223- // ignores the callee's return value. Skip the normal writeback path in that case, because
224- // `#setLocalValue` only accepts real local indices and would get stuck on `local(-1)`.
222+ // `place(local(-1), .ProjectionElems)` is the sentinel destination for calls whose
223+ // return should not be written back. Without this rule, the return path would fall
224+ // through to `#setLocalValue`, which only accepts real local indices and would get
225+ // stuck on `local(-1)`.
225226 rule [termReturnIgnored]: <k> #execTerminator(terminator(terminatorKindReturn, _SPAN)) ~> _
226227 =>
227228 #execBlockIdx(TARGET)
@@ -390,21 +391,18 @@ where the returned result should go.
390391
391392 rule <k> #consumeNoOpArg(operandConstant(_)) => .K ... </k>
392393
393- rule <k> #consumeNoOpArg(operandValue(_)) => .K ... </k>
394-
395394 rule <k> #consumeNoOpArg(operandCopy(place(local(I), .ProjectionElems))) => .K ... </k>
396- <stack> ListItem(StackFrame(_, _, _, _, CALLERLOCALS)) _:List </stack >
395+ <locals> LOCALS </locals >
397396 requires 0 <=Int I
398- andBool I <Int size(CALLERLOCALS )
399- andBool isTypedValue(CALLERLOCALS [I])
397+ andBool I <Int size(LOCALS )
398+ andBool isTypedValue(LOCALS [I])
400399 [preserves-definedness]
401400
402401 rule <k> #consumeNoOpArg(operandMove(place(local(I), _))) => .K ... </k>
403- <stack> (ListItem(StackFrame(_, _, _, _, CALLERLOCALS) #as CALLERFRAME => #updateStackLocal(CALLERFRAME, I, Moved))) _:List
404- </stack>
402+ <locals> LOCALS => LOCALS[I <- typedValue(Moved, tyOfLocal(getLocal(LOCALS, I)), mutabilityMut)] </locals>
405403 requires 0 <=Int I
406- andBool I <Int size(CALLERLOCALS )
407- andBool isTypedValue(CALLERLOCALS [I])
404+ andBool I <Int size(LOCALS )
405+ andBool isTypedValue(LOCALS [I])
408406 [preserves-definedness]
409407
410408 // Regular function call - full state switching and stack setup
@@ -502,6 +500,7 @@ An operand may be a `Reference` (the only way a function could access another fu
502500
503501``` k
504502 syntax KItem ::= #setUpCalleeData(MonoItemKind, Operands, Span)
503+ | #setUpDropGlueData(MonoItemKind, Value, Span)
505504
506505 // reserve space for local variables and copy/move arguments from old locals into their place
507506 rule [setupCalleeData]: <k> #setUpCalleeData(
@@ -526,6 +525,21 @@ An operand may be a `Reference` (the only way a function could access another fu
526525 </currentFrame>
527526 // TODO: Haven't handled "noBody" case
528527
528+ rule [setupDropGlueData]: <k> #setUpDropGlueData(
529+ monoItemFn(_, _, someBody(body((FIRST:BasicBlock _) #as BLOCKS, NEWLOCALS, _, _, _, _))),
530+ PTR,
531+ _SPAN
532+ )
533+ =>
534+ #setLocalValue(place(local(1), .ProjectionElems), #incrementRef(PTR)) ~> #execBlock(FIRST)
535+ ...
536+ </k>
537+ <currentFrame>
538+ <currentBody> _ => toKList(BLOCKS) </currentBody>
539+ <locals> _ => #reserveFor(NEWLOCALS) </locals>
540+ ...
541+ </currentFrame>
542+
529543 syntax List ::= #reserveFor( LocalDecls ) [function, total]
530544
531545 rule #reserveFor(.LocalDecls) => .List
@@ -534,11 +548,6 @@ An operand may be a `Reference` (the only way a function could access another fu
534548 =>
535549 ListItem(newLocal(TY, MUT)) #reserveFor(REST)
536550
537- syntax Operand ::= operandValue ( Value )
538-
539- // Internal helper operand for already-evaluated runtime values.
540- rule <k> operandValue(VAL) => VAL ... </k>
541-
542551 syntax KItem ::= #setArgsFromStack ( Int, Operands)
543552 | #setArgFromStack ( Int, Operand)
544553 | #execIntrinsic ( MonoItemKind, Operands, Place, Span )
@@ -558,12 +567,6 @@ An operand may be a `Reference` (the only way a function could access another fu
558567 ...
559568 </k>
560569
561- rule <k> #setArgFromStack(IDX, operandValue(VAL))
562- =>
563- #setLocalValue(place(local(IDX), .ProjectionElems), #incrementRef(VAL))
564- ...
565- </k>
566-
567570 rule <k> #setArgFromStack(IDX, operandCopy(place(local(I), .ProjectionElems)))
568571 =>
569572 #setLocalValue(place(local(IDX), .ProjectionElems), #incrementRef(getValue(CALLERLOCALS, I)))
@@ -772,19 +775,20 @@ Drops are elaborated to Noops but still define the continuing control flow. Unre
772775 ...
773776 </k>
774777
775- rule <k> PTR:Value ~> #callDropGlue(FTY, TARGET, UNWIND, SPAN)
776- =>
777- #execTerminatorCall(
778- FTY,
779- lookupFunction(FTY),
780- operandValue(PTR) .Operands,
781- place(local(-1), .ProjectionElems),
782- someBasicBlockIdx(TARGET),
783- UNWIND,
784- SPAN
785- )
786- ...
778+ rule [termCallDropGlue]:
779+ <k> PTR:Value ~> #callDropGlue(FTY, TARGET, UNWIND, SPAN) ~> _
780+ => #setUpDropGlueData(lookupFunction(FTY), PTR, SPAN)
787781 </k>
782+ <currentFunc> CALLER => FTY </currentFunc>
783+ <currentFrame>
784+ <currentBody> _ </currentBody>
785+ <caller> OLDCALLER => CALLER </caller>
786+ <dest> OLDDEST => place(local(-1), .ProjectionElems) </dest>
787+ <target> OLDTARGET => someBasicBlockIdx(TARGET) </target>
788+ <unwind> OLDUNWIND => UNWIND </unwind>
789+ <locals> LOCALS </locals>
790+ </currentFrame>
791+ <stack> STACK => ListItem(StackFrame(OLDCALLER, OLDDEST, OLDTARGET, OLDUNWIND, LOCALS)) STACK </stack>
788792
789793 syntax MIRError ::= "ReachedUnreachable"
790794
0 commit comments