示例#1
0
        private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            switch (instr.OpCode)
            {
            case IROpCode.__NOT:
                instrs.Replace(index, new[]
                {
                    new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr)
                });
                break;

            case IROpCode.__AND:
            {
                IRVariable tmp = tr.Context.AllocateVRegister(instr.Operand2.Type);
                instrs.Replace(index, new[]
                    {
                        new IRInstruction(IROpCode.MOV, tmp, instr.Operand2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr),
                        new IRInstruction(IROpCode.NOR, tmp, tmp, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, tmp, instr)
                    });
                break;
            }

            case IROpCode.__OR:
                instrs.Replace(index, new[]
                {
                    new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand2, instr),
                    new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr)
                });
                break;

            case IROpCode.__XOR:
            {
                IRVariable tmp1 = tr.Context.AllocateVRegister(instr.Operand2.Type);
                IRVariable tmp2 = tr.Context.AllocateVRegister(instr.Operand2.Type);
                instrs.Replace(index, new[]
                    {
                        new IRInstruction(IROpCode.MOV, tmp1, instr.Operand1, instr),
                        new IRInstruction(IROpCode.NOR, tmp1, instr.Operand2, instr),
                        new IRInstruction(IROpCode.MOV, tmp2, instr.Operand2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr),
                        new IRInstruction(IROpCode.NOR, tmp2, tmp2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, tmp2, instr),
                        new IRInstruction(IROpCode.NOR, instr.Operand1, tmp1, instr)
                    });
                break;
            }
            }
        }
        // Direct call
        private void ProcessDCall(IRInstrList instrs, IRInstruction instr, int index, IRTransformer tr, MethodDef method)
        {
            var retVar   = (IRVariable)instr.Operand2;
            var callinfo = (InstrCallInfo)instr.Annotation;

            callinfo.Method = method; // Ensure it's resolved

            var callInstrs = new List <IRInstruction>();

            callInstrs.Add(new IRInstruction(IROpCode.CALL, new IRMetaTarget(method)
            {
                LateResolve = true
            })
            {
                Annotation = instr.Annotation,
                ILAST      = instr.ILAST
            });
            if (retVar != null)
            {
                callInstrs.Add(new IRInstruction(IROpCode.MOV, retVar, new IRRegister(DarksVMRegisters.R0, retVar.Type))
                {
                    Annotation = instr.Annotation,
                    ILAST      = instr.ILAST
                });
            }
            int stackAdjust = -callinfo.Arguments.Length;

            callInstrs.Add(new IRInstruction(IROpCode.ADD, IRRegister.SP, IRConstant.FromI4(stackAdjust))
            {
                Annotation = instr.Annotation,
                ILAST      = instr.ILAST
            });

            instrs.Replace(index, callInstrs);
        }
 void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
 {
     if (instr.OpCode == IROpCode.__GETF)
     {
         instrs.Replace(index, new[] {
             new IRInstruction(IROpCode.MOV, instr.Operand1, IRRegister.FL, instr),
             new IRInstruction(IROpCode.__AND, instr.Operand1, instr.Operand2, instr)
         });
     }
     else if (instr.OpCode == IROpCode.__SETF)
     {
         instrs.Replace(index, new[] {
             new IRInstruction(IROpCode.__OR, IRRegister.FL, instr.Operand1, instr)
         });
     }
 }
        // External call
        private void ProcessECall(IRInstrList instrs, IRInstruction instr, int index, IRTransformer tr)
        {
            var method = (IMethod)((IRMetaTarget)instr.Operand1).MetadataItem;
            var retVar = (IRVariable)instr.Operand2;

            uint          opCode        = 0;
            ITypeDefOrRef constrainType = ((InstrCallInfo)instr.Annotation).ConstrainType;

            if (instr.OpCode == IROpCode.__CALL)
            {
                opCode = tr.VM.Runtime.VCallOps.ECALL_CALL;
            }
            else if (instr.OpCode == IROpCode.__CALLVIRT)
            {
                if (constrainType != null)
                {
                    opCode = tr.VM.Runtime.VCallOps.ECALL_CALLVIRT_CONSTRAINED;
                }
                else
                {
                    opCode = tr.VM.Runtime.VCallOps.ECALL_CALLVIRT;
                }
            }
            else if (instr.OpCode == IROpCode.__NEWOBJ)
            {
                opCode = tr.VM.Runtime.VCallOps.ECALL_NEWOBJ;
            }

            int methodId   = (int)(tr.VM.Data.GetId(method) | (opCode << 30));
            int ecallId    = tr.VM.Runtime.VMCall.ECALL;
            var callInstrs = new List <IRInstruction>();

            if (constrainType != null)
            {
                callInstrs.Add(new IRInstruction(IROpCode.PUSH)
                {
                    Operand1   = IRConstant.FromI4((int)tr.VM.Data.GetId(constrainType)),
                    Annotation = instr.Annotation,
                    ILAST      = instr.ILAST
                });
            }
            callInstrs.Add(new IRInstruction(IROpCode.VCALL)
            {
                Operand1   = IRConstant.FromI4(ecallId),
                Operand2   = IRConstant.FromI4(methodId),
                Annotation = instr.Annotation,
                ILAST      = instr.ILAST
            });
            if (retVar != null)
            {
                callInstrs.Add(new IRInstruction(IROpCode.POP, retVar)
                {
                    Annotation = instr.Annotation,
                    ILAST      = instr.ILAST
                });
            }
            instrs.Replace(index, callInstrs);
        }
