private List <CilSigArg> CompleteSigArgs(CilInstructionMethod instruction, CilMethod method) { var isInstanceCall = instruction.CallConv.IsInstance; var instanceSigArg = new CilSigArg { Id = ".this", Type = instruction.TypeSpec.GetCilType(_program) }; var result = isInstanceCall ? (new List <CilSigArg> { instanceSigArg }).Concat(instruction.SigArgs).ToList() : instruction.SigArgs; var start = isInstanceCall ? 1 : 0; for (int i = start; i < result.Count; i++) { result[i].Id = isInstanceCall ? method.Arguments[i - 1].Id : method.Arguments[i].Id; } return(result); }
private object CallExternalMethod(CilInstructionMethod instruction, IValue instanceVal, IValue[] argsVal, object instanceObj) { var instance = instanceObj != null ? instanceObj : instruction.CallConv.IsInstance ? instanceVal.AsRuntime(instruction.TypeSpec.GetCilType(_program), ManagedMemory, _program) : null; var args = argsVal.Zip(instruction.SigArgs, (argVal, sigArg) => argVal.AsRuntime(sigArg.Type, ManagedMemory, _program)).ToArray(); var callerConfig = new ExternalMethodCallerConfig { AssemblyName = instruction.TypeSpec.ClassName?.AssemblyName, ClassName = instruction.TypeSpec.ClassName?.ClassName, ExternalType = instruction.TypeSpec.ClassName == null?instruction.TypeSpec.GetCilType(_program).GetRuntimeType(_program) : null, MethodName = instruction.MethodName, Arguments = args, Types = instruction.SigArgs.Select(sa => sa.Type.GetRuntimeType(_program)).ToArray(), Instance = instance, CallConstructor = instruction.MethodName == ".ctor", IsInstanceCall = instruction.CallConv.IsInstance }; var result = ExternalMetodCaller.Call(callerConfig); return(result); }
private List <IValue> CompleteArgs(CilInstructionMethod instruction, List <IValue> args, IValue instanceVal) { var isInstanceCall = instruction.CallConv.IsInstance; var result = isInstanceCall ? (new List <IValue> { instanceVal }).Concat(args).ToList() : args; return(result); }
private List <IValue> PopMethodArgs(CilInstructionMethod instruction) { var methodArgs = new List <IValue>(); for (int i = 0; i < instruction.SigArgs.Count; i++) { var ind = instruction.SigArgs.Count - i - 1; ControlState.EvaluationStack.PopValue(_program, instruction.SigArgs[ind].Type, out var value); methodArgs.Add(value); } methodArgs.Reverse(); return(methodArgs); }
public void VisitInstructionMethod(CilInstructionMethod instruction) { if (instruction is CallInstruction callInstruction) { VisitCallInstruction(callInstruction); } else if (instruction is CallVirtualInstruction callVirtualInstruction) { VisitCallVirtualInstruction(callVirtualInstruction); } else if (instruction is NewObjectInstruction newObjectInstruction) { VisitNewObjectInstruction(newObjectInstruction); } else { throw new ArgumentException($"CIL instruction method cannot be recognized: '{instruction.ToString()}'."); } }
public override void Init(AstContext context, ParseTreeNode parseNode) { // _("call") var callChildren = AstChildren.Empty() .Add("call"); if (callChildren.PopulateWith(parseNode)) { Instruction = new CallInstruction(); return; } // _("callvirt") var callvirtChildren = AstChildren.Empty() .Add("callvirt"); if (callvirtChildren.PopulateWith(parseNode)) { Instruction = new CallVirtualInstruction(); return; } // _("newobj") var newobjChildren = AstChildren.Empty() .Add("newobj"); if (newobjChildren.PopulateWith(parseNode)) { Instruction = new NewObjectInstruction(); return; } throw new NotImplementedException(); }
private object GetRuntimeEmptyInstance(CilInstructionMethod instruction, List <IValue> methodArgs, bool isNewObject) { object emptyInstance = null; if (instruction.TypeSpec.Type != null && instruction.TypeSpec.Type is CilTypeArray cilTypeArray) { if (isNewObject) { var lengths = methodArgs.Cast <CilValueInt32>().Select(v => v.Value + 1).ToArray(); emptyInstance = Array.CreateInstance(cilTypeArray.ElementType.GetRuntimeType(_program), lengths); } else { throw new System.NotImplementedException(); } } else { var type = ReflectionHelper.GetExternalType(instruction.TypeSpec.ClassName); emptyInstance = FormatterServices.GetUninitializedObject(@type); } return(emptyInstance); }