public Instruction this[int index] { get { return(instructions[index]); } set { backtracer = null; labelCache = null; instructions[index] = value; } }
public void RemoveAt(int position, bool nonDestructive = false) { if (!nonDestructive) { backtracer = null; } else if (backtracer != null) { backtracer.NotifyRemoval(position); } labelCache = null; instructions.RemoveAt(position); }
public void Insert(int position, Instruction instruction, bool nonDestructive = false) { if (!nonDestructive) { backtracer = null; } else if (backtracer != null) { backtracer.NotifyInsert(position); } labelCache = null; instructions.Insert(position, instruction); }
public void Add(Instruction instruction) { backtracer = null; labelCache = null; instructions.Add(instruction); }
public void ClearCache() { labelCache = null; backtracer = null; }
public void InsertRange(int position, IEnumerable <Instruction> newInstructions) { backtracer = null; labelCache = null; instructions.InsertRange(position, newInstructions); }
public void RemoveRange(int start, int count) { backtracer = null; labelCache = null; instructions.RemoveRange(start, count); }
protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i) { var changed = false; var j = i; var patchedLabels = new Dictionary <ushort, ushort>(); context.RemoveAt(j); while (!IsChainBreaker(context[j], matchedInstruction, null)) { var instruction = context[j]; switch (instruction.Type) { case InstructionType.StorePosition: j++; break; case InstructionType.BoundsCheck: case InstructionType.Char: var targetLabel = instruction.Label; if (patchedLabels.TryGetValue(targetLabel, out var newTarget)) { targetLabel = newTarget; } else { var oldLabel = targetLabel; targetLabel = AddStub(context, targetLabel, matchedInstruction, ref j); patchedLabels[oldLabel] = targetLabel; } changed = true; context[j] = new Instruction(instruction.Type, targetLabel, instruction.Offset, instruction.Data1, instruction.Data2); j++; break; } } context.Insert(j, matchedInstruction); return(changed); }
protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i) { var changed = false; var j = i; var patchedLabels = new Dictionary <(ushort label, short offset), ushort>(); var offset = matchedInstruction.Offset; var removedAt = 0; context.RemoveAt(j); while (!IsChainBreaker(context[j], Instruction.Advance(offset), null)) { var instruction = context[j]; switch (instruction.Type) { case InstructionType.Advance: offset += instruction.Offset; removedAt = j; context.RemoveAt(j); break; case InstructionType.BoundsCheck: case InstructionType.Char: var targetLabel = instruction.Label; if (context[context.GetLabelPosition(targetLabel) + 1].Type != InstructionType.RestorePosition) { if (patchedLabels.TryGetValue((targetLabel, offset), out var newTarget)) { targetLabel = newTarget; } else if (offset != 0) { var oldLabel = targetLabel; targetLabel = AddStub(context, targetLabel, Instruction.Advance(offset), ref j); patchedLabels[(oldLabel, offset)] = targetLabel;
protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i) { var changed = false; var j = i; context.RemoveAt(j); while (!IsChainBreaker(context[j], matchedInstruction, null)) { var instruction = context[j]; if (instruction.Matches(InstructionType.BoundsCheck, matchedInstruction.Label)) { changed = true; matchedInstruction = Instruction.BoundsCheck(instruction.Label, Math.Max(instruction.Offset, context[j].Offset)); context.RemoveAt(j); } else { j++; } } context.Insert(i, matchedInstruction); return(changed); }
protected abstract bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i);
protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i) { var changed = false; var j = i; var patchedLabels = new Dictionary <(ushort label, short offset), ushort>(); context.RemoveAt(j); while (!IsChainBreaker(context[j], matchedInstruction, new BacktracerView(backtracer, j - 1, false))) { var instruction = context[j]; switch (instruction.Type) { case InstructionType.BoundsCheck: case InstructionType.Char: var targetLabel = instruction.Label; if (patchedLabels.TryGetValue((targetLabel, matchedInstruction.Offset), out var newTarget)) { targetLabel = newTarget; } else { var oldLabel = targetLabel; targetLabel = AddStub(context, targetLabel, matchedInstruction, ref j); patchedLabels[(oldLabel, matchedInstruction.Offset)] = targetLabel;