示例#5
0
 private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
 {
     if (instr.OpCode == IROpCode.__NOT)
     {
         instrs.Replace(index, new[]
         {
             new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr)
         });
     }
     else if (instr.OpCode == IROpCode.__AND)
     {
         var tmp = tr.Context.AllocateVRegister(instr.Operand2.Type);
         instrs.Replace(index, new[]
         {
             new IRInstruction(IROpCode.MOV, tmp, instr.Operand2, instr),
             new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr),
             new IRInstruction(IROpCode.NOR, tmp, tmp, instr),
             new IRInstruction(IROpCode.NOR, instr.Operand1, tmp, instr)
         });
     }
     else if (instr.OpCode == IROpCode.__OR)
     {
         instrs.Replace(index, new[]
         {
             new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand2, instr),
             new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr)
         });
     }
     else if (instr.OpCode == IROpCode.__XOR)
     {
         var tmp1 = tr.Context.AllocateVRegister(instr.Operand2.Type);
         var tmp2 = tr.Context.AllocateVRegister(instr.Operand2.Type);
         instrs.Replace(index, new[]
         {
             new IRInstruction(IROpCode.MOV, tmp1, instr.Operand1, instr),
             new IRInstruction(IROpCode.NOR, tmp1, instr.Operand2, instr),
             new IRInstruction(IROpCode.MOV, tmp2, instr.Operand2, instr),
             new IRInstruction(IROpCode.NOR, instr.Operand1, instr.Operand1, instr),
             new IRInstruction(IROpCode.NOR, tmp2, tmp2, instr),
             new IRInstruction(IROpCode.NOR, instr.Operand1, tmp2, instr),
             new IRInstruction(IROpCode.NOR, instr.Operand1, tmp1, instr)
         });
     }
 }
 void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
 {
     if (instr.OpCode == IROpCode.__ENTRY && !doneEntry)
     {
         instrs.Replace(index, new[] {
             instr,
             new IRInstruction(IROpCode.PUSH, IRRegister.BP),
             new IRInstruction(IROpCode.MOV, IRRegister.BP, IRRegister.SP),
             new IRInstruction(IROpCode.ADD, IRRegister.SP, IRConstant.FromI4(allocator.LocalSize))
         });
         doneEntry = true;
     }
     else if (instr.OpCode == IROpCode.__EXIT && !doneExit)
     {
         instrs.Replace(index, new[] {
             new IRInstruction(IROpCode.MOV, IRRegister.SP, IRRegister.BP),
             new IRInstruction(IROpCode.POP, IRRegister.BP),
             instr
         });
         doneExit = true;
     }
 }
示例#7
0
 void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
 {
     if (instr.OpCode == IROpCode.__LEA)
     {
         var source = (IRPointer)instr.Operand2;
         var target = instr.Operand1;
         Debug.Assert(source.Register == IRRegister.BP);
         instrs.Replace(index, new[] {
             new IRInstruction(IROpCode.MOV, target, IRRegister.BP, instr),
             new IRInstruction(IROpCode.ADD, target, IRConstant.FromI4(source.Offset), instr)
         });
     }
 }
示例#8
0
 void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
 {
     if (instr.OpCode == IROpCode.RET)
     {
         instrs.Replace(index, new[] {
             new IRInstruction(IROpCode.JMP, new IRBlockTarget(epilog))
         });
         if (!tr.Block.Targets.Contains(epilog))
         {
             tr.Block.Targets.Add(epilog);
             epilog.Sources.Add(tr.Block);
         }
     }
 }
示例#9
0
        private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            if (instr.OpCode != IROpCode.__LEAVE)
            {
                return;
            }

            var targetScopes = tr.RootScope.SearchBlock(((IRBlockTarget)instr.Operand1).Target);

            var escapeTarget = FindCommonAncestor(thisScopes, targetScopes);
            var leaveInstrs  = new List <IRInstruction>();

            for (var i = thisScopes.Length - 1; i >= 0; i--)
            {
                if (thisScopes[i] == escapeTarget)
                {
                    break;
                }
                if (thisScopes[i].Type != ScopeType.Try)
                {
                    continue;
                }

                IBasicBlock handler = null, filter = null;
                SearchForHandlers(tr.RootScope, thisScopes[i].ExceptionHandler, ref handler, ref filter);
                if (handler == null)
                {
                    throw new InvalidProgramException();
                }

                leaveInstrs.Add(new IRInstruction(IROpCode.LEAVE, new IRBlockTarget(handler))
                {
                    Annotation = new EHInfo(thisScopes[i].ExceptionHandler)
                });
            }
            instr.OpCode = IROpCode.JMP;
            leaveInstrs.Add(instr);
            instrs.Replace(index, leaveInstrs);
        }
        private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            if (instr.OpCode == IROpCode.__ENTRY && !this.done)
            {
                var init = new List <IRInstruction>();
                init.Add(instr);
                foreach (dnlib.DotNet.Emit.Local local in tr.Context.Method.Body.Variables)
                {
                    if (local.Type.IsValueType && !local.Type.IsPrimitive)
                    {
                        IRVariable adr = tr.Context.AllocateVRegister(ASTType.ByRef);
                        init.Add(new IRInstruction(IROpCode.__LEA, adr, tr.Context.ResolveLocal(local)));

                        int typeId  = (int)tr.VM.Data.GetId(local.Type.RemovePinnedAndModifiers().ToTypeDefOrRef());
                        int ecallId = tr.VM.Runtime.VMCall.INITOBJ;
                        init.Add(new IRInstruction(IROpCode.PUSH, adr));
                        init.Add(new IRInstruction(IROpCode.VCALL, IRConstant.FromI4(ecallId), IRConstant.FromI4(typeId)));
                    }
                }
                instrs.Replace(index, init);
                this.done = true;
            }
        }