MCPcopy Create free account
hub / github.com/decomp/decomp / primIfElse

Method primIfElse

cmd/ll2go/primitive.go:188–234  ·  view source on GitHub ↗

primIfElse merges the basic blocks of the given if_else-primitive into a corresponding conceputal basic block for the primitive.

(condBlock, bodyTrueBlock, bodyFalseBlock, exitBlock *basicBlock)

Source from the content-addressed store, hash-verified

186// primIfElse merges the basic blocks of the given if_else-primitive into a
187// corresponding conceputal basic block for the primitive.
188func (d *decompiler) primIfElse(condBlock, bodyTrueBlock, bodyFalseBlock, exitBlock *basicBlock) (*basicBlock, error) {
189 // Handle terminators.
190 var cond ast.Expr
191 switch condTerm := condBlock.Term.(type) {
192 case *ir.TermCondBr:
193 cond = d.value(condTerm.Cond)
194 case *ir.TermSwitch:
195 cases := condTerm.Cases
196 if len(cases) != 1 {
197 return nil, errors.Errorf("invalid number of switch cases in if_else primitive; expected 1, got %d", len(cases))
198 }
199 cond = &ast.BinaryExpr{
200 X: d.value(condTerm.X),
201 Op: token.EQL,
202 Y: d.constant(cases[0].X),
203 }
204 default:
205 return nil, errors.Errorf("invalid cond terminator type; expected *ir.TermCondBr, got %T", condBlock.Term)
206 }
207 // TODO: Figure out a clean way to check if the body_true basic block is the
208 // true branch or the false branch. If body_true is the false branch, use
209 // body_true for the else body of the if-statement.
210 if _, ok := bodyTrueBlock.Term.(*ir.TermBr); !ok {
211 return nil, errors.Errorf("invalid body_true terminator type; expected *ir.TermBr, got %T", bodyTrueBlock.Term)
212 }
213 if _, ok := bodyFalseBlock.Term.(*ir.TermBr); !ok {
214 return nil, errors.Errorf("invalid body_false terminator type; expected *ir.TermBr, got %T", bodyFalseBlock.Term)
215 }
216 block := &basicBlock{BasicBlock: &ir.BasicBlock{}}
217 block.Term = exitBlock.Term
218 // Handle instructions.
219 block.stmts = append(block.stmts, d.stmts(condBlock)...)
220 bodyTrue := &ast.BlockStmt{
221 List: d.stmts(bodyTrueBlock),
222 }
223 bodyFalse := &ast.BlockStmt{
224 List: d.stmts(bodyFalseBlock),
225 }
226 ifElseStmt := &ast.IfStmt{
227 Cond: cond,
228 Body: bodyTrue,
229 Else: bodyFalse,
230 }
231 block.stmts = append(block.stmts, ifElseStmt)
232 block.stmts = append(block.stmts, d.stmts(exitBlock)...)
233 return block, nil
234}
235
236// primIfReturn merges the basic blocks of the given if_return-primitive into a
237// corresponding conceputal basic block for the primitive.

Callers 1

primMethod · 0.95

Calls 3

valueMethod · 0.95
constantMethod · 0.95
stmtsMethod · 0.95

Tested by

no test coverage detected