private void InsertInstructions(int ix, CILInstruction[] newInsts, int numNew) { CILInstruction[] newBuff = buffer, oldBuff = buffer; int newSize = tide + numNew - numReplace; if (buffer.Length < newSize) { newBuff = new CILInstruction[newSize]; for (int i = 0; i < ix; i++) { newBuff[i] = oldBuff[i]; } } // shuffle up int offset = numNew - numReplace; int end = ix + numReplace; for (int i = tide - 1; i >= end; i--) { newBuff[i + offset] = oldBuff[i]; } // insert new instructions for (int i = 0; i < numNew; i++) { newBuff[ix + i] = newInsts[i]; } buffer = newBuff; tide += numNew - numReplace; UpdateIndexesFrom(ix); }
/*------------------------- private methods ----------------------------*/ private void AddToBuffer(CILInstruction inst) { if (tide >= buffer.Length) { CILInstruction[] tmp = buffer; buffer = new CILInstruction[tmp.Length * 2]; for (int i = 0; i < tide; i++) { buffer[i] = tmp[i]; } } //Console.WriteLine("Adding instruction at offset " + offset + " with size " + inst.size); //inst.offset = offset; //offset += inst.size; inst.index = (uint)tide; buffer[tide++] = inst; }
internal void SetAndResolveInstructions(CILInstruction[] insts) { offset = 0; SCG.List<CILLabel> labels = new SCG.List<CILLabel>(); foreach (CILInstruction inst in insts) { inst.offset = offset; offset += inst.size; if (inst is BranchInstr) { ((BranchInstr)inst).MakeTargetLabel(labels); } else if (inst is SwitchInstr) { ((SwitchInstr)inst).MakeTargetLabels(labels); } } if (exceptions != null) { for (int i = 0; i < exceptions.Count; i++) { exceptions[i] = ((EHClause)exceptions[i]).MakeTryBlock(labels); } } if (labels.Count == 0) { buffer = insts; tide = buffer.Length; return; } buffer = new CILInstruction[insts.Length + labels.Count]; int currentPos = 0; tide = 0; foreach (CILLabel lbl in labels) { CILLabel lab = lbl; while ((currentPos < insts.Length) && (insts[currentPos].offset < lab.offset)) buffer[tide++] = insts[currentPos++]; buffer[tide++] = lab; } while (currentPos < insts.Length) { buffer[tide++] = insts[currentPos++]; } }
private static bool IsTerminatingInstruction(CILInstruction cilInstr) { // Return or throw instructions are terminating instructions if (cilInstr is Instr) { if (((Instr)cilInstr).GetOp() == Op.ret) return true; if (((Instr)cilInstr).GetOp() == Op.throwOp) return true; if (((Instr)cilInstr).GetOp() == Op.rethrow) return true; } // jmp is a terminating instruction if (cilInstr is MethInstr) { if (((MethInstr)cilInstr).GetMethodOp() == MethodOp.jmp) return true; } return false; }
/// <summary> /// Set the instruction to be the new array of instructions, this will replace /// any existing instructions. This method cannot be called when in "insert" mode. /// </summary> /// <param name="insts">The new instructions</param> public void SetInstructions(CILInstruction[] insts) { if (inserting) throw new Exception("Cannot replace instructions during insert."); buffer = insts; tide = buffer.Length; for (int i = 0; i < tide; i++) { if (insts[i] == null) tide = i; insts[i].index = (uint)i; } }