本文整理汇总了C#中ILVariable类的典型用法代码示例。如果您正苦于以下问题:C# ILVariable类的具体用法?C# ILVariable怎么用?C# ILVariable使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
ILVariable类属于命名空间,在下文中一共展示了ILVariable类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: AssignNameToVariable
void AssignNameToVariable(ILVariable varDef, IEnumerable<ILExpression> allExpressions)
{
string proposedName = null;
foreach (ILExpression expr in allExpressions) {
if (expr.Operand != varDef)
continue;
if (expr.Code == ILCode.Stloc) {
proposedName = GetNameFromExpression(expr.Arguments.Single());
}
if (proposedName != null)
break;
}
if (proposedName == null)
proposedName = GetNameByType(varDef.Type);
if (!typeNames.ContainsKey(proposedName)) {
typeNames.Add(proposedName, 0);
}
int count = ++typeNames[proposedName];
if (count > 1) {
varDef.Name = proposedName + count.ToString();
} else {
varDef.Name = proposedName;
}
}
开发者ID:hlesesne,项目名称:ILSpy,代码行数:25,代码来源:NameVariables.cs
示例2: GetMethodInfo
public void GetMethodInfo(MethodKey key, out Parameter[] parameters, out Local[] locals, out ILVariable[] decLocals) {
parameters = null;
locals = null;
decLocals = null;
foreach (var textView in MainWindow.Instance.AllTextViews) {
if (parameters != null && decLocals != null)
break;
var cm = textView.CodeMappings;
if (cm == null)
continue;
MemberMapping mapping;
if (!cm.TryGetValue(key, out mapping))
continue;
var method = mapping.MethodDefinition;
if (mapping.LocalVariables != null && method.Body != null) {
locals = method.Body.Variables.ToArray();
decLocals = new ILVariable[method.Body.Variables.Count];
foreach (var v in mapping.LocalVariables) {
if (v.IsGenerated)
continue;
if (v.OriginalVariable == null)
continue;
if ((uint)v.OriginalVariable.Index >= decLocals.Length)
continue;
decLocals[v.OriginalVariable.Index] = v;
}
}
parameters = method.Parameters.ToArray();
}
}
开发者ID:nakijun,项目名称:dnSpy,代码行数:33,代码来源:LocalsControl.xaml.cs
示例3: Get
public bool Get (ILVariable localVariable, out DynamicCallSiteInfo info) {
FieldReference storageField;
if (Aliases.TryGetValue(localVariable.Name, out storageField))
return Get(storageField, out info);
info = null;
return false;
}
开发者ID:RainsSoft,项目名称:JSIL,代码行数:9,代码来源:DynamicCallSites.cs
示例4: HasSingleLoad
bool HasSingleLoad(ILVariable v)
{
int loads = 0;
foreach (ILExpression expr in method.GetSelfAndChildrenRecursive<ILExpression>()) {
if (expr.Operand == v) {
if (expr.Code == ILCode.Ldloc)
loads++;
else if (expr.Code != ILCode.Stloc)
return false;
}
}
return loads == 1;
}
开发者ID:stgwilli,项目名称:ILSpy,代码行数:13,代码来源:TypeAnalysis.cs
示例5: FindLoadInNext
/// <summary>
/// Finds the position to inline to.
/// </summary>
/// <returns>true = found; false = cannot continue search; null = not found</returns>
static bool? FindLoadInNext(ILExpression expr, ILVariable v, out ILExpression parent, out int pos)
{
parent = null;
pos = 0;
if (expr == null)
return false;
for (int i = 0; i < expr.Arguments.Count; i++) {
ILExpression arg = expr.Arguments[i];
if (arg.Code == ILCode.Ldloc && arg.Operand == v) {
parent = expr;
pos = i;
return true;
}
bool? r = FindLoadInNext(arg, v, out parent, out pos);
if (r != null)
return r;
}
return IsWithoutSideEffects(expr.Code) ? (bool?)null : false;
}
开发者ID:hlesesne,项目名称:ILSpy,代码行数:23,代码来源:ILInlining.cs
示例6: AdjustInitializerStack
static bool AdjustInitializerStack(List<ILExpression> initializerStack, ILExpression argument, ILVariable v, bool isCollection)
{
// Argument is of the form 'getter(getter(...(v)))'
// Unpack it into a list of getters:
List<ILExpression> getters = new List<ILExpression>();
while (argument.Code == ILCode.CallvirtGetter || argument.Code == ILCode.Ldfld) {
getters.Add(argument);
if (argument.Arguments.Count != 1)
return false;
argument = argument.Arguments[0];
}
// Ensure that the final argument is 'v'
if (!argument.MatchLdloc(v))
return false;
// Now compare the getters with those that are currently active on the initializer stack:
int i;
for (i = 1; i <= Math.Min(getters.Count, initializerStack.Count - 1); i++) {
ILExpression g1 = initializerStack[i].Arguments[0]; // getter stored in initializer
ILExpression g2 = getters[getters.Count - i]; // matching getter from argument
if (g1.Operand != g2.Operand) {
// operands differ, so we abort the comparison
break;
}
}
// Remove all initializers from the stack that were not matched with one from the argument:
initializerStack.RemoveRange(i, initializerStack.Count - i);
// Now create new initializers for the remaining arguments:
for (; i <= getters.Count; i++) {
ILExpression g = getters[getters.Count - i];
MemberReference mr = (MemberReference)g.Operand;
TypeReference returnType;
if (mr is FieldReference)
returnType = TypeAnalysis.GetFieldType((FieldReference)mr);
else
returnType = TypeAnalysis.SubstituteTypeArgs(((MethodReference)mr).ReturnType, mr);
ILExpression nestedInitializer = new ILExpression(
IsCollectionType(returnType) ? ILCode.InitCollection : ILCode.InitObject,
null, g);
// add new initializer to its parent:
ILExpression parentInitializer = initializerStack[initializerStack.Count - 1];
if (parentInitializer.Code == ILCode.InitCollection) {
// can't add children to collection initializer
if (parentInitializer.Arguments.Count == 1) {
// convert empty collection initializer to object initializer
parentInitializer.Code = ILCode.InitObject;
} else {
return false;
}
}
parentInitializer.Arguments.Add(nestedInitializer);
initializerStack.Add(nestedInitializer);
}
ILExpression lastInitializer = initializerStack[initializerStack.Count - 1];
if (isCollection) {
return lastInitializer.Code == ILCode.InitCollection;
} else {
if (lastInitializer.Code == ILCode.InitCollection) {
if (lastInitializer.Arguments.Count == 1) {
// convert empty collection initializer to object initializer
lastInitializer.Code = ILCode.InitObject;
return true;
} else {
return false;
}
} else {
return true;
}
}
}
开发者ID:constructor-igor,项目名称:cudafy,代码行数:70,代码来源:InitializerPeepholeTransforms.cs
示例7: DeclareVariable
protected JSVariable DeclareVariable(ILVariable variable, MethodReference function)
{
return DeclareVariable(JSVariable.New(variable, function));
}
开发者ID:aprishchepov,项目名称:JSIL,代码行数:4,代码来源:ILBlockTranslator.cs
示例8: ParseObjectInitializer
/// <summary>
/// Parses an object initializer.
/// </summary>
/// <param name="body">ILAst block</param>
/// <param name="pos">
/// Input: position of the instruction assigning to 'v'.
/// Output: first position after the object initializer
/// </param>
/// <param name="v">The variable that holds the object being initialized</param>
/// <param name="newObjExpr">The newobj instruction</param>
/// <returns>InitObject instruction</returns>
ILExpression ParseObjectInitializer(List<ILNode> body, ref int pos, ILVariable v, ILExpression newObjExpr, bool isCollection)
{
Debug.Assert(((ILExpression)body[pos]).Code == ILCode.Stloc);
// Take care not to modify any existing ILExpressions in here.
// We just construct new ones around the old ones, any modifications must wait until the whole
// object/collection initializer was analyzed.
ILExpression objectInitializer = new ILExpression(isCollection ? ILCode.InitCollection : ILCode.InitObject, null, newObjExpr);
List<ILExpression> initializerStack = new List<ILExpression>();
initializerStack.Add(objectInitializer);
while (++pos < body.Count) {
ILExpression nextExpr = body[pos] as ILExpression;
if (IsSetterInObjectInitializer(nextExpr)) {
if (!AdjustInitializerStack(initializerStack, nextExpr.Arguments[0], v, false)) {
CleanupInitializerStackAfterFailedAdjustment(initializerStack);
break;
}
initializerStack[initializerStack.Count - 1].Arguments.Add(nextExpr);
} else if (IsAddMethodCall(nextExpr)) {
if (!AdjustInitializerStack(initializerStack, nextExpr.Arguments[0], v, true)) {
CleanupInitializerStackAfterFailedAdjustment(initializerStack);
break;
}
initializerStack[initializerStack.Count - 1].Arguments.Add(nextExpr);
} else {
// can't match any more initializers: end of object initializer
break;
}
}
return objectInitializer;
}
开发者ID:constructor-igor,项目名称:cudafy,代码行数:41,代码来源:InitializerPeepholeTransforms.cs
示例9: InlineIfPossible
/// <summary>
/// Inlines 'expr' into 'next', if possible.
/// </summary>
bool InlineIfPossible(ILVariable v, ILExpression inlinedExpression, ILNode next, bool aggressive)
{
// ensure the variable is accessed only a single time
if (numStloc.GetOrDefault(v) != 1)
return false;
int ldloc = numLdloc.GetOrDefault(v);
if (ldloc > 1 || ldloc + numLdloca.GetOrDefault(v) != 1)
return false;
if (next is ILCondition)
next = ((ILCondition)next).Condition;
else if (next is ILWhileLoop)
next = ((ILWhileLoop)next).Condition;
ILExpression parent;
int pos;
if (FindLoadInNext(next as ILExpression, v, inlinedExpression, out parent, out pos) == true) {
if (ldloc == 0) {
if (!IsGeneratedValueTypeTemporary((ILExpression)next, parent, pos, v, inlinedExpression))
return false;
} else {
if (!aggressive && !v.GeneratedByDecompiler && !NonAggressiveInlineInto((ILExpression)next, parent, inlinedExpression))
return false;
}
// Assign the ranges of the ldloc instruction:
if (context.CalculateILRanges)
parent.Arguments[pos].AddSelfAndChildrenRecursiveILRanges(inlinedExpression.ILRanges);
if (ldloc == 0) {
// it was an ldloca instruction, so we need to use the pseudo-opcode 'addressof' so that the types
// comes out correctly
parent.Arguments[pos] = new ILExpression(ILCode.AddressOf, null, inlinedExpression);
} else {
parent.Arguments[pos] = inlinedExpression;
}
return true;
}
return false;
}
开发者ID:GreenDamTan,项目名称:dnSpy,代码行数:43,代码来源:ILInlining.cs
示例10: AssignStateRanges
int AssignStateRanges(List<ILNode> body, int bodyLength, bool forDispose)
{
if (bodyLength == 0)
return 0;
for (int i = 0; i < bodyLength; i++) {
StateRange nodeRange = ranges[body[i]];
nodeRange.Simplify();
ILLabel label = body[i] as ILLabel;
if (label != null) {
ranges[body[i + 1]].UnionWith(nodeRange);
continue;
}
ILTryCatchBlock tryFinally = body[i] as ILTryCatchBlock;
if (tryFinally != null) {
if (!forDispose || tryFinally.CatchBlocks.Count != 0 || tryFinally.FaultBlock != null || tryFinally.FinallyBlock == null)
throw new YieldAnalysisFailedException();
ranges[tryFinally.TryBlock].UnionWith(nodeRange);
AssignStateRanges(tryFinally.TryBlock.Body, tryFinally.TryBlock.Body.Count, forDispose);
continue;
}
ILExpression expr = body[i] as ILExpression;
if (expr == null)
throw new YieldAnalysisFailedException();
switch (expr.Code) {
case ILCode.Switch:
{
SymbolicValue val = Eval(expr.Arguments[0]);
if (val.Type != SymbolicValueType.State)
throw new YieldAnalysisFailedException();
ILLabel[] targetLabels = (ILLabel[])expr.Operand;
for (int j = 0; j < targetLabels.Length; j++) {
int state = j - val.Constant;
ranges[targetLabels[j]].UnionWith(nodeRange, state, state);
}
StateRange nextRange = ranges[body[i + 1]];
nextRange.UnionWith(nodeRange, int.MinValue, -1 - val.Constant);
nextRange.UnionWith(nodeRange, targetLabels.Length - val.Constant, int.MaxValue);
break;
}
case ILCode.Br:
case ILCode.Leave:
ranges[(ILLabel)expr.Operand].UnionWith(nodeRange);
break;
case ILCode.Brtrue:
{
SymbolicValue val = Eval(expr.Arguments[0]);
if (val.Type == SymbolicValueType.StateEquals) {
ranges[(ILLabel)expr.Operand].UnionWith(nodeRange, val.Constant, val.Constant);
StateRange nextRange = ranges[body[i + 1]];
nextRange.UnionWith(nodeRange, int.MinValue, val.Constant - 1);
nextRange.UnionWith(nodeRange, val.Constant + 1, int.MaxValue);
} else if (val.Type == SymbolicValueType.StateInEquals) {
ranges[body[i + 1]].UnionWith(nodeRange, val.Constant, val.Constant);
StateRange targetRange = ranges[(ILLabel)expr.Operand];
targetRange.UnionWith(nodeRange, int.MinValue, val.Constant - 1);
targetRange.UnionWith(nodeRange, val.Constant + 1, int.MaxValue);
} else {
throw new YieldAnalysisFailedException();
}
break;
}
case ILCode.Nop:
ranges[body[i + 1]].UnionWith(nodeRange);
break;
case ILCode.Ret:
break;
case ILCode.Stloc:
{
SymbolicValue val = Eval(expr.Arguments[0]);
if (val.Type == SymbolicValueType.State && val.Constant == 0 && rangeAnalysisStateVariable == null)
rangeAnalysisStateVariable = (ILVariable)expr.Operand;
else
throw new YieldAnalysisFailedException();
goto case ILCode.Nop;
}
case ILCode.Call:
// in some cases (e.g. foreach over array) the C# compiler produces a finally method outside of try-finally blocks
if (forDispose) {
MethodDefinition mdef = GetMethodDefinition(expr.Operand as MethodReference);
if (mdef == null || finallyMethodToStateInterval.ContainsKey(mdef))
throw new YieldAnalysisFailedException();
finallyMethodToStateInterval.Add(mdef, nodeRange.ToEnclosingInterval());
} else {
throw new YieldAnalysisFailedException();
}
break;
default:
if (forDispose)
throw new YieldAnalysisFailedException();
else
return i;
}
}
return bodyLength;
}
开发者ID:hlesesne,项目名称:ILSpy,代码行数:98,代码来源:YieldReturnDecompiler.cs
示例11: ConvertToAst
List<ILNode> ConvertToAst(List<ByteCode> body)
{
List<ILNode> ast = new List<ILNode>();
// Convert stack-based IL code to ILAst tree
foreach(ByteCode byteCode in body) {
OpCode opCode = byteCode.OpCode;
object operand = byteCode.Operand;
MethodBodyRocks.ExpandMacro(ref opCode, ref operand, methodDef.Body);
ILExpression expr = new ILExpression(opCode, operand);
expr.ILRanges.Add(new ILRange() { From = byteCode.Offset, To = byteCode.EndOffset });
// Label for this instruction
if (byteCode.Label != null) {
ast.Add(byteCode.Label);
}
// Reference arguments using temporary variables
int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count;
for (int i = byteCode.StackBefore.Count - popCount; i < byteCode.StackBefore.Count; i++) {
StackSlot slot = byteCode.StackBefore[i];
if (slot.PushedBy != null) {
ILExpression ldExpr = new ILExpression(OpCodes.Ldloc, slot.LoadFrom);
expr.Arguments.Add(ldExpr);
} else {
ILExpression ldExpr = new ILExpression(OpCodes.Ldloc, new ILVariable() { Name = "ex", IsGenerated = true });
expr.Arguments.Add(ldExpr);
}
}
// Store the result to temporary variable(s) if needed
if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0) {
ast.Add(expr);
} else if (byteCode.StoreTo.Count == 1) {
ast.Add(new ILExpression(OpCodes.Stloc, byteCode.StoreTo[0], expr));
} else {
ILVariable tmpVar = new ILVariable() { Name = "expr_" + byteCode.Offset.ToString("X2"), IsGenerated = true };
ast.Add(new ILExpression(OpCodes.Stloc, tmpVar, expr));
foreach(ILVariable storeTo in byteCode.StoreTo) {
ast.Add(new ILExpression(OpCodes.Stloc, storeTo, new ILExpression(OpCodes.Ldloc, tmpVar)));
}
}
}
// Try to in-line stloc / ldloc pairs
for(int i = 0; i < ast.Count - 1; i++) {
if (i < 0) continue;
ILExpression currExpr = ast[i] as ILExpression;
ILExpression nextExpr = ast[i + 1] as ILExpression;
if (currExpr != null && nextExpr != null && currExpr.OpCode.Code == Code.Stloc) {
// If the next expression is generated stloc, look inside
if (nextExpr.OpCode.Code == Code.Stloc && ((ILVariable)nextExpr.Operand).IsGenerated) {
nextExpr = nextExpr.Arguments[0];
}
// Find the use of the 'expr'
for(int j = 0; j < nextExpr.Arguments.Count; j++) {
ILExpression arg = nextExpr.Arguments[j];
// We are moving the expression evaluation past the other aguments.
// It is ok to pass ldloc because the expression can not contain stloc and thus the ldcoc will still return the same value
if (arg.OpCode.Code == Code.Ldloc) {
bool canInline;
allowInline.TryGetValue((ILVariable)arg.Operand, out canInline);
if (arg.Operand == currExpr.Operand && canInline) {
// Assigne the ranges for optimized away instrustions somewhere
currExpr.Arguments[0].ILRanges.AddRange(currExpr.ILRanges);
currExpr.Arguments[0].ILRanges.AddRange(nextExpr.Arguments[j].ILRanges);
ast.RemoveAt(i);
nextExpr.Arguments[j] = currExpr.Arguments[0]; // Inline the stloc body
i -= 2; // Try the same index again
break; // Found
}
} else {
break; // Side-effects
}
}
}
}
return ast;
}
开发者ID:HEskandari,项目名称:ILSpy,代码行数:87,代码来源:ILAstBuilder.cs
示例12: CopyPropagation
/// <summary>
/// Runs a very simple form of copy propagation.
/// Copy propagation is used in two cases:
/// 1) assignments from arguments to local variables
/// If the target variable is assigned to only once (so always is that argument) and the argument is never changed (no ldarga/starg),
/// then we can replace the variable with the argument.
/// 2) assignments of address-loading instructions to local variables
/// </summary>
public void CopyPropagation(List<ILNode> newList)
{
var newListTemp = newList;
method.GetSelfAndChildrenRecursive<ILNode>(newList);
bool recalc = false;
foreach (var node1 in newList) {
var block = node1 as ILBlock;
if (block == null)
continue;
for (int i = 0; i < block.Body.Count; i++) {
ILVariable v;
ILExpression copiedExpr;
if (block.Body[i].Match(ILCode.Stloc, out v, out copiedExpr)
&& !v.IsParameter && numStloc.GetOrDefault(v) == 1 && numLdloca.GetOrDefault(v) == 0
&& CanPerformCopyPropagation(copiedExpr, v))
{
// un-inline the arguments of the ldArg instruction
ILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Arguments.Count];
for (int j = 0; j < uninlinedArgs.Length; j++) {
uninlinedArgs[j] = new ILVariable { GeneratedByDecompiler = true, Name = v.Name + "_cp_" + j };
block.Body.Insert(i++, new ILExpression(ILCode.Stloc, uninlinedArgs[j], copiedExpr.Arguments[j]));
recalc = true;
}
// perform copy propagation:
foreach (var node2 in newListTemp) {
var expr = node2 as ILExpression;
if (expr == null)
continue;
if (expr.Code == ILCode.Ldloc && expr.Operand == v) {
expr.Code = copiedExpr.Code;
expr.Operand = copiedExpr.Operand;
for (int j = 0; j < uninlinedArgs.Length; j++) {
expr.Arguments.Add(new ILExpression(ILCode.Ldloc, uninlinedArgs[j]));
}
}
}
if (context.CalculateILRanges) {
Utils.AddILRanges(block, block.Body, i, block.Body[i].ILRanges);
Utils.AddILRanges(block, block.Body, i, copiedExpr.ILRanges);
}
block.Body.RemoveAt(i);
if (uninlinedArgs.Length > 0) {
// if we un-inlined stuff; we need to update the usage counters
AnalyzeMethod();
}
InlineInto(block, block.Body, i, aggressive: false); // maybe inlining gets possible after the removal of block.Body[i]
i -= uninlinedArgs.Length + 1;
if (recalc) {
recalc = false;
newListTemp = method.GetSelfAndChildrenRecursive<ILNode>(newListTemp == newList ? (newListTemp = list_ILNode) : newListTemp);
}
}
}
}
}
开发者ID:GreenDamTan,项目名称:dnSpy,代码行数:66,代码来源:ILInlining.cs
示例13: CanPerformCopyPropagation
bool CanPerformCopyPropagation(ILExpression expr, ILVariable copyVariable)
{
switch (expr.Code) {
case ILCode.Ldloca:
case ILCode.Ldelema:
case ILCode.Ldflda:
case ILCode.Ldsflda:
// All address-loading instructions always return the same value for a given operand/argument combination,
// so they can be safely copied.
return true;
case ILCode.Ldloc:
ILVariable v = (ILVariable)expr.Operand;
if (v.IsParameter) {
// Parameters can be copied only if they aren't assigned to (directly or indirectly via ldarga)
return numLdloca.GetOrDefault(v) == 0 && numStloc.GetOrDefault(v) == 0;
} else {
// Variables are be copied only if both they and the target copy variable are generated,
// and if the variable has only a single assignment
return v.GeneratedByDecompiler && copyVariable.GeneratedByDecompiler && numLdloca.GetOrDefault(v) == 0 && numStloc.GetOrDefault(v) == 1;
}
default:
return false;
}
}
开发者ID:GreenDamTan,项目名称:dnSpy,代码行数:24,代码来源:ILInlining.cs
示例14: FindLoadInNext
/// <summary>
/// Finds the position to inline to.
/// </summary>
/// <returns>true = found; false = cannot continue search; null = not found</returns>
bool? FindLoadInNext(ILExpression expr, ILVariable v, ILExpression expressionBeingMoved, out ILExpression parent, out int pos)
{
parent = null;
pos = 0;
if (expr == null)
return false;
for (int i = 0; i < expr.Arguments.Count; i++) {
// Stop when seeing an opcode that does not guarantee that its operands will be evaluated.
// Inlining in that case might result in the inlined expresion not being evaluted.
if (i == 1 && (expr.Code == ILCode.LogicAnd || expr.Code == ILCode.LogicOr || expr.Code == ILCode.TernaryOp || expr.Code == ILCode.NullCoalescing))
return false;
ILExpression arg = expr.Arguments[i];
if ((arg.Code == ILCode.Ldloc || arg.Code == ILCode.Ldloca) && arg.Operand == v) {
parent = expr;
pos = i;
return true;
}
bool? r = FindLoadInNext(arg, v, expressionBeingMoved, out parent, out pos);
if (r != null)
return r;
}
if (IsSafeForInlineOver(expr, expressionBeingMoved))
return null; // continue searching
else
return false; // abort, inlining not possible
}
开发者ID:GreenDamTan,项目名称:dnSpy,代码行数:32,代码来源:ILInlining.cs
示例15: CanInlineInto
/// <summary>
/// Gets whether 'expressionBeingMoved' can be inlined into 'expr'.
/// </summary>
public bool CanInlineInto(ILExpression expr, ILVariable v, ILExpression expressionBeingMoved)
{
ILExpression parent;
int pos;
return FindLoadInNext(expr, v, expressionBeingMoved, out parent, out pos) == true;
}
开发者ID:GreenDamTan,项目名称:dnSpy,代码行数:9,代码来源:ILInlining.cs
示例16: IsGeneratedValueTypeTemporary
/// <summary>
/// Is this a temporary variable generated by the C# compiler for instance method calls on value type values
/// </summary>
/// <param name="next">The next top-level expression</param>
/// <param name="parent">The direct parent of the load within 'next'</param>
/// <param name="pos">Index of the load within 'parent'</param>
/// <param name="v">The variable being inlined.</param>
/// <param name="inlinedExpression">The expression being inlined</param>
bool IsGeneratedValueTypeTemporary(ILExpression next, ILExpression parent, int pos, ILVariable v, ILExpression inlinedExpression)
{
if (pos == 0 && v.Type != null && DnlibExtensions.IsValueType(v.Type)) {
// Inlining a value type variable is allowed only if the resulting code will maintain the semantics
// that the method is operating on a copy.
// Thus, we have to disallow inlining of other locals, fields, array elements, dereferenced pointers
switch (inlinedExpression.Code) {
case ILCode.Ldloc:
case ILCode.Stloc:
case ILCode.CompoundAssignment:
case ILCode.Ldelem:
case ILCode.Ldelem_I:
case ILCode.Ldelem_I1:
case ILCode.Ldelem_I2:
case ILCode.Ldelem_I4:
case ILCode.Ldelem_I8:
case ILCode.Ldelem_R4:
case ILCode.Ldelem_R8:
case ILCode.Ldelem_Ref:
case ILCode.Ldelem_U1:
case ILCode.Ldelem_U2:
case ILCode.Ldelem_U4:
case ILCode.Ldobj:
case ILCode.Ldind_Ref:
return false;
case ILCode.Ldfld:
case ILCode.Stfld:
case ILCode.Ldsfld:
case ILCode.Stsfld:
// allow inlining field access only if it's a readonly field
FieldDef f = ((IField)inlinedExpression.Operand).Resolve();
if (!(f != null && f.IsInitOnly))
return false;
break;
case ILCode.Call:
case ILCode.CallGetter:
// inlining runs both before and after IntroducePropertyAccessInstructions,
// so we have to handle both 'call' and 'callgetter'
IMethod mr = (IMethod)inlinedExpression.Operand;
// ensure that it's not an multi-dimensional array getter
TypeSig ts;
if (mr.DeclaringType is TypeSpec && (ts = ((TypeSpec)mr.DeclaringType).TypeSig.RemovePinnedAndModifiers()) != null && ts.IsSingleOrMultiDimensionalArray)
return false;
goto case ILCode.Callvirt;
case ILCode.Callvirt:
case ILCode.CallvirtGetter:
// don't inline foreach loop variables:
mr = (IMethod)inlinedExpression.Operand;
if (mr.Name == "get_Current" && mr.MethodSig != null && mr.MethodSig.HasThis)
return false;
break;
case ILCode.Castclass:
case ILCode.Unbox_Any:
// These are valid, but might occur as part of a foreach loop variable.
ILExpression arg = inlinedExpression.Arguments[0];
if (arg.Code == ILCode.CallGetter || arg.Code == ILCode.CallvirtGetter || arg.Code == ILCode.Call || arg.Code == ILCode.Callvirt) {
mr = (IMethod)arg.Operand;
if (mr.Name == "get_Current" && mr.MethodSig != null && mr.MethodSig.HasThis)
return false; // looks like a foreach loop variable, so don't inline it
}
break;
}
// inline the compiler-generated variable that are used when accessing a member on a value type:
switch (parent.Code) {
case ILCode.Call:
case ILCode.CallGetter:
case ILCode.CallSetter:
case ILCode.Callvirt:
case ILCode.CallvirtGetter:
case ILCode.CallvirtSetter:
IMethod mr = parent.Operand as IMethod;
return mr == null || mr.MethodSig == null ? false : mr.MethodSig.HasThis;
case ILCode.Stfld:
case ILCode.Ldfld:
case ILCode.Ldflda:
case ILCode.Await:
return true;
}
}
return false;
}
开发者ID:GreenDamTan,项目名称:dnSpy,代码行数:90,代码来源:ILInlining.cs
示例17: Capture
static bool Capture(ref ILVariable pmvar, ILVariable v)
{
if (pmvar != null) return pmvar == v;
pmvar = v;
return true;
}
开发者ID:ropean,项目名称:Usable,代码行数:6,代码来源:LiftedOperators.cs
示例18: AnalyzeMoveNext
void AnalyzeMoveNext()
{
MethodDefinition moveNextMethod = enumeratorType.Methods.FirstOrDefault(m => m.Name == "MoveNext");
ILBlock ilMethod = CreateILAst(moveNextMethod);
if (ilMethod.Body.Count == 0)
throw new YieldAnalysisFailedException();
ILExpression lastReturnArg;
if (!ilMethod.Body.Last().Match(ILCode.Ret, out lastReturnArg))
throw new YieldAnalysisFailedException();
// There are two possibilities:
if (lastReturnArg.Code == ILCode.Ldloc) {
// a) the compiler uses a variable for returns (in debug builds, or when there are try-finally blocks)
returnVariable = (ILVariable)lastReturnArg.Operand;
returnLabel = ilMethod.Body.ElementAtOrDefault(ilMethod.Body.Count - 2) as ILLabel;
if (returnLabel == null)
throw new YieldAnalysisFailedException();
} else {
// b) the compiler directly returns constants
returnVariable = null;
returnLabel = null;
// In this case, the last return must return false.
if (lastReturnArg.Code != ILCode.Ldc_I4 || (int)lastReturnArg.Operand != 0)
throw new YieldAnalysisFailedException();
}
ILTryCatchBlock tryFaultBlock = ilMethod.Body[0] as ILTryCatchBlock;
List<ILNode> body;
int bodyLength;
if (tryFaultBlock != null) {
// there are try-finally blocks
if (returnVariable == null) // in this case, we must use a return variable
throw new YieldAnalysisFailedException();
// must be a try-fault block:
if (tryFaultBlock.CatchBlocks.Count != 0 || tryFaultBlock.FinallyBlock != null || tryFaultBlock.FaultBlock == null)
throw new YieldAnalysisFailedException();
ILBlock faultBlock = tryFaultBlock.FaultBlock;
// Ensure the fault block contains the call to Dispose().
if (faultBlock.Body.Count != 2)
throw new YieldAnalysisFailedException();
MethodReference disposeMethodRef;
ILExpression disposeArg;
if (!faultBlock.Body[0].Match(ILCode.Call, out disposeMethodRef, out disposeArg))
throw new YieldAnalysisFailedException();
if (GetMethodDefinition(disposeMethodRef) != disposeMethod || !LoadFromArgument.This.Match(disposeArg))
throw new YieldAnalysisFailedException();
if (!faultBlock.Body[1].Match(ILCode.Endfinally))
throw new YieldAnalysisFailedException();
body = tryFaultBlock.TryBlock.Body;
bodyLength = body.Count;
} else {
// no try-finally blocks
body = ilMethod.Body;
if (returnVariable == null)
bodyLength = body.Count - 1; // all except for the return statement
else
bodyLength = body.Count - 2; // all except for the return label and statement
}
// Now verify that the last instruction in the body is 'ret(false)'
if (returnVariable != null) {
// If we don't have a return variable, we already verified that above.
// If we do have one, check for 'stloc(returnVariable, ldc.i4(0))'
// Maybe might be a jump to the return label after the stloc:
ILExpression leave = body.ElementAtOrDefault(bodyLength - 1) as ILExpression;
if (leave != null && (leave.Code == ILCode.Br || leave.Code == ILCode.Leave) && leave.Operand == returnLabel)
bodyLength--;
ILExpression store0 = body.ElementAtOrDefault(bodyLength - 1) as ILExpression;
if (store0 == null || store0.Code != ILCode.Stloc || store0.Operand != returnVariable)
throw new YieldAnalysisFailedException();
if (store0.Arguments[0].Code != ILCode.Ldc_I4 || (int)store0.Arguments[0].Operand != 0)
throw new YieldAnalysisFailedException();
bodyLength--; // don't conside the stloc instruction to be part of the body
}
// verify that the last element in the body is a label pointing to the 'ret(false)'
returnFalseLabel = body.ElementAtOrDefault(bodyLength - 1) as ILLabel;
if (returnFalseLabel == null)
throw new YieldAnalysisFailedException();
InitStateRanges(body[0]);
int pos = AssignStateRanges(body, bodyLength, forDispose: false);
if (pos > 0 && body[pos - 1] is ILLabel) {
pos--;
} else {
// ensure that the first element at body[pos] is a label:
ILLabel newLabel = new ILLabel();
newLabel.Name = "YieldReturnEntryPoint";
ranges[newLabel] = ranges[body[pos]]; // give the label the range of the instruction at body[pos]
body.Insert(pos, newLabel);
bodyLength++;
}
List<KeyValuePair<ILLabel, StateRange>> labels = new List<KeyValuePair<ILLabel, StateRange>>();
for (int i = pos; i < bodyLength; i++) {
//.........这里部分代码省略.........
开发者ID:hlesesne,项目名称:ILSpy,代码行数:101,代码来源:YieldReturnDecompiler.cs
示例19: AddStateVariable
public void AddStateVariable(ILVariable v)
{
if (!stateVariables.Contains(v))
stateVariables.Add(v);
}
开发者ID:KOLANICH,项目名称:ILSpy,代码行数:5,代码来源:SymbolicExecution.cs
示例20: MatchFixedInitializer
bool MatchFixedInitializer(List<ILNode> body, int i, out ILVariable pinnedVar, out ILExpression initValue, out int nextPos)
{
if (body[i].Match(ILCode.Stloc, out pinnedVar, out initValue) && pinnedVar.IsPinned && !IsNullOrZero(initValue)) {
initValue = (ILExpression)body[i];
nextPos = i + 1;
HandleStringFixing(pinnedVar, body, ref nextPos, ref initValue);
return true;
}
ILCondition ifStmt = body[i] as ILCondition;
ILExpression arrayLoadingExpr;
if (ifStmt != null && MatchFixedArrayInitializerCondition(ifStmt.Condition, out arrayLoadingExpr)) {
ILVariable arrayVariable = (ILVariable)arrayLoadingExpr.Operand;
ILExpression trueValue;
if (ifStmt.TrueBlock != null && ifStmt.TrueBlock.Body.Count == 1
&& ifStmt.TrueBlock.Body[0].Match(ILCode.Stloc, out pinnedVar, out trueValue)
&& pinnedVar.IsPinned && IsNullOrZero(trueValue))
{
if (ifStmt.FalseBlock != null && ifStmt.FalseBlock.Body.Count == 1 && ifStmt.FalseBlock.Body[0] is ILFixedStatement) {
ILFixedStatement fixedStmt = (ILFixedStatement)ifStmt.FalseBlock.Body[0];
ILVariable stlocVar;
ILExpression falseValue;
if (fixedStmt.Initializers.Count == 1 && fixedStmt.BodyBlock.Body.Count == 0
&& fixedStmt.Initializers[0].Match(ILCode.Stloc, out stlocVar, out falseValue) && stlocVar == pinnedVar)
{
ILVariable loadedVariable;
if (falseValue.Code == ILCode.Ldelema
&& falseValue.Arguments[0].Match(ILCode.Ldloc, out loadedVariable) && loadedVariable == arrayVariable
&& IsNullOrZero(falseValue.Arguments[1]))
{
// OK, we detected the pattern for fixing an array.
// Now check whether the loading expression was a store ot a temp. var
// that can be eliminated.
if (arrayLoadingExpr.Code == ILCode.Stloc) {
ILInlining inlining = new ILInlining(method);
if (inlining.numLdloc.GetOrDefault(arrayVariable) == 2 &&
inlining.numStloc.GetOrDefault(arrayVariable) == 1 && inlining.numLdloca.GetOrDefault(arrayVariable) == 0)
{
arrayLoadingExpr = arrayLoadingExpr.Arguments[0];
}
}
initValue = new ILExpression(ILCode.Stloc, pinnedVar, arrayLoadingExpr);
nextPos = i + 1;
return true;
}
}
}
}
}
initValue = null;
nextPos = -1;
return false;
}
开发者ID:BGCX261,项目名称:zoom-decompiler-hg-to-git,代码行数:52,代码来源:PeepholeTransform.cs
注:本文中的ILVariable类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论