@@ -989,7 +989,8 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
989989    private  mutating  func  visitReturnLike( )  throws  { 
990990        preserveOnStack ( depth:  self . type. results. count) 
991991        for  (index,  resultType)    in  self . type. results. enumerated ( ) . reversed ( )  { 
992-             let  source  =  ensureOnVReg ( try   valueStack. pop ( resultType) ) 
992+             guard  let  operand =  try   popOperand ( resultType)  else  {  continue  } 
993+             let  source  =  ensureOnVReg ( operand) 
993994            let  dest  =  returnReg ( index) 
994995            emitCopyStack ( from:  source,  to:  dest) 
995996        } 
@@ -1170,9 +1171,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
11701171    } 
11711172
11721173    mutating  func  visitEnd( )  throws  ->  Output  { 
1173-         guard  let  poppedFrame =  controlStack. popFrame ( )  else  { 
1174-             throw  TranslationError ( " Unexpected `end` instruction " ) 
1175-         } 
1174+         let  toBePopped  =  try   controlStack. currentFrame ( ) 
11761175        // Reset the last emission to avoid relinking the result of the last instruction inside the block.
11771176        // Relinking results across the block boundary is invalid because the producer instruction is not
11781177        // statically known. Think about the following case:
@@ -1187,46 +1186,47 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
11871186        // ```
11881187        //
11891188        iseqBuilder. resetLastEmission ( ) 
1190-         if  case . block( root:  true )  =  poppedFrame . kind { 
1191-             if  poppedFrame . reachable { 
1189+         if  case . block( root:  true )  =  toBePopped . kind { 
1190+             if  toBePopped . reachable { 
11921191                try   translateReturn ( ) 
11931192                // TODO: Merge logic with regular block frame
1194-                 guard  valueStack. height ==  poppedFrame . stackHeight else  { 
1193+                 guard  valueStack. height ==  toBePopped . stackHeight else  { 
11951194                    throw  ValidationError ( " values remaining on stack at end of block " ) 
11961195                } 
11971196            } 
1198-             try   iseqBuilder. pinLabelHere ( poppedFrame . continuation) 
1197+             try   iseqBuilder. pinLabelHere ( toBePopped . continuation) 
11991198            return 
12001199        } 
12011200
1202-         if  case . if( _,  _,  isElse:  false )  =  poppedFrame . kind { 
1201+         if  case . if( _,  _,  isElse:  false )  =  toBePopped . kind { 
12031202            // `if` inst without `else` must have the same parameter and result types
1204-             let  blockType  =  poppedFrame . blockType
1203+             let  blockType  =  toBePopped . blockType
12051204            guard  blockType. parameters ==  blockType. results else  { 
12061205                throw  TranslationError ( " Expected the same parameter and result types for `if` block but got  \( blockType) " ) 
12071206            } 
12081207        } 
12091208
12101209        // NOTE: `valueStack.height - poppedFrame.stackHeight` is usually the same as `poppedFrame.copyCount`
12111210        // but it's not always the case when this block is already unreachable.
1212-         preserveOnStack ( depth:  Int ( valueStack. height -  poppedFrame . stackHeight) ) 
1213-         switch  poppedFrame . kind { 
1211+         preserveOnStack ( depth:  Int ( valueStack. height -  toBePopped . stackHeight) ) 
1212+         switch  toBePopped . kind { 
12141213        case  . block: 
1215-             try   iseqBuilder. pinLabelHere ( poppedFrame . continuation) 
1214+             try   iseqBuilder. pinLabelHere ( toBePopped . continuation) 
12161215        case  . loop:  break 
12171216        case  . if: 
1218-             try   iseqBuilder. pinLabelHere ( poppedFrame . continuation) 
1217+             try   iseqBuilder. pinLabelHere ( toBePopped . continuation) 
12191218        } 
1220-         for  result  in  poppedFrame . blockType. results. reversed ( )  { 
1221-             guard  try   checkBeforePop ( typeHint:  result,  controlFrame:  poppedFrame )  else  {  continue  } 
1219+         for  result  in  toBePopped . blockType. results. reversed ( )  { 
1220+             guard  try   checkBeforePop ( typeHint:  result,  controlFrame:  toBePopped )  else  {  continue  } 
12221221            _ =  try   valueStack. pop ( result) 
12231222        } 
1224-         guard  valueStack. height ==  poppedFrame . stackHeight else  { 
1223+         guard  valueStack. height ==  toBePopped . stackHeight else  { 
12251224            throw  ValidationError ( " values remaining on stack at end of block " ) 
12261225        } 
1227-         for  result  in  poppedFrame . blockType. results { 
1226+         for  result  in  toBePopped . blockType. results { 
12281227            _ =  valueStack. push ( result) 
12291228        } 
1229+         _ =  controlStack. popFrame ( ) 
12301230    } 
12311231
12321232    private  static  func  computePopCount( 
@@ -1411,7 +1411,6 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
14111411    } 
14121412
14131413    mutating  func  visitReturn( )  throws  ->  Output  { 
1414-         guard  try   controlStack. currentFrame ( ) . reachable else  {  return  } 
14151414        try   translateReturn ( ) 
14161415        try   markUnreachable ( ) 
14171416    } 
0 commit comments