private int PerformMethodOptimization (IodineMethod method) { int removed = 0; Instruction[] oldInstructions = method.Body.ToArray (); Instruction[] newInstructions = new Instruction[method.Body.Count]; int next = 0; Instruction last = new Instruction (); for (int i = 0; i < method.Body.Count; i++) { Instruction curr = oldInstructions [i]; if (i != 0 && curr.OperationCode == Opcode.Pop) { if (last.OperationCode == Opcode.LoadLocal || last.OperationCode == Opcode.LoadGlobal || last.OperationCode == Opcode.LoadNull) { oldInstructions [i] = new Instruction (curr.Location, Opcode.Nop, 0); oldInstructions [i - 1] = new Instruction (curr.Location, Opcode.Nop, 0); removed++; } } else if (curr.OperationCode == Opcode.Jump && curr.Argument == i + 1) { oldInstructions [i] = new Instruction (curr.Location, Opcode.Nop, 0); removed++; } last = curr; } for (int i = 0; i < oldInstructions.Length; i++) { Instruction curr = oldInstructions [i]; if (curr.OperationCode == Opcode.Nop) { ShiftLabels (next, newInstructions); ShiftLabels (next, oldInstructions); } else { newInstructions [next++] = curr; } } method.Body.Clear (); method.Body.AddRange (newInstructions); return removed; }
public IodineInstruction (IodineMethod method, Instruction instruction) : base (TypeDefinition) { Instruction = instruction; parentMethod = method; SetAttribute ("opcode", new IodineInteger ((long)instruction.OperationCode)); SetAttribute ("immediate", new IodineInteger (instruction.Argument)); }
private void ShiftLabels (int start, Instruction[] instructions) { for (int i = 0; i < instructions.Length; i++) { Instruction ins = instructions [i]; if (ins.OperationCode == Opcode.Jump || ins.OperationCode == Opcode.JumpIfFalse || ins.OperationCode == Opcode.JumpIfTrue || ins.OperationCode == Opcode.PushExceptionHandler) { if (ins.Argument > start) { instructions [i] = new Instruction (ins.Location, ins.OperationCode, ins.Argument - 1); } } } }
public void PerformOptimization (IodineMethod method) { List <ReachableRegion> regions = new List<ReachableRegion> (); int reachableSize = 0; FindRegion (method, regions, 0); foreach (ReachableRegion region in regions) { reachableSize += region.Size + 1; } Instruction[] oldInstructions = method.Body.ToArray (); Instruction[] newInstructions = new Instruction[method.Body.Count]; int next = 0; for (int i = 0; i < method.Body.Count; i++) { if (IsReachable (regions, i)) { newInstructions [next++] = oldInstructions [i]; } else { ShiftLabels (next, oldInstructions); ShiftLabels (next, newInstructions); } } method.Body.Clear (); method.Body.AddRange (newInstructions); }
public void FinalizeLabels () { foreach (int position in labelReferences.Keys) { instructions [position] = new Instruction (instructions [position].Location, instructions [position].OperationCode, labelReferences [position]._Position); } }
private IodineObject Invoke(IodineMethod method, IodineObject[] arguments) { if (method.Body.Count > 0) { currLoc = method.Body [0].Location; } int insCount = method.Body.Count; int i = 0; foreach (string param in method.Parameters.Keys) { if (method.Variadic && (method.AcceptsKeywordArgs ? i == method.Parameters.Keys.Count - 2 : i == method.Parameters.Keys.Count - 1)) { IodineObject[] tupleItems = new IodineObject[arguments.Length - i]; Array.Copy (arguments, i, tupleItems, 0, arguments.Length - i); Top.StoreLocal (method.Parameters [param], new IodineTuple (tupleItems)); } else if (i == method.Parameters.Keys.Count - 1 && method.AcceptsKeywordArgs) { if (i < arguments.Length && arguments [i] is IodineHashMap) { Top.StoreLocal (method.Parameters [param], arguments [i]); } else { Top.StoreLocal (method.Parameters [param], new IodineHashMap ()); } } else { Top.StoreLocal (method.Parameters [param], arguments [i++]); } } StackFrame top = Top; while (top.InstructionPointer < insCount && !top.AbortExecution && !Top.Yielded) { instruction = method.Body [Top.InstructionPointer++]; ExecuteInstruction (); top.Location = currLoc; } if (top.AbortExecution) { while (top.DisposableObjects.Count > 0) { top.DisposableObjects.Pop ().Exit (this); } return IodineNull.Instance; } IodineObject retVal = last ?? IodineNull.Instance; EndFrame (); while (top.DisposableObjects.Count > 0) { top.DisposableObjects.Pop ().Exit (this); } return retVal; }