public void VisitLoadField(LoadField load) { if (m_equality != null) { DoFieldRef(load.Field, load.Index); } }
private bool DoCallsExternalCode(Call call, ref string name) { if (call.Target.Name == "Invoke" && call.Target.HasThis) { int i = call.GetThisIndex(m_info); Log.DebugLine(this, "found invoke call at {0:X2}", call.Untyped.Offset); if (i >= 0) { LoadField load = m_info.Instructions[i] as LoadField; if (load != null) { Log.DebugLine(this, " this pointer is at {0:X2}", load.Untyped.Offset); if (load.Field.FieldType.IsSameOrSubclassOf("System.Delegate", Cache)) { Log.DebugLine(this, " and is a delegate type"); name = load.Field.ToString(); return(true); } } } } return(false); }
protected override void VisitLoadField(LoadField downNode, object o) { ObjectReferenceValue obj = this.state.Stack.Pop() as ObjectReferenceValue; PointerValue ptr = new PointerToObjectFieldValue(obj.Obj, downNode.Field); this.loadVar(downNode, ptr, o); }
Expression ProcessVertexBuffer(StageValue vertexBuffer) { Expression result; if (!VertexBuffers.TryGetValue(vertexBuffer.Value.ToString(), out result)) { var src = vertexBuffer.Value.Source; var type = ILFactory.GetType(src, "Uno.Graphics.VertexBuffer"); if (vertexBuffer.Value.ReturnType.Equals(type)) { result = ProcessStage(vertexBuffer, MetaStage.Volatile, MetaStage.Volatile).Value; VertexBuffers.Add(vertexBuffer.Value.ToString(), result); return(result); } var loc = LocationStack.Last(); var mp = GetProperty(loc); var name = CreateFieldName(mp, loc); var owner = Path.DrawBlock.Method.DeclaringType; var field = new Field(src, owner, name, null, Modifiers.Private | Modifiers.Generated, 0, type); owner.Fields.Add(field); result = new LoadField(src, new This(src, owner), field); VertexBuffers.Add(vertexBuffer.Value.ToString(), result); if (vertexBuffer.MinStage > MetaStage.Volatile) { Log.Error(src, ErrorCode.E5025, "Vertex buffer cannot be accessed from " + vertexBuffer.MinStage + " stage"); return(result); } else if (vertexBuffer.MinStage == MetaStage.Volatile) { InitScope.Statements.Add( new StoreField(src, new This(src, owner), field, ILFactory.NewObject(src, "Uno.Graphics.VertexBuffer", ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Dynamic")))); FrameScope.Statements.Add( ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Update", vertexBuffer.Value)); } else { InitScope.Statements.Add( new StoreField(src, new This(src, owner), field, ILFactory.NewObject(src, "Uno.Graphics.VertexBuffer", vertexBuffer.Value, ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Immutable")))); } FreeScope.Statements.Add( ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Dispose")); } return(result); }
public Expression ThisInside(Expression thisExpr) { var loadFirstField = new LoadField(Source.Unknown, thisExpr, Type.Fields[0]); if (Parent == null) { return(loadFirstField); } else { return(Parent.ThisInside(loadFirstField)); } }
private TypeReference DoGetType(int index, int nth) { TypeReference type = null; int i = m_info.Tracker.GetStackIndex(index, nth); if (i >= 0) { do // TODO: would be nice to do something with load constant instructions as well { LoadArg arg = m_info.Instructions[i] as LoadArg; if (arg != null && arg.Arg >= 1) { ParameterDefinition p = m_info.Method.Parameters[arg.Arg - 1]; type = p.ParameterType; break; } LoadField field = m_info.Instructions[i] as LoadField; if (field != null) { type = field.Field.FieldType; break; } LoadLocal local = m_info.Instructions[i] as LoadLocal; if (local != null) { VariableDefinition v = m_info.Method.Body.Variables[local.Variable]; type = v.VariableType; break; } LoadStaticField sfield = m_info.Instructions[i] as LoadStaticField; if (sfield != null) { type = sfield.Field.FieldType; break; } Box box = m_info.Instructions[i] as Box; if (box != null) { type = box.Type; break; } }while (false); } return(type); }
protected internal override void VisitLoadField(LoadField node, object data) { StackTypes stack = data as StackTypes; if (node.Field.IsStatic) { stack.Push(node.Field.FieldType); } else { Verifier.ProcessLdFld(stack, node.Field, false); } AddTask(node.Next, stack); }
public void VisitLoadField(LoadField field) { if (m_needsCheck) { Log.Indent(); LoadArg load = m_info.Instructions[field.Index - 1] as LoadArg; if (load != null && m_types[load.Arg] != null) { TypeReference type = field.Field.DeclaringType; DoUseArg(load.Arg, field.Untyped.Offset, type); } Log.Unindent(); } }
protected override Statement TransformDraw(Draw draw) { var src = draw.Source; var scope = new Scope(src); var field = GetField(draw); var obj = new LoadField(src, new This(src, field.DeclaringType).Address, field).Address; var index = 0; foreach (var t in TerminalFields) { if (t.Value != draw.State.Terminals[t.Key].ToString()) { scope.Statements.Add(ILFactory.SetProperty(src, obj, t.Key, draw.State.Terminals[t.Key])); } } foreach (var v in draw.State.RuntimeConstants) { scope.Statements.Add(CallConst(src, obj, v, index++)); } scope.Statements.Add(ILFactory.CallMethod(src, obj, "Use")); foreach (var v in draw.State.VertexAttributes) { scope.Statements.Add(CallAttrib(src, obj, v, index++)); } foreach (var v in draw.State.Uniforms) { scope.Statements.Add(CallUniform(src, obj, v, index++)); } foreach (var v in draw.State.PixelSamplers) { scope.Statements.Add(CallSampler(src, obj, v, index++)); } scope.Statements.Add(draw.State.OptionalIndices == null ? ILFactory.CallMethod(src, obj, "DrawArrays", draw.State.Terminals["VertexCount"]) : ILFactory.CallMethod(src, obj, "Draw", draw.State.Terminals["VertexCount"], draw.State.OptionalIndices.IndexType, draw.State.OptionalIndices.Buffer)); return(draw.State.Terminals.ContainsKey("CullDrawable") ? (Statement) new IfElse(src, ILFactory.CallOperator(src, Essentials.Bool, "!", draw.State.Terminals["CullDrawable"]), scope) : scope); }
public void VisitCall(Call call) { if (m_disposable) { if (m_isNullaryDispose) { if (call.Target.ToString().Contains("System.GC::SuppressFinalize(System.Object)")) { Log.DebugLine(this, "has suppress call"); m_supressWasCalled = true; } } if (m_disposableFields.Count > 0) { // ldfld class System.IO.TextWriter Smokey.DisposableFieldsTest/GoodCase::m_writer // callvirt instance void class [mscorlib]System.IO.TextWriter::Dispose() if (call.Target.Name == "Dispose" || call.Target.Name == "Close") { if (m_minfo.Instructions[call.Index - 1].Untyped.OpCode.Code == Code.Ldfld) { FieldReference field = (FieldReference)m_minfo.Instructions[call.Index - 1].Untyped.Operand; Log.DebugLine(this, "found Dispose call for {0}", field.Name); Unused.Value = m_disposableFields.Remove(field.ToString()); } } } // ldarg.0 // ldfld class [mscorlib]System.IO.StringWriter Smokey.Tests.DisposeableTest/NoNullCheck1::m_writer // callvirt instance void class [mscorlib]System.IO.TextWriter::Dispose() if ((m_isNullaryDispose || m_isUnaryDispose) && call.Index >= 2 && !m_callsNullableField && !m_hasNullCall) { LoadArg load1 = m_minfo.Instructions[call.Index - 2] as LoadArg; LoadField load2 = m_minfo.Instructions[call.Index - 1] as LoadField; if (load1 != null && load2 != null) { if (load1.Arg == 0 && !load2.Field.FieldType.IsValueType) { if (m_ownedFields.IndexOf(load2.Field) >= 0) { m_callsNullableField = true; } } } } } }
// ldarg.0 this // ldfld System.String Smokey.Tests.WeakIdentityLockTest/Cases::m_string private FieldReference DoGetField(int index) { FieldReference field = null; if (index > 0) { LoadField load = m_info.Instructions[index] as LoadField; LoadArg arg = m_info.Instructions[index - 1] as LoadArg; if (arg != null && load != null && arg.Arg == 0) { field = load.Field; } } return(field); }
// ldfld bool Smokey.Tests.DisposeableTest/NoNullCheck2::m_disposed // brtrue IL_001d public void VisitConditional(ConditionalBranch branch) { if (m_disposable) { if (m_isNullaryDispose || m_isUnaryDispose) { if (branch.Index > 0) { LoadField load = m_minfo.Instructions[branch.Index - 1] as LoadField; if (load == null || load.Field.Name.IndexOf("m_disposed") < 0) // testing m_disposed does not count as a branch for null checking { m_hasNoBranches = false; } } } } }
private TypeReference DoGetThisType(Call call) { TypeReference self = null; if (call.Target.HasThis) { int index = call.GetThisIndex(m_info); if (index >= 0) { do { LoadArg arg = m_info.Instructions[index] as LoadArg; if (arg != null) { self = arg.Type; break; } LoadField field = m_info.Instructions[index] as LoadField; if (field != null) { self = field.Field.FieldType; break; } LoadStaticField sfield = m_info.Instructions[index] as LoadStaticField; if (sfield != null) { self = sfield.Field.FieldType; break; } LoadLocal local = m_info.Instructions[index] as LoadLocal; if (local != null) { self = local.Type; break; } }while (false); } } return(self); }
public void VisitLoadField(LoadField load) { if (m_needsCheck) { State state; if (m_fields.TryGetValue(load.Field, out state)) { if (state == State.Defined) { m_fields[load.Field] = State.Used; } } else { m_fields.Add(load.Field, State.Referenced); } } }
// ldarg.0 // ldfld string Smokey.Tests.EqualsMissesStateTest/Good1::m_name // ret private void DoTrivialGetter() { do { if (m_minfo.Instructions.Length != 3) { break; } LoadArg larg = m_minfo.Instructions[0] as LoadArg; if (larg == null || larg.Arg != 0) { break; } LoadField load = m_minfo.Instructions[1] as LoadField; if (load == null) { break; } if (m_minfo.Type.Fields.GetField(load.Field.Name) == null) // only count fields defined int this class { break; } if (m_minfo.Instructions[2].Untyped.OpCode.Code != Code.Ret) { break; } Log.DebugLine(this, "found trivial getter for {0}", load.Field.Name); string name = m_minfo.Method.Name.Substring(4); Property prop = m_properties.SingleOrDefault(p => p.Name == name && p.Field == load.Field.Name); if (prop == null) { prop = new Property(name, load.Field.Name); m_properties.Add(prop); } prop.HasTrivialGetter = true; }while (false); }
public static Expression TransformSwizzleToNewObject(this Swizzle s, Namescope scope) { // a.XYZ -> (temp = a, new T(temp.X, temp.Y, temp.Z)) // OR new T(a.X, a.Y, a.Z) var obj = s.Object; var ind = TryCreateIndirection(scope, ref obj); var args = new Expression[s.Fields.Length]; for (int i = 0; i < s.Fields.Length; i++) { args[i] = new LoadField(s.Source, obj, s.Fields[i]); } var result = new NewObject(s.Source, s.Constructor, args); return(ind != null ? (Expression) new SequenceOp(ind, result) : result); }
Expression AddCached(string type, Func <Expression> factory, params object[] descriptor) { if (descriptor.Length == 0) { throw new ArgumentException("Expected at least one descriptor"); } var hash = type.GetHashCode(); foreach (var e in descriptor) { hash = 13 * hash + (e ?? "<null>").ToString().GetHashCode(); } var path = (descriptor[0] ?? "").ToString(); if (path.IsValidPath()) { type = Path.GetFileNameWithoutExtension(path); } Expression result; var key = (type + hash.ToString("x8")).ToIdentifier(); if (!_cache.TryGetValue(key, out result)) { var value = factory(); var bundle = GetBundle(value.Source.Package); var field = new Field(value.Source, bundle, key, null, Modifiers.Public | Modifiers.Static, FieldModifiers.ReadOnly, value.ReturnType); result = new LoadField(value.Source, null, field); bundle.Fields.Add(field); _fields[field] = value; _cache[key] = result; } return(result); }
private void DoGetReferences(Dictionary <MethodInfo, List <string> > references, MethodInfo info) { for (int i = 1; i < info.Instructions.Length; ++i) { do { LoadField field = info.Instructions[i] as LoadField; if (field != null) { if (info.Instructions.LoadsThisArg(i - 1)) { DoAddReference(references, info, field.Field.Name, field.Untyped.Offset); } break; } LoadFieldAddress addr = info.Instructions[i] as LoadFieldAddress; if (addr != null) { if (info.Instructions.LoadsThisArg(i - 1)) { DoAddReference(references, info, addr.Field.Name, addr.Untyped.Offset); } break; } Call call = info.Instructions[i] as Call; if (call != null && call.Target.Name.StartsWith("get_")) { if (info.Instructions.LoadsThisArg(i - 1)) { DoAddReference(references, info, call.Target.Name, call.Untyped.Offset); } break; } }while (false); } }
private FieldReference DoSaveLocks(Call call) { FieldReference field = null; // Look for a lock using one of our fields. if (DoMatchLock1(call.Index)) { LoadStaticField sload = (LoadStaticField)m_info.Instructions[call.Index - 3]; if (sload.Field.DeclaringType == m_info.Type) { field = sload.Field; } } else if (DoMatchLock2(call.Index)) { LoadField load = (LoadField)m_info.Instructions[call.Index - 3]; field = load.Field; } // If we found one then record that the method locked the field. if (field != null) { List <FieldReference> fields; if (!m_current.Locked.TryGetValue(m_info.Method, out fields)) { fields = new List <FieldReference>(); m_current.Locked.Add(m_info.Method, fields); } fields.Add(field); Log.DebugLine(this, "{0} locks {1}", m_info.Method.Name, field.Name); } return(field); }
protected override void VisitLoadField(LoadField node, object data) { state.Stack.Perform_LoadField(node.Field, out exc); nextNode = node.Next; }
public void VisitLoadField(LoadField load) { DoAddField(load.Field); }
public static MethodBodyBlock Convert(MethodEx method) { if (!method.IsVerified) { throw new ConvertionException(); } MethodInfoExtention _method_ = new MethodInfoExtention(method.Method); MethodBodyBlock mainBlock = new MethodBodyBlock(_method_.GetReturnType().type); mainBlock.Options["StackTypes"] = new StackTypes(); Block currentBlock = mainBlock; Node[] heads = new Node[method.Count]; Node[] tails = new Node[method.Count]; Node head = null; Node tail = null; Node firstBlock = null; Node lastBlock = null; int iNum, iNumNext; Variable[] locals = new Variable[method.Locals.Count]; Variable[] args = new Variable[_method_.ArgCount]; VariablesList methodVarList = mainBlock.Variables; for (int i = 0; i < args.Length; i++) { args[i] = methodVarList.CreateVar(_method_.GetArgType(i).type, VariableKind.Parameter); args[i].Name = "Arg" + i; // methodVarList.Add(args[i]); } for (int i = 0; i < locals.Length; i++) { locals[i] = methodVarList.CreateVar(method.Locals[i], VariableKind.Local); locals[i].Name = "Loc" + i; // methodVarList.Add(locals[i]); } BlockType nextBlockType; int nextBlockStart = -1; int nextBlockEnd = 1 << 30; int nextBlockIndex; Type nextCatchBlockType; Hashtable tryBlocks = new Hashtable(); Hashtable filterBlocks = new Hashtable(); Stack blockEnds = new Stack(); blockEnds.Push(method.Count); FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex); //Nodes and blocks creation, blocks linkage for (iNum = 0; iNum < method.Count; iNum++) { while (iNum == (int)blockEnds.Peek()) { currentBlock = currentBlock.Parent; blockEnds.Pop(); } firstBlock = null; lastBlock = null; Node thisBlock = null; while (iNum == nextBlockStart) { Block currentBlockOld = currentBlock; switch (nextBlockType) { case BlockType.Try: currentBlock = new ProtectedBlock(); break; case BlockType.Catch: currentBlock = new CatchBlock(nextCatchBlockType); break; case BlockType.Finally: currentBlock = new FinallyBlock(false); break; case BlockType.Filter: currentBlock = new FilterBlock(); break; case BlockType.FilteredCatch: currentBlock = new UserFilteredBlock(); break; } currentBlock.setParent(currentBlockOld); blockEnds.Push(nextBlockEnd); if (thisBlock == null) { thisBlock = firstBlock = currentBlock; } else { thisBlock.Next = currentBlock; thisBlock = currentBlock; } switch (nextBlockType) { case BlockType.Try: tryBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock); break; case BlockType.Filter: filterBlocks.Add(new Segment(nextBlockStart, nextBlockEnd), thisBlock); break; case BlockType.Finally: case BlockType.Catch: { Segment tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex); ProtectedBlock tryBlock = tryBlocks[tryBlockKey] as ProtectedBlock; tryBlock.AddHandler(thisBlock as EHBlock); } break; case BlockType.FilteredCatch: { Segment tryBlockKey = FindProtectedBlock(method.EHClauses, nextBlockIndex); ProtectedBlock tryBlock = tryBlocks[tryBlockKey] as ProtectedBlock; tryBlock.AddHandler(thisBlock as EHBlock); Segment filterKey = FindFilterBlock(method.EHClauses, nextBlockIndex); FilterBlock filterBlock = filterBlocks[filterKey] as FilterBlock; (thisBlock as UserFilteredBlock).Filter = filterBlock; } break; } FindNextBlockStart(method.EHClauses, out nextBlockType, ref nextBlockStart, ref nextBlockEnd, out nextCatchBlockType, out nextBlockIndex); } lastBlock = thisBlock; Instruction i = method[iNum]; switch (i.Code) { case InstructionCode.NEG: case InstructionCode.NOT: { head = tail = new UnaryOp(UnaryOpFromCode(i.Code)); /*!*/ head.setParent(currentBlock); } break; case InstructionCode.ADD: case InstructionCode.AND: case InstructionCode.CEQ: case InstructionCode.CGT: case InstructionCode.CLT: case InstructionCode.DIV: case InstructionCode.MUL: case InstructionCode.OR: case InstructionCode.REM: case InstructionCode.SHL: case InstructionCode.SHR: case InstructionCode.SUB: case InstructionCode.XOR: { head = tail = new BinaryOp(BinaryOpFromCode(i.Code), i.OverflowFlag, i.UnsignedFlag); /*!*/ head.setParent(currentBlock); } break; case InstructionCode.LDC: head = tail = new LoadConst(i.Param); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDARG: head = tail = new LoadVar(args[(int)(i.Param)]); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDLOC: head = tail = new LoadVar(locals[(int)(i.Param)]); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDARGA: head = tail = new LoadVarAddr(args[(int)(i.Param)]); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDLOCA: head = tail = new LoadVarAddr(locals[(int)(i.Param)]); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDIND: head = tail = new LoadIndirect(i.TypeBySuffixOrParam()); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDFLD: { FieldInfo field = i.Param as FieldInfo; if (field.IsStatic) { head = new RemoveStackTop(); /*!*/ head.setParent(currentBlock); //remove the object instance when accessing the static field with LDFLD tail = new LoadField(field); /*!*/ tail.setParent(currentBlock); head.Next = tail; } else { head = tail = new LoadField(field); /*!*/ head.setParent(currentBlock); } } break; case InstructionCode.LDFLDA: { FieldInfo field = i.Param as FieldInfo; if (field.IsStatic) { head = new RemoveStackTop(); /*!*/ head.setParent(currentBlock); tail = new LoadFieldAddr(field); /*!*/ tail.setParent(currentBlock); head.Next = tail; } else { head = tail = new LoadFieldAddr(field); /*!*/ head.setParent(currentBlock); } } break; case InstructionCode.LDSFLD: head = tail = new LoadField(i.Param as FieldInfo); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDSFLDA: head = tail = new LoadFieldAddr(i.Param as FieldInfo); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDELEM: head = tail = new LoadElement(i.TypeBySuffixOrParam()); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDELEMA: head = tail = new LoadElementAddr(i.TypeBySuffixOrParam()); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDOBJ: head = tail = new LoadIndirect(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.SIZEOF: head = tail = new LoadSizeOfValue(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDLEN: head = tail = new LoadLength(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDTOKEN: if (i.Param is Type) { head = tail = new LoadConst((i.Param as Type).TypeHandle); } else if (i.Param is MethodBase) { head = tail = new LoadConst((i.Param as MethodBase).MethodHandle); } else if (i.Param is FieldInfo) { head = tail = new LoadConst((i.Param as FieldInfo).FieldHandle); } else { throw new ConvertionException(); } /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDNULL: head = tail = new LoadConst(null); /*!*/ head.setParent(currentBlock); break; case InstructionCode.LDSTR: head = tail = new LoadConst(i.Param); /*!*/ head.setParent(currentBlock); break; case InstructionCode.STARG: head = tail = new StoreVar(args[(int)(i.Param)]); /*!*/ head.setParent(currentBlock); break; case InstructionCode.STLOC: head = tail = new StoreVar(locals[(int)(i.Param)]); /*!*/ head.setParent(currentBlock); break; case InstructionCode.STIND: head = tail = new StoreIndirect(i.TypeBySuffixOrParam()); /*!*/ head.setParent(currentBlock); break; case InstructionCode.STFLD: { FieldInfo field = i.Param as FieldInfo; if (field.IsStatic) { head = new StoreField(field); /*!*/ head.setParent(currentBlock); tail = new RemoveStackTop(); /*!*/ tail.setParent(currentBlock); head.Next = tail; } else { head = tail = new StoreField(i.Param as FieldInfo); /*!*/ head.setParent(currentBlock); } } break; case InstructionCode.STSFLD: head = tail = new StoreField(i.Param as FieldInfo); /*!*/ head.setParent(currentBlock); break; case InstructionCode.STELEM: head = tail = new StoreElement(i.TypeBySuffixOrParam()); /*!*/ head.setParent(currentBlock); break; case InstructionCode.STOBJ: head = tail = new StoreIndirect(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.CPOBJ: head = new LoadIndirect(i.Param as Type); /*!*/ head.setParent(currentBlock); tail = new StoreIndirect(i.Param as Type); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.DUP: head = tail = new DuplicateStackTop(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.CALL: head = tail = new CallMethod(i.Param as MethodBase, false, i.HasTail); /*!*/ head.setParent(currentBlock); break; case InstructionCode.CALLVIRT: MethodInfo callee = i.Param as MethodInfo; head = tail = new CallMethod(callee, callee.IsVirtual, i.HasTail); /*!*/ head.setParent(currentBlock); break; case InstructionCode.NEWOBJ: { ConstructorInfo ctor = i.Param as ConstructorInfo; if (Verifier.IsDelegate(ctor.DeclaringType)) { if (Verifier.IsInstanceDispatch(method, iNum)) { heads[iNum - 1] = tails[iNum - 1] = null; head = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, false); } else if (Verifier.IsVirtualDispatch(method, iNum)) { heads[iNum - 2] = tails[iNum - 2] = null; heads[iNum - 1] = tails[iNum - 1] = null; head = tail = new CreateDelegate(ctor, method[iNum - 1].Param as MethodInfo, true); } } else { head = tail = new NewObject(ctor); } /*!*/ head.setParent(currentBlock); } break; case InstructionCode.NEWARR: head = tail = new NewArray(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.INITOBJ: head = tail = new InitValue(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.ISINST: head = tail = new CastClass(i.Param as Type, false); /*!*/ head.setParent(currentBlock); break; case InstructionCode.CASTCLASS: head = tail = new CastClass(i.Param as Type, true); /*!*/ head.setParent(currentBlock); break; case InstructionCode.BOX: head = tail = new BoxValue(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.UNBOX: head = tail = new UnboxValue(i.Param as Type); /*!*/ head.setParent(currentBlock); break; case InstructionCode.CONV: head = tail = new ConvertValue(i.TypeBySuffixOrParam(), i.OverflowFlag, i.UnsignedFlag); /*!*/ head.setParent(currentBlock); break; case InstructionCode.POP: head = tail = new RemoveStackTop(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.BEQ: head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false); /*!*/ head.setParent(currentBlock); tail = new Branch(); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.BNE: head = new BinaryOp(BinaryOp.ArithOp.CEQ, false, false); /*!*/ head.setParent(currentBlock); tail = new Branch(); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.BGE: if (TypeFixer.IsFloatOrCompatible(i.Stack.Top())) { head = new BinaryOp(BinaryOp.ArithOp.CLT, false, !i.UnsignedFlag); } else { head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag); } tail = new Branch(); /*!*/ head.setParent(currentBlock); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.BGT: head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag); tail = new Branch(); /*!*/ head.setParent(currentBlock); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.BLE: if (TypeFixer.IsFloatOrCompatible(i.Stack.Top())) { head = new BinaryOp(BinaryOp.ArithOp.CGT, false, !i.UnsignedFlag); } else { head = new BinaryOp(BinaryOp.ArithOp.CGT, false, i.UnsignedFlag); } tail = new Branch(); /*!*/ head.setParent(currentBlock); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.BLT: head = new BinaryOp(BinaryOp.ArithOp.CLT, false, i.UnsignedFlag); tail = new Branch(); /*!*/ head.setParent(currentBlock); /*!*/ tail.setParent(currentBlock); head.Next = tail; break; case InstructionCode.BRTRUE: head = tail = new Branch(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.BRFALSE: head = tail = new Branch(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.SWITCH: head = tail = new Switch((i.Param as int[]).Length); /*!*/ head.setParent(currentBlock); break; case InstructionCode.BR: case InstructionCode.NOP: case InstructionCode.BREAK: case InstructionCode.LDFTN: // Expecting further delegate construction... case InstructionCode.LDVIRTFTN: // head = tail = new DummyNode(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.THROW: head = tail = new ThrowException(); /*!*/ head.setParent(currentBlock); break; case InstructionCode.RET: case InstructionCode.ENDFINALLY: case InstructionCode.ENDFILTER: case InstructionCode.LEAVE: head = tail = new Leave(); /*!*/ head.setParent(currentBlock); break; default: throw new ConvertionException(); } if (head != null) { head.Options["StackTypes"] = i.Stack.Clone() as StackTypes; } if (head != tail) //=> head :: BinaryOp, tail :: Branch //|| head :: LoadIndirect, tail :: StoreIndirect { if (head is BinaryOp && tail is Branch) { StackTypes stack = i.Stack.Clone() as StackTypes; stack.Pop(); stack.Pop(); stack.Push(typeof(int)); tail.Options["StackTypes"] = stack; } else if (head is LoadIndirect && tail is StoreIndirect) { StackTypes stack = i.Stack.Clone() as StackTypes; TypeEx type = stack.Pop(); //type == S& stack.Push(type.type.GetElementType()); tail.Options["StackTypes"] = stack; } } if (firstBlock != null) { lastBlock.Next = head; for (Node n = firstBlock; n != head; n = n.Next) { n.Options["StackTypes"] = i.Stack.Clone() as StackTypes; } head = firstBlock; if (tail == null) { tail = lastBlock; //This may occure what the NOP instruction starts some block } } heads[iNum] = head; tails[iNum] = tail; } //for mainBlock.Next = heads[0]; //Control flow linkage for (iNum = 0; iNum < method.Count; iNum++) { if (heads[iNum] == null) { throw new ConvertionException(); //impossible :) } Instruction i = method[iNum]; switch (i.Code) { case InstructionCode.BR: case InstructionCode.LEAVE: tails[iNum].Next = heads[(int)i.Param]; break; case InstructionCode.RET: case InstructionCode.ENDFINALLY: case InstructionCode.ENDFILTER: case InstructionCode.THROW: case InstructionCode.RETHROW: break; case InstructionCode.BRFALSE: //false case InstructionCode.BGE: //false case InstructionCode.BLE: //false case InstructionCode.BNE: //false tails[iNum].Next = heads[(int)i.Param]; (tails[iNum] as Branch).Alt = heads[iNum + 1]; break; case InstructionCode.BRTRUE: //true case InstructionCode.BEQ: //true case InstructionCode.BGT: //true case InstructionCode.BLT: //true tails[iNum].Next = heads[iNum + 1]; (tails[iNum] as Branch).Alt = heads[(int)i.Param]; break; case InstructionCode.SWITCH: tails[iNum].Next = heads[iNum + 1]; Switch node = tails[iNum] as Switch; int[] alt = i.Param as int[]; for (int j = 0; j < node.Count; j++) { node[j] = heads[alt[j]]; } break; default: tails[iNum].Next = heads[iNum + 1]; break; } } //Removing DummyNodes for (iNum = 0; iNum < method.Count; iNum++) { if (heads[iNum] is DummyNode) { Node dummy = heads[iNum]; Node[] prev = new Node[dummy.PrevArray.Count]; for (int j = 0; j < prev.Length; j++) { prev[j] = dummy.PrevArray[j]; } for (int j = 0; j < prev.Length; j++) { prev[j].NextArray[prev[j].NextArray.IndexOf(dummy)] = dummy.Next; } dummy.RemoveFromGraph(); } } return(mainBlock); }
private bool DoIsBad(int index) { bool bad = false; do { LoadArg arg = m_info.Instructions[index] as LoadArg; if (arg != null && arg.Arg >= 1) { Log.DebugLine(this, "arg: {0}", arg.Arg); ParameterDefinition p = m_info.Method.Parameters[arg.Arg - 1]; Log.DebugLine(this, "param {0} is of type {1}", arg.Arg, p.ParameterType.FullName); if (DoIsBad(p.ParameterType)) { bad = true; } break; } LoadLocal local = m_info.Instructions[index] as LoadLocal; if (local != null) { Log.DebugLine(this, "local: {0}", local.Variable); TypeReference type = m_info.Method.Body.Variables[local.Variable].VariableType; Log.DebugLine(this, "local {0} is of type {1}", local.Variable, type.FullName); if (DoIsBad(type)) { bad = true; } break; } LoadField field = m_info.Instructions[index] as LoadField; if (field != null) { Log.DebugLine(this, "field: {0}", field.Field.Name); TypeReference type = field.Field.FieldType; Log.DebugLine(this, "field {0} is of type {1}", field.Field.Name, type.FullName); if (DoIsBad(type)) { bad = true; } break; } LoadStaticField sfield = m_info.Instructions[index] as LoadStaticField; if (sfield != null) { Log.DebugLine(this, "static field: {0}", sfield.Field.Name); TypeReference type = sfield.Field.FieldType; Log.DebugLine(this, "static field {0} is of type {1}", sfield.Field.Name, type.FullName); if (DoIsBad(type)) { bad = true; } break; } }while (false); return(bad); }
public void WriteLoadField(LoadField s, ExpressionUsage u) { WriteLoadField(s.Source, s.Field, s.Object, u); }
public void VisitLoadField(LoadField field) { DoAdd(field.Field.FieldType); }
public static bool IsIntOperand(MethodInfo info, int index, int nth) { bool isInt = false; int i = info.Tracker.GetStackIndex(index, nth); if (i >= 0) { do { LoadArg arg = info.Instructions[i] as LoadArg; if (arg != null && arg.Arg >= 1) { ParameterDefinition p = info.Method.Parameters[arg.Arg - 1]; if (p.ParameterType.FullName == "System.Int32") { isInt = true; } break; } LoadConstantInt constant = info.Instructions[i] as LoadConstantInt; if (constant != null) { Code code = constant.Untyped.OpCode.Code; switch (code) { case Code.Ldc_I4_M1: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: case Code.Ldc_I4_S: case Code.Ldc_I4: isInt = true; break; } break; } LoadField field = info.Instructions[i] as LoadField; if (field != null) { if (field.Field.FieldType.FullName == "System.Int32") { isInt = true; } break; } LoadLocal local = info.Instructions[i] as LoadLocal; if (local != null) { VariableDefinition v = info.Method.Body.Variables[local.Variable]; if (v.VariableType.FullName == "System.Int32") { isInt = true; } break; } LoadStaticField sfield = info.Instructions[i] as LoadStaticField; if (sfield != null) { if (sfield.Field.FieldType.FullName == "System.Int32") { isInt = true; } break; } }while (false); } return(isInt); }
private bool DoIsFloat(int index) { TypedInstruction instruction = m_info.Instructions[index]; TypeReference type = null; do { LoadArg arg = instruction as LoadArg; if (arg != null && arg.Arg >= 1) { type = m_info.Method.Parameters[arg.Arg - 1].ParameterType; break; } LoadLocal local = instruction as LoadLocal; if (local != null) { type = m_info.Method.Body.Variables[local.Variable].VariableType; break; } LoadField field = instruction as LoadField; if (field != null) { type = field.Field.FieldType; break; } LoadStaticField sfield = instruction as LoadStaticField; if (sfield != null) { type = sfield.Field.FieldType; break; } LoadConstantFloat cf = instruction as LoadConstantFloat; if (cf != null) { return(cf.Value != double.PositiveInfinity && cf.Value != double.NegativeInfinity); } BinaryOp binary = instruction as BinaryOp; if (binary != null) { int j = m_info.Tracker.GetStackIndex(instruction.Index, 0); int k = m_info.Tracker.GetStackIndex(instruction.Index, 1); if (j >= 0 && k >= 0) { if (DoIsFloat(j) && DoIsFloat(k)) { return(true); } } } if (instruction.Untyped.OpCode.Code == Code.Conv_R4 || instruction.Untyped.OpCode.Code == Code.Conv_R8 || instruction.Untyped.OpCode.Code == Code.Conv_R_Un) { return(true); } Call call = instruction as Call; if (call != null) { type = call.Target.ReturnType.ReturnType; break; } }while (false); return(type != null && (type.FullName == "System.Single" || type.FullName == "System.Double")); }
protected internal virtual void VisitLoadField(LoadField node, object data) { throw new NodeNotSupportedException(node); }