public ILInstrList Translate(IRInstrList instrs) { Instructions = new ILInstrList(); var i = 0; foreach (var instr in instrs) { ITranslationHandler handler; if (!handlers.TryGetValue(instr.OpCode, out handler)) { throw new NotSupportedException(instr.OpCode.ToString()); } try { handler.Translate(instr, this); } catch (Exception ex) { throw new Exception(string.Format("Failed to translate ir {0}.", instr.ILAST), ex); } while (i < Instructions.Count) { Instructions[i].IR = instr; i++; } } var ret = Instructions; Instructions = null; return(ret); }
private void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILTransformer tr) { if (instr.Operand is ILBlockTarget) { var target = (ILBlockTarget)instr.Operand; if (target.Target == trampoline) { target.Target = newTrampoline; } } else if (instr.IR == null) { return; } if (instr.IR.Annotation == SMCBlock.CounterInit && instr.OpCode == ILOpCode.PUSHI_DWORD) { var imm = (ILImmediate)instr.Operand; if ((int)imm.Value == 0x0f000001) { newTrampoline.CounterOperand = imm; } } else if (instr.IR.Annotation == SMCBlock.EncryptionKey && instr.OpCode == ILOpCode.PUSHI_DWORD) { var imm = (ILImmediate)instr.Operand; if ((int)imm.Value == 0x0f000002) { imm.Value = (int)newTrampoline.Key; } } else if (instr.IR.Annotation == SMCBlock.AddressPart1 && instr.OpCode == ILOpCode.PUSHI_DWORD && instr.Operand is ILBlockTarget) { var target = (ILBlockTarget)instr.Operand; var relBase = new ILInstruction(ILOpCode.PUSHR_QWORD, ILRegister.IP, instr); instr.OpCode = ILOpCode.PUSHI_DWORD; instr.Operand = new SMCBlockRef(target, relBase, (uint)adrKey); instrs.Replace(index, new[] { relBase, instr, new ILInstruction(ILOpCode.ADD_QWORD, null, instr) }); } else if (instr.IR.Annotation == SMCBlock.AddressPart2 && instr.OpCode == ILOpCode.PUSHI_DWORD) { var imm = (ILImmediate)instr.Operand; if ((int)imm.Value == 0x0f000003) { imm.Value = adrKey; } } }
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--; }
private void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILTransformer tr) { if (instr.Operand is ILRegister) { var reg = ((ILRegister)instr.Operand).Register; if (reg.IsGPR()) { methodInfo.UsedRegister.Add(reg); } } }
private void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILTransformer tr) { if (instr.OpCode == ILOpCode.__ENTRY) { instrs.RemoveAt(index); index--; } else if (instr.OpCode == ILOpCode.__EXIT) { instrs[index] = new ILInstruction(ILOpCode.RET, null, instr); } }
private void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILPostTransformer tr) { if (!(instr.Operand is ILRelReference rel)) { return; } if (!(rel.Target is ILMethodTarget methodRef)) { return; } methodRef.Resolve(tr.Runtime); }
void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILTransformer tr) { if (instr.OpCode == ILOpCode.PUSHI_DWORD && instr.Operand is IHasOffset) { var relBase = new ILInstruction(ILOpCode.PUSHR_QWORD, ILRegister.IP, instr); instr.OpCode = ILOpCode.PUSHI_DWORD; instr.Operand = new ILRelReference((IHasOffset)instr.Operand, relBase); instrs.Replace(index, new[] { relBase, instr, new ILInstruction(ILOpCode.ADD_QWORD, null, instr) }); } }
private void VisitInstr(ILInstrList instrs, ILInstruction instr, ref int index, ILPostTransformer tr) { var rel = instr.Operand as ILRelReference; if (rel == null) { return; } var methodRef = rel.Target as ILMethodTarget; if (methodRef == null) { return; } methodRef.Resolve(tr.Runtime); }
public SMCBlock(int id, ILInstrList content) : base(id, content) { }
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--; }