public static IType GetInstType(ILInstruction inst, IType typeHint = null) { if (inst.MatchCastClass(out ILInstruction arg, out IType type)) { return(type); } var call = inst as CallInstruction; if (call != null) { return(call.Method.ReturnType); } if (inst.MatchLdLoc(out ILVariable var)) { return(GetVariableType(var)); } if (inst.MatchLdNull()) { return(null); } if (inst.MatchLdStr(out string xx)) { // we don't handle string literals. Should be replaced finally return(null); } if (inst.MatchLdObj(out var target, out var fldType)) { if (target.MatchLdsFlda(out var sfield)) { return(sfield.Type); } if (target.MatchLdFlda(out var target2, out var field)) { return(field.Type); } } if (inst.MatchLdLoca(out var v)) { return(new PointerType(v.Type)); } if (inst.MatchLdFlda(out var target3, out var field2)) { return(new PointerType(field2.Type)); } if (inst.MatchLdsFlda(out var field4)) { return(new PointerType(field4.Type)); } if (inst.MatchLdObj(out var target4, out var type3)) { return(type3); } if (inst.MatchLdTypeToken(out var type4)) { return(null); } if (inst is Conv c) { // todo handle integer types return(null); } // todo field, etc Debug.Assert(false, "Implement this type: " + inst.GetType().Name); return(null); }
protected sealed override void Default(ILInstruction inst) { DebugStartPoint(inst); // This method assumes normal control flow and no branches. if ((inst.DirectFlags & flagsRequiringManualImpl) != 0) { throw new NotImplementedException(GetType().Name + " is missing implementation for " + inst.GetType().Name); } // Since this instruction has normal control flow, we can evaluate our children left-to-right. foreach (var child in inst.Children) { child.AcceptVisitor(this); Debug.Assert(state.IsBottom || !child.HasFlag(InstructionFlags.EndPointUnreachable), "Unreachable code must be in the bottom state."); } DebugEndPoint(inst); }
public void Interpret(AppDomain appDomain, ILMethodDefinition method, params object[] arguments) { object[] locals = new object[20]; for (int i = 0; i < method.Instructions.Length; i++) { ILInstruction instruction = method.Instructions[i]; switch (instruction) { case NopInstruction nop: break; //case CallInstruction call: // ILMethodDefinition callMethod = appDomain.Loader.ReadMethod(call.Target); // object[] args = new object[callMethod.ArgumentsCount]; // for (int j = 0; j < args.Length; j++) // { // args[j] = this.Stack.Dequeue(); // } // this.Interpret(appDomain, callMethod, args); // break; case PushInt32Instruction push: this.Stack.Enqueue(push.Value); break; case PushInt64Instruction push: this.Stack.Enqueue(push.Value); break; case StoreLocalInstruction store: locals[store.Index] = this.Stack.Dequeue(); break; case BranchInstruction branch: i = method.ILOffsets[branch.ToIndex] - 1; break; case LoadLocalInstruction load: this.Stack.Enqueue(locals[load.Index]); break; case ReturnInstruction @return: return; case LoadArgumentInstruction argument: this.Stack.Enqueue(arguments[argument.Index]); break; case BranchFalseInstruction branch: object value = this.Stack.Dequeue(); if (value is int number && number == 0) { i = method.ILOffsets[branch.ToIndex] - 1; } break; case AddInstruction add: { int num = (int)this.Stack.Dequeue(); int num2 = (int)this.Stack.Dequeue(); this.Stack.Enqueue(num + num2); break; } case SubtractInstruction sub: { int num = (int)this.Stack.Dequeue(); int num2 = (int)this.Stack.Dequeue(); this.Stack.Enqueue(num - num2); break; } case BranchGreaterInstruction greater: { break; } default: throw new InvalidOperationException("Wtf is tihs: " + instruction.GetType()); } } throw new InvalidOperationException("not like tihs"); }