@@ -530,7 +530,9 @@ Therefore a heuristics is used here:
530530 _SPAN
531531 )
532532 =>
533- #setTupleArgs(2, getValue(LOCALS, TUPLE)) ~> #execBlock(FIRST)
533+ #setLocalValue(place(local(1), .ProjectionElems), #incrementRef(getValue(LOCALS, CLOSURE)))
534+ ~> #setTupleArgs(2, getValue(LOCALS, TUPLE))
535+ ~> #execBlock(FIRST)
534536 // arguments are tuple components, stored as _2 .. _n
535537 ...
536538 </k>
@@ -547,7 +549,7 @@ Therefore a heuristics is used here:
547549 andBool 0 <=Int TUPLE andBool TUPLE <Int size(LOCALS)
548550 andBool isTypedValue(LOCALS[TUPLE])
549551 andBool isTupleType(lookupTy(tyOfLocal({LOCALS[TUPLE]}:>TypedLocal)))
550- andBool isTypedLocal (LOCALS[CLOSURE])
552+ andBool isTypedValue (LOCALS[CLOSURE])
551553 andBool typeInfoVoidType ==K lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal))
552554 // either the closure ref type is missing from type table
553555 [priority(40), preserves-definedness]
@@ -560,7 +562,9 @@ Therefore a heuristics is used here:
560562 _SPAN
561563 )
562564 =>
563- #setTupleArgs(2, getValue(LOCALS, TUPLE)) ~> #execBlock(FIRST)
565+ #setLocalValue(place(local(1), .ProjectionElems), #incrementRef(getValue(LOCALS, CLOSURE)))
566+ ~> #setTupleArgs(2, getValue(LOCALS, TUPLE))
567+ ~> #execBlock(FIRST)
564568 // arguments are tuple components, stored as _2 .. _n
565569 ...
566570 </k>
@@ -577,7 +581,7 @@ Therefore a heuristics is used here:
577581 andBool 0 <=Int TUPLE andBool TUPLE <Int size(LOCALS)
578582 andBool isTypedValue(LOCALS[TUPLE])
579583 andBool isTupleType(lookupTy(tyOfLocal({LOCALS[TUPLE]}:>TypedLocal)))
580- andBool isTypedLocal (LOCALS[CLOSURE])
584+ andBool isTypedValue (LOCALS[CLOSURE])
581585 // or the closure ref type pointee is missing from the type table
582586 andBool isRefType(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))
583587 andBool isTy(pointeeTy(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal))))
@@ -587,6 +591,72 @@ Therefore a heuristics is used here:
587591 )
588592 [priority(45), preserves-definedness]
589593
594+ // Closure-call setup for typed closure environments.
595+ // When closure pointee type is known (`typeInfoFunType`), unpack tuple args into `_2 .. _n`.
596+ rule [setupCalleeClosure3]: <k> #setUpCalleeData(
597+ monoItemFn(_, _, someBody(body((FIRST:BasicBlock _) #as BLOCKS, NEWLOCALS, _, _, _, _))),
598+ operandMove(place(local(CLOSURE:Int), .ProjectionElems))
599+ operandMove(place(local(TUPLE), .ProjectionElems))
600+ .Operands,
601+ _SPAN
602+ )
603+ =>
604+ #setLocalValue(place(local(1), .ProjectionElems), #incrementRef(getValue(LOCALS, CLOSURE)))
605+ ~> #setTupleArgs(2, getValue(LOCALS, TUPLE))
606+ ~> #execBlock(FIRST)
607+ // arguments are tuple components, stored as _2 .. _n
608+ ...
609+ </k>
610+ <currentFrame>
611+ <currentBody> _ => toKList(BLOCKS) </currentBody>
612+ <locals> LOCALS => #reserveFor(NEWLOCALS) </locals>
613+ <stack>
614+ (ListItem(CALLERFRAME => #updateStackLocal(#updateStackLocal(CALLERFRAME, TUPLE, Moved), CLOSURE, Moved)))
615+ _:List
616+ </stack>
617+ ...
618+ </currentFrame>
619+ requires 0 <=Int CLOSURE andBool CLOSURE <Int size(LOCALS)
620+ andBool 0 <=Int TUPLE andBool TUPLE <Int size(LOCALS)
621+ andBool isTypedValue(LOCALS[TUPLE])
622+ andBool isTupleType(lookupTy(tyOfLocal({LOCALS[TUPLE]}:>TypedLocal)))
623+ andBool isTypedValue(LOCALS[CLOSURE])
624+ andBool isRefType(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))
625+ andBool isFunType(#lookupMaybeTy(pointeeTy(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))))
626+ [priority(46), preserves-definedness]
627+
628+ // Stable MIR may expose closures as direct `typeInfoFunType` values instead of references.
629+ // In that case we still need to unpack the tuple argument payload into `_2 .. _n`.
630+ rule [setupCalleeClosure4]: <k> #setUpCalleeData(
631+ monoItemFn(_, _, someBody(body((FIRST:BasicBlock _) #as BLOCKS, NEWLOCALS, _, _, _, _))),
632+ operandMove(place(local(CLOSURE:Int), .ProjectionElems))
633+ operandMove(place(local(TUPLE), .ProjectionElems))
634+ .Operands,
635+ _SPAN
636+ )
637+ =>
638+ #setLocalValue(place(local(1), .ProjectionElems), getValue(LOCALS, CLOSURE))
639+ ~> #setTupleArgs(2, getValue(LOCALS, TUPLE))
640+ ~> #execBlock(FIRST)
641+ ...
642+ </k>
643+ <currentFrame>
644+ <currentBody> _ => toKList(BLOCKS) </currentBody>
645+ <locals> LOCALS => #reserveFor(NEWLOCALS) </locals>
646+ <stack>
647+ (ListItem(CALLERFRAME => #updateStackLocal(#updateStackLocal(CALLERFRAME, TUPLE, Moved), CLOSURE, Moved)))
648+ _:List
649+ </stack>
650+ ...
651+ </currentFrame>
652+ requires 0 <=Int CLOSURE andBool CLOSURE <Int size(LOCALS)
653+ andBool 0 <=Int TUPLE andBool TUPLE <Int size(LOCALS)
654+ andBool isTypedValue(LOCALS[TUPLE])
655+ andBool isTupleType(lookupTy(tyOfLocal({LOCALS[TUPLE]}:>TypedLocal)))
656+ andBool isTypedValue(LOCALS[CLOSURE])
657+ andBool isFunType(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))
658+ [priority(47), preserves-definedness]
659+
590660 syntax Bool ::= isTupleType ( TypeInfo ) [function, total]
591661 | isRefType ( TypeInfo ) [function, total]
592662 | isFunType ( TypeInfo ) [function, total]
0 commit comments