public static void PopOperand(this ILTranslator tr, IIROperand operand) { if (operand is IRRegister) { var reg = ILRegister.LookupRegister(((IRRegister)operand).Register); tr.Instructions.Add(new ILInstruction(ILOpCode.POP, reg)); } else if (operand is IRPointer pointer) { var reg = ILRegister.LookupRegister(pointer.Register.Register); tr.Instructions.Add(new ILInstruction(pointer.Register.GetPUSHR(), reg)); if (pointer.Offset != 0) { tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, ILImmediate.Create(pointer.Offset, ASTType.I4))); if (pointer.Register.Type == ASTType.I4) { tr.Instructions.Add(new ILInstruction(ILOpCode.ADD_DWORD)); } else { tr.Instructions.Add(new ILInstruction(ILOpCode.ADD_QWORD)); } } tr.Instructions.Add(new ILInstruction(pointer.GetSIND())); } else { throw new NotSupportedException(); } }
private void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILPostTransformer tr) { if (instr.OpCode != ILOpCode.__BEGINCALL && instr.OpCode != ILOpCode.__ENDCALL) { return; } var callInfo = (InstrCallInfo)instr.Annotation; if (callInfo.IsECall) { instrs.RemoveAt(index); index--; return; } var saving = new HashSet <DarksVMRegisters>(saveRegs); var retVar = (IRVariable)callInfo.ReturnValue; // R0 = return register, need to save if retVar register is not R0 //Debug.Assert(!(retVar == null ^ (callInfo.ReturnRegister == null ^ callInfo.ReturnSlot == null))); if (retVar != null) { if (callInfo.ReturnSlot == null) { var retReg = callInfo.ReturnRegister.Register; saving.Remove(retReg); if (retReg != DarksVMRegisters.R0) { saving.Add(DarksVMRegisters.R0); } } else { saving.Add(DarksVMRegisters.R0); } } else { saving.Add(DarksVMRegisters.R0); } if (instr.OpCode == ILOpCode.__BEGINCALL) { instrs.Replace(index, saving .Select(reg => new ILInstruction(ILOpCode.PUSHR_OBJECT, ILRegister.LookupRegister(reg), instr))); } else { instrs.Replace(index, saving .Select(reg => new ILInstruction(ILOpCode.POP, ILRegister.LookupRegister(reg), instr)) .Reverse()); } index--; }
static void GenerateCLRBindingByAnalysis() { GenerateCLRBinding(); //用新的分析热更dll调用引用来生成绑定代码 ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain(); using (FileStream fs = new FileStream("Assets/Resources/Hotfix.dll.bytes", FileMode.Open, FileAccess.Read)) { domain.LoadAssembly(fs); //Crossbind Adapter is needed to generate the correct binding code ILRegister.InitILRuntime(domain); ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, "Assets/Scripts/ILBinding"); AssetDatabase.Refresh(); } }
public void Destroy() { ILRegister.DoDestroy(Domain); Domain = null; if (dllStream != null) { dllStream.Close(); dllStream = null; } if (pdbStream != null) { pdbStream.Close(); pdbStream = null; } }
static void GenerateCLRBindingByAnalysis() { //用新的分析热更dll调用引用来生成绑定代码 ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain(); using (FileStream fs = new FileStream(HotfixBuild.DllFullPath, FileMode.Open, FileAccess.Read)) { domain.LoadAssembly(fs); //Crossbind Adapter is needed to generate the correct binding code ILRegister.InitILRuntime(domain); CustomExportDefine customExportDefine = new CustomExportDefine(); ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, "Assets/Scripts/ILBinding/Binder", customExportDefine.valueTypeBinders, customExportDefine.delegateTypes, "UnityEngine_Debug_Binding" ); AssetDatabase.Refresh(); } }
public void Load(byte[] assBytes, byte[] pdbBytes) { Domain = new ILRuntime.Runtime.Enviorment.AppDomain(); dllStream = new MemoryStream(assBytes); if (pdbBytes != null) { pdbStream = new MemoryStream(pdbBytes); Domain.LoadAssembly(dllStream, pdbStream, new ILRuntime.Mono.Cecil.Pdb.PdbReaderProvider()); } else { Domain.LoadAssembly(dllStream); } #if ENABLE_PROFILER && (UNITY_EDITOR || UNITY_ANDROID || UNITY_IOS) //由于Unity的Profiler接口只允许在主线程使用,为了避免出异常,需要告诉ILRuntime主线程的线程ID才能正确将函数运行耗时报告给Profiler Domain.UnityMainThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId; #endif ILRegister.InitILRuntime(Domain); #if DEBUG Domain.DebugService.StartDebugService(56000); #endif Debug.Log($"当前使用的是ILRuntime模式"); }
public static void PushOperand(this ILTranslator tr, IIROperand operand) { if (operand is IRRegister) { var reg = ILRegister.LookupRegister(((IRRegister)operand).Register); tr.Instructions.Add(new ILInstruction(((IRRegister)operand).GetPUSHR(), reg)); } else if (operand is IRPointer pointer) { var reg = ILRegister.LookupRegister(pointer.Register.Register); tr.Instructions.Add(new ILInstruction(pointer.Register.GetPUSHR(), reg)); if (pointer.Offset != 0) { tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, ILImmediate.Create(pointer.Offset, ASTType.I4))); switch (pointer.Register.Type) { case ASTType.I4: tr.Instructions.Add(new ILInstruction(ILOpCode.ADD_DWORD)); break; default: tr.Instructions.Add(new ILInstruction(ILOpCode.ADD_QWORD)); break; } } tr.Instructions.Add(new ILInstruction(pointer.GetLIND())); } else if (operand is IRConstant constant) { if (constant.Value != null) { tr.Instructions.Add(new ILInstruction(constant.Type.Value.GetPUSHI(), ILImmediate.Create(constant.Value, constant.Type.Value))); } else { tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, ILImmediate.Create(0, ASTType.O))); } } else if (operand is IRMetaTarget) { var method = (MethodDef)((IRMetaTarget)operand).MetadataItem; tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, new ILMethodTarget(method))); } else if (operand is IRBlockTarget) { CFG.IBasicBlock target = ((IRBlockTarget)operand).Target; tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, new ILBlockTarget(target))); } else if (operand is IRJumpTable) { CFG.IBasicBlock[] targets = ((IRJumpTable)operand).Targets; tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, new ILJumpTable(targets))); } else if (operand is IRDataTarget) { RT.BinaryChunk target = ((IRDataTarget)operand).Target; tr.Instructions.Add(new ILInstruction(ILOpCode.PUSHI_DWORD, new ILDataTarget(target))); } else { throw new NotSupportedException(); } }
void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILPostTransformer tr) { if (instr.OpCode != ILOpCode.__BEGINCALL && instr.OpCode != ILOpCode.__ENDCALL) { return; } var callInfo = (InstrCallInfo)instr.Annotation; if (callInfo.IsECall) { instrs.RemoveAt(index); index--; return; } var saving = new HashSet <VMRegisters>(saveRegs); var retVar = (IRVariable)callInfo.ReturnValue; // R0 = return register, need to save if retVar register is not R07 if (retVar == null ^ (callInfo.ReturnRegister == null ^ callInfo.ReturnSlot == null)) { ConsoleColor c = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Debug.Assert [SaveRegistersTransform.cs] L36"); Console.WriteLine($"Method target->{callInfo.Method.FullName}"); Console.ForegroundColor = c; } if (retVar != null) { if (callInfo.ReturnSlot == null) { var retReg = callInfo.ReturnRegister.Register; saving.Remove(retReg); if (retReg != VMRegisters.R0) { saving.Add(VMRegisters.R0); } } else { saving.Add(VMRegisters.R0); } } else { saving.Add(VMRegisters.R0); } if (instr.OpCode == ILOpCode.__BEGINCALL) { instrs.Replace(index, saving .Select(reg => new ILInstruction(ILOpCode.PUSHR_OBJECT, ILRegister.LookupRegister(reg), instr))); } else { instrs.Replace(index, saving .Select(reg => new ILInstruction(ILOpCode.POP, ILRegister.LookupRegister(reg), instr)) .Reverse()); } index--; }