1 6 7 11 12 package org.openlaszlo.sc; 13 import java.io.*; 14 import java.nio.*; 15 import java.util.*; 16 import org.openlaszlo.sc.Instructions.*; 17 import org.openlaszlo.sc.Emitter; 18 import org.openlaszlo.sc.StackModel; 19 20 public class Optimizer implements Emitter { 21 Emitter receiver; 22 List instrBlock; 23 StackModel stackModel; 24 25 public Optimizer (Emitter receiver) { 26 this.receiver = receiver; 27 this.instrBlock = new ArrayList(); 29 this.stackModel = new StackModel(); 32 } 33 34 public void flush() { 35 if (this.instrBlock.size() != 0) { 36 for (Iterator i = instrBlock.iterator(); i.hasNext(); ) { 37 this.receiver.emit((Instruction)i.next()); 38 } 39 this.instrBlock.clear(); 40 if (this.stackModel != null) { 41 this.stackModel.clear(); 42 } else { 43 this.stackModel = new StackModel(); 44 } 45 } 46 } 47 48 public byte[] assemble(List instrs) { 49 for (Iterator i = instrs.iterator(); i.hasNext(); ) { 50 this.emit((Instruction)i.next()); 51 } 52 this.flush(); 53 return this.receiver.assemble(Collections.EMPTY_LIST); 54 } 55 56 public void emit(Instruction instr) { 57 61 StackModel model = this.stackModel; 69 List instrBlock = this.instrBlock; 70 71 if (instr instanceof PUSHInstruction) { 72 PUSHInstruction push = (PUSHInstruction)instr; 73 PUSHInstruction last = model.lastPush(); 74 if (last != null) { 76 if ((Instruction)last != (Instruction)instrBlock.get(instrBlock.size() - 1) && push.isVolatile()) { 80 ; 82 } else if (last.merge(push, model)) { 83 return; 84 } 85 } 86 push = new PUSHInstruction(push.args); 89 instrBlock.add(push); 90 this.stackModel = push.updateStackModel(model); 91 } else if (instr instanceof ConcreteInstruction && 92 ((ConcreteInstruction)instr).op == Actions.DUP) { 93 PUSHInstruction last = model.lastPush(); 95 if (last != null) { 96 if (last.dup(model)) { 99 return; 100 } 101 } 102 if (instrBlock.size() != 0) { 104 instrBlock.add(instr); 106 this.stackModel = instr.updateStackModel(model); 107 } else { 108 this.receiver.emit(instr); 109 } 110 } else { 112 if (instrBlock.size() != 0) { 114 instrBlock.add(instr); 116 this.stackModel = instr.updateStackModel(model); 117 } else { 118 this.receiver.emit(instr); 119 } 120 } 121 if (this.stackModel == null) { 123 this.flush(); 124 } 125 } 126 } 127 | Popular Tags |