@@ -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