@@ -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,20 +581,89 @@ 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))))
584588 andBool lookupTy({pointeeTy(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))}:>Ty) ==K typeInfoVoidType
585589 [priority(45), preserves-definedness]
586590
591+ // Closure-call setup for typed closure environments.
592+ // When closure pointee type is known (`typeInfoFunType`), unpack tuple args into `_2 .. _n`.
593+ rule [setupCalleeClosure3]: <k> #setUpCalleeData(
594+ monoItemFn(_, _, someBody(body((FIRST:BasicBlock _) #as BLOCKS, NEWLOCALS, _, _, _, _))),
595+ operandMove(place(local(CLOSURE:Int), .ProjectionElems))
596+ operandMove(place(local(TUPLE), .ProjectionElems))
597+ .Operands,
598+ _SPAN
599+ )
600+ =>
601+ #setLocalValue(place(local(1), .ProjectionElems), #incrementRef(getValue(LOCALS, CLOSURE)))
602+ ~> #setTupleArgs(2, getValue(LOCALS, TUPLE))
603+ ~> #execBlock(FIRST)
604+ // arguments are tuple components, stored as _2 .. _n
605+ ...
606+ </k>
607+ <currentFrame>
608+ <currentBody> _ => toKList(BLOCKS) </currentBody>
609+ <locals> LOCALS => #reserveFor(NEWLOCALS) </locals>
610+ <stack>
611+ (ListItem(CALLERFRAME => #updateStackLocal(#updateStackLocal(CALLERFRAME, TUPLE, Moved), CLOSURE, Moved)))
612+ _:List
613+ </stack>
614+ ...
615+ </currentFrame>
616+ requires 0 <=Int CLOSURE andBool CLOSURE <Int size(LOCALS)
617+ andBool 0 <=Int TUPLE andBool TUPLE <Int size(LOCALS)
618+ andBool isTypedValue(LOCALS[TUPLE])
619+ andBool isTupleType(lookupTy(tyOfLocal({LOCALS[TUPLE]}:>TypedLocal)))
620+ andBool isTypedValue(LOCALS[CLOSURE])
621+ andBool isRefType(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))
622+ andBool isFunType(#lookupMaybeTy(pointeeTy(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))))
623+ [priority(46), preserves-definedness]
624+
625+ // Stable MIR may expose closures as direct `typeInfoFunType` values instead of references.
626+ // In that case we still need to unpack the tuple argument payload into `_2 .. _n`.
627+ rule [setupCalleeClosure4]: <k> #setUpCalleeData(
628+ monoItemFn(_, _, someBody(body((FIRST:BasicBlock _) #as BLOCKS, NEWLOCALS, _, _, _, _))),
629+ operandMove(place(local(CLOSURE:Int), .ProjectionElems))
630+ operandMove(place(local(TUPLE), .ProjectionElems))
631+ .Operands,
632+ _SPAN
633+ )
634+ =>
635+ #setLocalValue(place(local(1), .ProjectionElems), getValue(LOCALS, CLOSURE))
636+ ~> #setTupleArgs(2, getValue(LOCALS, TUPLE))
637+ ~> #execBlock(FIRST)
638+ ...
639+ </k>
640+ <currentFrame>
641+ <currentBody> _ => toKList(BLOCKS) </currentBody>
642+ <locals> LOCALS => #reserveFor(NEWLOCALS) </locals>
643+ <stack>
644+ (ListItem(CALLERFRAME => #updateStackLocal(#updateStackLocal(CALLERFRAME, TUPLE, Moved), CLOSURE, Moved)))
645+ _:List
646+ </stack>
647+ ...
648+ </currentFrame>
649+ requires 0 <=Int CLOSURE andBool CLOSURE <Int size(LOCALS)
650+ andBool 0 <=Int TUPLE andBool TUPLE <Int size(LOCALS)
651+ andBool isTypedValue(LOCALS[TUPLE])
652+ andBool isTupleType(lookupTy(tyOfLocal({LOCALS[TUPLE]}:>TypedLocal)))
653+ andBool isTypedValue(LOCALS[CLOSURE])
654+ andBool isFunType(lookupTy(tyOfLocal({LOCALS[CLOSURE]}:>TypedLocal)))
655+ [priority(47), preserves-definedness]
656+
587657 syntax Bool ::= isTupleType ( TypeInfo ) [function, total]
588658 | isRefType ( TypeInfo ) [function, total]
659+ | isFunType ( TypeInfo ) [function, total]
589660 // -------------------------------------------------------
590661 rule isTupleType(typeInfoTupleType(_, _)) => true
591662 rule isTupleType( _ ) => false [owise]
592663 rule isRefType(typeInfoRefType(_)) => true
593664 rule isRefType( _ ) => false [owise]
665+ rule isFunType(typeInfoFunType(_)) => true
666+ rule isFunType( _ ) => false [owise]
594667
595668 syntax KItem ::= #setTupleArgs ( Int , Value )
596669 | #setTupleArgs ( Int , List )
0 commit comments