primIfReturn merges the basic blocks of the given if_return-primitive into a corresponding conceputal basic block for the primitive.
(condBlock, bodyBlock, exitBlock *basicBlock)
| 236 | // primIfReturn merges the basic blocks of the given if_return-primitive into a |
| 237 | // corresponding conceputal basic block for the primitive. |
| 238 | func (d *decompiler) primIfReturn(condBlock, bodyBlock, exitBlock *basicBlock) (*basicBlock, error) { |
| 239 | // Handle terminators. |
| 240 | condTerm, ok := condBlock.Term.(*ir.TermCondBr) |
| 241 | if !ok { |
| 242 | return nil, errors.Errorf("invalid cond terminator type; expected *ir.TermCondBr, got %T", condBlock.Term) |
| 243 | } |
| 244 | cond := d.value(condTerm.Cond) |
| 245 | // TODO: Figure out a clean way to check if the body basic block is the true |
| 246 | // branch or the false branch. If body is the false branch, negate the |
| 247 | // condition. |
| 248 | bodyTermStmt := d.term(bodyBlock.Term) |
| 249 | block := &basicBlock{BasicBlock: &ir.BasicBlock{}} |
| 250 | block.Term = exitBlock.Term |
| 251 | // Handle instructions. |
| 252 | block.stmts = append(block.stmts, d.stmts(condBlock)...) |
| 253 | body := &ast.BlockStmt{ |
| 254 | List: d.stmts(bodyBlock), |
| 255 | } |
| 256 | body.List = append(body.List, bodyTermStmt) |
| 257 | ifReturnStmt := &ast.IfStmt{ |
| 258 | Cond: cond, |
| 259 | Body: body, |
| 260 | } |
| 261 | block.stmts = append(block.stmts, ifReturnStmt) |
| 262 | block.stmts = append(block.stmts, d.stmts(exitBlock)...) |
| 263 | return block, nil |
| 264 | } |
| 265 | |
| 266 | // primPreLoop merges the basic blocks of the given pre_loop-primitive into a |
| 267 | // corresponding conceputal basic block for the primitive. |