CommitCommand should be called after emitting the commands to replay a single command. CommitCommand frees all temporary allocated memory and clears the stack.
()
| 259 | // command. |
| 260 | // CommitCommand frees all temporary allocated memory and clears the stack. |
| 261 | func (b *Builder) CommitCommand() { |
| 262 | if !b.inCmd { |
| 263 | panic("CommitCommand called without a call to BeginCommand") |
| 264 | } |
| 265 | b.lastLabel, b.pendingLabel = b.pendingLabel, 0 |
| 266 | b.currentThreadID = b.pendingThreadID |
| 267 | b.inCmd = false |
| 268 | b.temp.reset() |
| 269 | pop := uint32(len(b.stack)) |
| 270 | // Optimise the instructions. |
| 271 | for si := len(b.stack) - 1; si >= 0; si-- { |
| 272 | s := b.stack[si] |
| 273 | switch i := b.instructions[s.idx].(type) { |
| 274 | case asm.Call: // Change calls that push an unused return value to discard the value. |
| 275 | if i.PushReturn { |
| 276 | i.PushReturn = false |
| 277 | b.instructions[s.idx] = i |
| 278 | pop-- |
| 279 | } |
| 280 | case asm.Clone, asm.Push, asm.Load: // Remove unused clones, pushes, loads |
| 281 | b.instructions[s.idx] = asm.Nop{} |
| 282 | pop-- |
| 283 | } |
| 284 | } |
| 285 | // Trim trailing no-ops |
| 286 | for len(b.instructions) > 0 { |
| 287 | if _, nop := b.instructions[len(b.instructions)-1].(asm.Nop); nop { |
| 288 | b.instructions = b.instructions[:len(b.instructions)-1] |
| 289 | } else { |
| 290 | break |
| 291 | } |
| 292 | } |
| 293 | // Pop any remaining stack values |
| 294 | if pop > 0 { |
| 295 | b.instructions = append(b.instructions, asm.Pop{Count: pop}) |
| 296 | } |
| 297 | b.stack = b.stack[:0] |
| 298 | } |
| 299 | |
| 300 | // RevertCommand reverts all the instructions since the last call to |
| 301 | // BeginCommand. Any postbacks issued since the last call to BeginCommand will |