本文整理汇总了C#中Context.InsertBefore方法的典型用法代码示例。如果您正苦于以下问题:C# Context.InsertBefore方法的具体用法?C# Context.InsertBefore怎么用?C# Context.InsertBefore使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Context
的用法示例。
在下文中一共展示了Context.InsertBefore方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: GetRuntimeTypeHandle
private Operand GetRuntimeTypeHandle(Context context, BaseMethodCompiler methodCompiler)
{
var typeDef = Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, StringClassTypeDefinitionSymbolName);
var runtimeTypeHandle = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.GetTypeByName("System", "RuntimeTypeHandle"));
var before = context.InsertBefore();
before.SetInstruction(IRInstruction.Move, runtimeTypeHandle, typeDef);
return runtimeTypeHandle;
}
示例2: InsertLoadBeforeInstruction
private Operand InsertLoadBeforeInstruction(Context context, string symbolName, MosaType type)
{
var before = context.InsertBefore();
Operand result = MethodCompiler.CreateVirtualRegister(type);
Operand op = Operand.CreateManagedSymbol(type, symbolName);
before.SetInstruction(CILInstruction.Get(OpCode.Ldc_i4), result, op);
return result;
}
示例3: InsertLoadBeforeInstruction
private Operand InsertLoadBeforeInstruction(Context context, string symbolName, SigType type)
{
Context before = context.InsertBefore();
Operand result = methodCompiler.CreateVirtualRegister(type);
Operand op = new SymbolOperand(type, symbolName);
before.SetInstruction(CILInstruction.Get(OpCode.Ldc_i4), result, op);
return result;
}
示例4: InsertCopyStatement
/// <summary>
/// Inserts the copy statement.
/// </summary>
/// <param name="predecessor">The predecessor.</param>
/// <param name="result">The result.</param>
/// <param name="operand">The operand.</param>
private void InsertCopyStatement(BasicBlock predecessor, Operand result, Operand operand)
{
var context = new Context(instructionSet, predecessor);
while (!context.EndOfInstruction && IsBranchInstruction(context))
context.GotoNext();
if (context.Index != -1)
context = context.InsertBefore();
var source = operand.IsSSA ? operand.SsaOperand : operand;
var destination = result.IsSSA ? result.SsaOperand : result;
Debug.Assert(!source.IsSSA);
Debug.Assert(!destination.IsSSA);
if (destination != source)
context.SetInstruction(IR.IRInstruction.Move, destination, source);
}
示例5: Callvirt
/// <summary>
/// Visitation function for Callvirt instruction.
/// </summary>
/// <param name="context">The context.</param>
private void Callvirt(Context context)
{
if (ProcessExternalCall(context))
return;
MosaMethod method = context.InvokeMethod;
Operand resultOperand = context.Result;
var operands = new List<Operand>(context.Operands);
if (context.Previous.Instruction is ConstrainedPrefixInstruction)
{
var type = context.Previous.MosaType;
context.Previous.Empty();
if (type.IsValueType)
{
method = GetMethodOrOverride(type, method);
if (type.Methods.Contains(method))
{
// If the method being called is a virtual method then we need to box the value type
if (method.IsVirtual &&
context.Operand1.Type.ElementType != null &&
context.Operand1.Type.ElementType.IsValueType &&
method.DeclaringType == context.Operand1.Type.ElementType)
{
var before = context.InsertBefore();
before.SetInstruction(IRInstruction.SubSigned, context.Operand1, context.Operand1, Operand.CreateConstant(TypeSystem, NativePointerSize * 2));
}
}
else
{
// Get the value type, size and native alignment
MosaType elementType = context.Operand1.Type.ElementType;
int typeSize = TypeLayout.GetTypeSize(elementType);
int alignment = TypeLayout.NativePointerAlignment;
typeSize += (alignment - (typeSize % alignment)) % alignment;
// Create a virtual register to hold our boxed value
var boxedValue = AllocateVirtualRegister(TypeSystem.BuiltIn.Object);
// Create a new context before the call and set it as a VmCall
var before = context.InsertBefore();
before.SetInstruction(IRInstruction.Nop);
ReplaceWithVmCall(before, VmCall.Box);
// Populate the operands for the VmCall and result
before.SetOperand(1, GetRuntimeTypeHandle(elementType, before));
before.SetOperand(2, context.Operand1);
before.SetOperand(3, Operand.CreateConstant(TypeSystem, typeSize));
before.OperandCount = 4;
before.Result = boxedValue;
before.ResultCount = 1;
// Now replace the value type pointer with the boxed value virtual register
context.Operand1 = boxedValue;
}
ProcessInvokeInstruction(context, method, resultOperand, operands);
return;
}
}
if (method.IsVirtual)
{
Operand thisPtr = context.Operand1;
Operand typeDefinition = AllocateVirtualRegister(TypeSystem.BuiltIn.Pointer);
Operand methodDefinition = AllocateVirtualRegister(TypeSystem.BuiltIn.Pointer);
Operand methodPtr = AllocateVirtualRegister(TypeSystem.BuiltIn.Pointer);
if (!method.DeclaringType.IsInterface)
{
// methodDefinitionOffset is as follows (slot * NativePointerSize) + (NativePointerSize * 14)
// We use 14 as that is the number of NativePointerSized fields until the start of methodDefinition pointers
int methodDefinitionOffset = CalculateMethodTableOffset(method) + (NativePointerSize * 14);
// Same as above except for methodPointer
int methodPointerOffset = (NativePointerSize * 4);
// Get the TypeDef pointer
context.SetInstruction(IRInstruction.LoadInteger, NativeInstructionSize, typeDefinition, thisPtr, ConstantZero);
// Get the MethodDef pointer
context.AppendInstruction(IRInstruction.LoadInteger, NativeInstructionSize, methodDefinition, typeDefinition, Operand.CreateConstant(TypeSystem, methodDefinitionOffset));
// Get the address of the method
context.AppendInstruction(IRInstruction.LoadInteger, NativeInstructionSize, methodPtr, methodDefinition, Operand.CreateConstant(TypeSystem, methodPointerOffset));
}
else
{
// Offset for InterfaceSlotTable in TypeDef
int interfaceSlotTableOffset = (NativePointerSize * 11);
// Offset for InterfaceMethodTable in InterfaceSlotTable
int interfaceMethodTableOffset = (NativePointerSize * 1) + CalculateInterfaceSlotOffset(method);
//.........这里部分代码省略.........
示例6: CalculateArrayElementOffset
/// <summary>
/// Calculates the element offset for the specified index.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="arrayType">The array type.</param>
/// <param name="index">The index operand.</param>
/// <returns>Element offset operand.</returns>
private Operand CalculateArrayElementOffset(Context context, MosaType arrayType, Operand index)
{
int size = 0, alignment = 0;
Architecture.GetTypeRequirements(TypeLayout, arrayType.ElementType, out size, out alignment);
var elementOffset = AllocateVirtualRegister(TypeSystem.BuiltIn.I4);
var elementSize = Operand.CreateConstant(TypeSystem, size);
var before = context.InsertBefore();
before.AppendInstruction(IRInstruction.MulSigned, elementOffset, index, elementSize);
return elementOffset;
}
示例7: Call
/// <summary>
/// Visitation function for Call instruction.
/// </summary>
/// <param name="context">The context.</param>
private void Call(Context context)
{
if (CanSkipDueToRecursiveSystemObjectCtorCall(context))
{
context.Empty();
return;
}
if (ProcessExternalCall(context))
return;
// If the method being called is a virtual method then we need to box the value type
if (context.InvokeMethod.IsVirtual &&
context.Operand1.Type.ElementType != null &&
context.Operand1.Type.ElementType.IsValueType &&
context.InvokeMethod.DeclaringType == context.Operand1.Type.ElementType)
{
if (OverridesMethod(context.InvokeMethod))
{
var before = context.InsertBefore();
before.SetInstruction(IRInstruction.SubSigned, context.Operand1, context.Operand1, Operand.CreateConstant(TypeSystem, NativePointerSize * 2));
}
else
{
// Get the value type, size and native alignment
MosaType type = context.Operand1.Type.ElementType;
int typeSize = TypeLayout.GetTypeSize(type);
int alignment = TypeLayout.NativePointerAlignment;
typeSize += (alignment - (typeSize % alignment)) % alignment;
// Create a virtual register to hold our boxed value
var boxedValue = AllocateVirtualRegister(TypeSystem.BuiltIn.Object);
// Create a new context before the call and set it as a VmCall
var before = context.InsertBefore();
before.SetInstruction(IRInstruction.Nop);
ReplaceWithVmCall(before, VmCall.Box);
// Populate the operands for the VmCall and result
before.SetOperand(1, GetRuntimeTypeHandle(type, before));
before.SetOperand(2, context.Operand1);
before.SetOperand(3, Operand.CreateConstant(TypeSystem, typeSize));
before.OperandCount = 4;
before.Result = boxedValue;
before.ResultCount = 1;
// Now replace the value type pointer with the boxed value virtual register
context.Operand1 = boxedValue;
}
}
ProcessInvokeInstruction(context, context.InvokeMethod, context.Result, new List<Operand>(context.Operands));
}
示例8: AddArrayBoundsCheck
/// <summary>
/// Adds bounds check to the array access.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="arrayOperand">The array operand.</param>
/// <param name="arrayIndexOperand">The index operand.</param>
private void AddArrayBoundsCheck(Context context, Operand arrayOperand, Operand arrayIndexOperand)
{
var before = context.InsertBefore();
// First create new block and split current block
var exceptionContext = CreateNewBlockContexts(1)[0];
var nextContext = Split(before);
// Get array length
var lengthOperand = AllocateVirtualRegister(TypeSystem.BuiltIn.U4);
var fixedOffset = Operand.CreateConstant(TypeSystem, NativePointerSize * 2);
before.SetInstruction(IRInstruction.LoadInteger, lengthOperand, arrayOperand, fixedOffset);
// Now compare length with index
// If index is greater than or equal to the length then jump to exception block, otherwise jump to next block
before.AppendInstruction(IRInstruction.CompareIntegerBranch, ConditionCode.UnsignedGreaterOrEqual, null, arrayIndexOperand, lengthOperand, exceptionContext.Block);
before.AppendInstruction(IRInstruction.Jmp, nextContext.Block);
// Build exception block which is just a call to throw exception
var method = InternalRuntimeType.FindMethodByName("ThrowIndexOutOfRangeException");
var symbolOperand = Operand.CreateSymbolFromMethod(TypeSystem, method);
exceptionContext.AppendInstruction(IRInstruction.Call, null, symbolOperand);
exceptionContext.InvokeMethod = method;
}
示例9: Box
/// <summary>
/// Visitation function for Box instruction.
/// </summary>
/// <param name="context">The context.</param>
private void Box(Context context)
{
var value = context.Operand1;
var result = context.Result;
var type = context.MosaType;
if (!type.IsValueType)
{
Debug.Assert(result.IsVirtualRegister);
Debug.Assert(value.IsVirtualRegister);
var moveInstruction = GetMoveInstruction(type);
context.ReplaceInstructionOnly(moveInstruction);
return;
}
int typeSize = TypeLayout.GetTypeSize(type);
int alignment = TypeLayout.NativePointerAlignment;
typeSize += (alignment - (typeSize % alignment)) % alignment;
VmCall vmCall = VmCall.Box32;
if (type.IsR4)
vmCall = VmCall.BoxR4;
else if (type.IsR8)
vmCall = VmCall.BoxR8;
else if (typeSize <= 4)
vmCall = VmCall.Box32;
else if (typeSize == 8)
vmCall = VmCall.Box64;
else
vmCall = VmCall.Box;
context.SetInstruction(IRInstruction.Nop);
ReplaceWithVmCall(context, vmCall);
context.SetOperand(1, GetRuntimeTypeHandle(type, context));
if (vmCall == VmCall.Box)
{
Operand adr = AllocateVirtualRegister(type.ToManagedPointer());
context.InsertBefore().SetInstruction(IRInstruction.AddressOf, adr, value);
context.SetOperand(2, adr);
context.SetOperand(3, Operand.CreateConstant(TypeSystem, typeSize));
context.OperandCount = 4;
}
else
{
context.SetOperand(2, value);
context.OperandCount = 3;
}
context.Result = result;
context.ResultCount = 1;
}
示例10: Ldelema
/// <summary>
/// Visitation function for Ldelema instruction.
/// </summary>
/// <param name="context">The context.</param>
private void Ldelema(Context context)
{
var result = context.Result;
var arrayOperand = context.Operand1;
var arrayIndexOperand = context.Operand2;
var arrayType = arrayOperand.Type;
Debug.Assert(arrayType.ElementType == result.Type.ElementType);
// Array bounds check
AddArrayBoundsCheck(context.InsertBefore(), arrayOperand, arrayIndexOperand);
//
// The sequence we're emitting is:
//
// arrayAddress = arrayOperand + 12
// offset = arrayIndexOperand * elementSize
// result = arrayAddress + offset
//
// The array data starts at offset 12 from the array object itself. The 12 is a assumption of x86,
// which might change for other platforms. This is automatically calculated using the plaform native pointer size.
//
var arrayAddress = LoadArrayBaseAddress(context, arrayType, arrayOperand);
var elementOffset = CalculateArrayElementOffset(context, arrayType, arrayIndexOperand);
context.SetInstruction(IRInstruction.AddSigned, result, arrayAddress, elementOffset);
}
示例11: Ldelem
/// <summary>
/// Visitation function for Ldelem instruction.
/// </summary>
/// <param name="context">The context.</param>
private void Ldelem(Context context)
{
var result = context.Result;
var arrayOperand = context.Operand1;
var arrayIndexOperand = context.Operand2;
var arraySigType = arrayOperand.Type;
// Array bounds check
AddArrayBoundsCheck(context.InsertBefore(), arrayOperand, arrayIndexOperand);
BaseIRInstruction loadInstruction = IRInstruction.Load;
if (MustSignExtendOnLoad(arraySigType.ElementType))
{
loadInstruction = IRInstruction.LoadSignExtended;
}
else if (MustZeroExtendOnLoad(arraySigType.ElementType))
{
loadInstruction = IRInstruction.LoadZeroExtended;
}
//
// The sequence we're emitting is:
//
// arrayAddress = arrayOperand + 12
// offset = arrayIndexOperand * elementSize
// result = *(arrayAddress + offset)
//
// The array data starts at offset 12 from the array object itself. The 12 is a assumption of x86,
// which might change for other platforms. This is automatically calculated using the plaform native pointer size.
//
var arrayAddress = LoadArrayBaseAddress(context, arraySigType, arrayOperand);
var elementOffset = CalculateArrayElementOffset(context, arraySigType, arrayIndexOperand);
Debug.Assert(elementOffset != null);
var size = GetInstructionSize(arraySigType.ElementType);
context.SetInstruction(loadInstruction, size, result, arrayAddress, elementOffset);
context.MosaType = arraySigType.ElementType;
}
示例12: SplitIntoBlocks
/// <summary>
/// Finds all targets.
/// </summary>
/// <param name="index">The index.</param>
private void SplitIntoBlocks(int index)
{
Dictionary<int, int> targets = new Dictionary<int, int>();
targets.Add(index, -1);
// Find out all targets labels
for (Context ctx = new Context(InstructionSet, index); ctx.Index >= 0; ctx.GotoNext())
{
switch (ctx.Instruction.FlowControl)
{
case FlowControl.Next: continue;
case FlowControl.Call: continue;
case FlowControl.Break: goto case FlowControl.UnconditionalBranch;
case FlowControl.Return: continue;
case FlowControl.Throw: continue;
case FlowControl.UnconditionalBranch:
// Unconditional branch
Debug.Assert(ctx.BranchTargets.Length == 1);
if (!targets.ContainsKey(ctx.BranchTargets[0]))
targets.Add(ctx.BranchTargets[0], -1);
continue;
case FlowControl.Switch: goto case FlowControl.ConditionalBranch;
case FlowControl.ConditionalBranch:
// Conditional branch with multiple targets
foreach (int target in ctx.BranchTargets)
if (!targets.ContainsKey(target))
targets.Add(target, -1);
int next = ctx.Next.Label;
if (!targets.ContainsKey(next))
targets.Add(next, -1);
continue;
case FlowControl.EndFinally: continue;
case FlowControl.Leave:
Debug.Assert(ctx.BranchTargets.Length == 1);
if (!targets.ContainsKey(ctx.BranchTargets[0]))
targets.Add(ctx.BranchTargets[0], -1);
continue;
default:
Debug.Assert(false);
break;
}
}
// Add Exception Class targets
foreach (var clause in MethodCompiler.Method.ExceptionBlocks)
{
if (!targets.ContainsKey(clause.HandlerOffset))
targets.Add(clause.HandlerOffset, -1);
if (!targets.ContainsKey(clause.TryOffset))
targets.Add(clause.TryOffset, -1);
if (clause.FilterOffset != null && !targets.ContainsKey(clause.FilterOffset.Value))
targets.Add(clause.FilterOffset.Value, -1);
}
BasicBlock currentBlock = null;
Context previous = null;
for (Context ctx = new Context(InstructionSet, index); ctx.Index >= 0; ctx.GotoNext())
{
if (targets.ContainsKey(ctx.Label))
{
if (currentBlock != null)
{
previous = ctx.Previous;
var flow = previous.Instruction.FlowControl;
if (flow == FlowControl.Next || flow == FlowControl.Call || flow == FlowControl.ConditionalBranch || flow == FlowControl.Switch)
{
// This jump joins fall-through blocks, by giving them a proper end.
previous.AppendInstruction(IRInstruction.Jmp);
previous.SetBranch(ctx.Label);
}
// Close current block
previous.AppendInstruction(IRInstruction.BlockEnd);
currentBlock.EndIndex = previous.Index;
}
Context prev = ctx.InsertBefore();
prev.SetInstruction(IRInstruction.BlockStart);
currentBlock = BasicBlocks.CreateBlock(ctx.Label, prev.Index);
targets.Remove(ctx.Label);
}
previous = ctx.Clone();
}
// Close current block
previous.AppendInstruction(IRInstruction.BlockEnd);
//.........这里部分代码省略.........
示例13: ToVmBoxCall
/// <summary>
/// Visitation function for Box instruction.
/// </summary>
/// <param name="context">The context.</param>
void CIL.ICILVisitor.Box(Context context)
{
var value = context.Operand1;
var result = context.Result;
var type = context.MosaType;
if (!type.IsValueType)
{
context.ReplaceInstructionOnly(IRInstruction.Move);
return;
}
int typeSize = TypeLayout.GetTypeSize(type);
int alignment = TypeLayout.NativePointerAlignment;
typeSize += (alignment - (typeSize % alignment)) % alignment;
var vmCall = ToVmBoxCall(typeSize);
context.SetInstruction(IRInstruction.Nop);
ReplaceWithVmCall(context, vmCall);
var methodTableSymbol = GetMethodTableSymbol(type);
context.SetOperand(1, methodTableSymbol);
if (vmCall == VmCall.Box)
{
Operand adr = MethodCompiler.CreateVirtualRegister(type.ToManagedPointer());
context.InsertBefore().SetInstruction(IRInstruction.AddressOf, adr, value);
context.SetOperand(2, adr);
context.SetOperand(3, Operand.CreateConstantUnsignedInt(TypeSystem, (uint)typeSize));
context.OperandCount = 4;
}
else
{
context.SetOperand(2, value);
context.OperandCount = 3;
}
context.Result = result;
return;
}
示例14: CreateBasicBlocksFromTargets
/// <summary>
/// Creates the basic blocks from targets.
/// </summary>
/// <param name="targets">The targets.</param>
private void CreateBasicBlocksFromTargets(SortedSet<int> targets)
{
BasicBlock currentBlock = null;
Context previous = null;
for (var ctx = new Context(InstructionSet, 0); ctx.Index >= 0; previous = ctx.Clone(), ctx.GotoNext())
{
if (!targets.Contains(ctx.Label))
continue;
if (currentBlock != null)
{
previous = ctx.Previous;
var flow = previous.Instruction.FlowControl;
if (flow == FlowControl.Next || flow == FlowControl.Call || flow == FlowControl.ConditionalBranch || flow == FlowControl.Switch)
{
// This jump joins fall-through blocks by giving them a proper end.
previous.AppendInstruction(IRInstruction.Jmp);
previous.SetBranch(ctx.Label);
}
// Close current block
previous.AppendInstruction(IRInstruction.BlockEnd);
currentBlock.EndIndex = previous.Index;
}
Context prev = ctx.InsertBefore();
prev.SetInstruction(IRInstruction.BlockStart);
currentBlock = BasicBlocks.CreateBlock(ctx.Label, prev.Index);
}
// Close current block
previous.AppendInstruction(IRInstruction.BlockEnd);
currentBlock.EndIndex = previous.Index;
}
示例15: Ldfld
/// <summary>
/// Visitation function for Ldfld instruction.
/// </summary>
/// <param name="context">The context.</param>
private void Ldfld(Context context)
{
Operand resultOperand = context.Result;
Operand objectOperand = context.Operand1;
MosaField field = context.MosaField;
if (!objectOperand.IsPointer && objectOperand.Type.IsUserValueType)
{
var userStruct = objectOperand;
if (!userStruct.IsStackLocal)
{
var originalOperand = userStruct;
userStruct = MethodCompiler.StackLayout.AddStackLocal(userStruct.Type);
context.InsertBefore().SetInstruction(IRInstruction.Move, userStruct, originalOperand);
}
objectOperand = MethodCompiler.CreateVirtualRegister(userStruct.Type.ToManagedPointer());
context.InsertBefore().SetInstruction(IRInstruction.AddressOf, objectOperand, userStruct);
}
int offset = TypeLayout.GetFieldOffset(field);
Operand offsetOperand = Operand.CreateConstant(TypeSystem, offset);
BaseIRInstruction loadInstruction = IRInstruction.Load;
if (MustSignExtendOnLoad(field.FieldType))
{
loadInstruction = IRInstruction.LoadSignExtended;
}
else if (MustZeroExtendOnLoad(field.FieldType))
{
loadInstruction = IRInstruction.LoadZeroExtended;
}
Debug.Assert(offsetOperand != null);
var size = GetInstructionSize(field.FieldType);
context.SetInstruction(loadInstruction, size, resultOperand, objectOperand, offsetOperand);
context.MosaType = field.FieldType;
}