private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            switch (instr.OpCode)
            {
            case IROpCode.MOV:
            case IROpCode.NOR:
            case IROpCode.CMP:
            case IROpCode.ADD:
            case IROpCode.MUL:
            case IROpCode.DIV:
            case IROpCode.REM:
            case IROpCode.__OR:
            case IROpCode.__AND:
            case IROpCode.__XOR:
            case IROpCode.__GETF:
                break;

            default:
                return;
            }
            Debug.Assert(instr.Operand1 != null && instr.Operand2 != null);
            if (instr.Operand1 is IRConstant)
            {
                instr.Operand1 = PromoteConstant((IRConstant)instr.Operand1, instr.Operand2.Type);
            }
            if (instr.Operand2 is IRConstant)
            {
                instr.Operand2 = PromoteConstant((IRConstant)instr.Operand2, instr.Operand1.Type);
            }
        }
Beispiel #2
0
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand1);
            tr.PushOperand(instr.Operand2);
            var type = TypeInference.InferBinaryOp(instr.Operand1.Type, instr.Operand2.Type);

            switch (type)
            {
            case ASTType.I4:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_DWORD));
                break;

            case ASTType.I8:
            case ASTType.Ptr:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_QWORD));
                break;

            case ASTType.R4:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_R32));
                break;

            case ASTType.R8:
                tr.Instructions.Add(new ILInstruction(ILOpCode.REM_R64));
                break;

            default:
                throw new NotSupportedException();
            }
            tr.PopOperand(instr.Operand1);
        }
Beispiel #3
0
 public void Translate(IRInstruction instr, ILTranslator tr)
 {
     tr.Instructions.Add(new ILInstruction(ILOpCode.__ENDCALL)
     {
         Annotation = instr.Annotation
     });
 }
        // 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);
        }
        private static void ComputeInstrLiveness(IRInstruction instr, HashSet <IRVariable> live)
        {
            LiveFlags flags;

            if (!opCodeLiveness.TryGetValue(instr.OpCode, out flags))
            {
                flags = 0;
            }

            var op1 = instr.Operand1 as IRVariable;
            var op2 = instr.Operand2 as IRVariable;

            if ((flags & LiveFlags.KILL1) != 0 && op1 != null)
            {
                live.Remove(op1);
            }
            if ((flags & LiveFlags.KILL2) != 0 && op2 != null)
            {
                live.Remove(op2);
            }
            if ((flags & LiveFlags.GEN1) != 0 && op1 != null)
            {
                live.Add(op1);
            }
            if ((flags & LiveFlags.GEN2) != 0 && op2 != null)
            {
                live.Add(op2);
            }
        }
Beispiel #6
0
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand2);
            switch (instr.Operand1.Type)
            {
            case ASTType.I4:
                if (instr.Operand1 is IRVariable)
                {
                    var rawType = ((IRVariable)instr.Operand1).RawType.ElementType;
                    if (rawType == ElementType.I2)
                    {
                        tr.Instructions.Add(new ILInstruction(ILOpCode.SX_WORD));
                    }
                }
                tr.Instructions.Add(new ILInstruction(ILOpCode.SX_BYTE));
                break;

            case ASTType.I8:
                tr.Instructions.Add(new ILInstruction(ILOpCode.SX_DWORD));
                break;

            default:
                throw new NotSupportedException();
            }
            tr.PopOperand(instr.Operand1);
        }
        private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            if (instr.OpCode != IROpCode.__CALL && instr.OpCode != IROpCode.__CALLVIRT &&
                instr.OpCode != IROpCode.__NEWOBJ)
            {
                return;
            }

            MethodDef method   = ((IMethod)((IRMetaTarget)instr.Operand1).MetadataItem).ResolveMethodDef();
            var       callInfo = (InstrCallInfo)instr.Annotation;

            if (method == null ||
                method.Module != tr.Context.Method.Module || // TODO: cross-module direct call
                !tr.VM.Settings.IsVirtualized(method) ||
                instr.OpCode != IROpCode.__CALL)
            {
                callInfo.IsECall = true;
                this.ProcessECall(instrs, instr, index, tr);
            }
            else
            {
                callInfo.IsECall = false;
                this.ProcessDCall(instrs, instr, index, tr, method);
            }
        }
Beispiel #8
0
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand2);
            switch (instr.Operand2.Type)
            {
            case ASTType.R4:
                Debug.Assert(instr.Operand1.Type == ASTType.R8);
                tr.Instructions.Add(new ILInstruction(ILOpCode.FCONV_R32_R64));
                break;

            case ASTType.R8:
                Debug.Assert(instr.Operand1.Type == ASTType.R4);
                tr.Instructions.Add(new ILInstruction(ILOpCode.FCONV_R64_R32));
                break;

            default:
                Debug.Assert(instr.Operand2.Type == ASTType.I8);
                switch (instr.Operand1.Type)
                {
                case ASTType.R4:
                    tr.Instructions.Add(new ILInstruction(ILOpCode.FCONV_R32));
                    break;

                case ASTType.R8:
                    tr.Instructions.Add(new ILInstruction(ILOpCode.FCONV_R64));
                    break;

                default:
                    throw new NotSupportedException();
                }
                break;
            }
            tr.PopOperand(instr.Operand1);
        }
Beispiel #9
0
        IRInstruction ReadInstr(Node node)
        {
            var instr = new IRInstruction(IROpCode.NOP);

            for (int i = 0; i < node.Count; i++)
            {
                var child = node[i];
                if (child.Id == (int)IRConstants.OP_CODE)
                {
                    instr.OpCode = (IROpCode)Enum.Parse(typeof(IROpCode), ((Token)child[0]).Image);
                }
                else if (child.Id == (int)IRConstants.OPERAND)
                {
                    if (instr.Operand1 == null)
                    {
                        instr.Operand1 = ReadOperand(child);
                    }
                    else
                    {
                        instr.Operand2 = ReadOperand(child);
                    }
                }
            }
            if (instr.Operand1 is UnresolvedReference || instr.Operand2 is UnresolvedReference)
            {
                references.Add(instr);
            }
            return(instr);
        }
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand1);
            tr.PushOperand(instr.Operand2);

            if (instr.Operand1.Type == ASTType.O || instr.Operand2.Type == ASTType.O)
            {
                tr.Instructions.Add(new ILInstruction(ILOpCode.CMP));
            }

            else if (instr.Operand1.Type == ASTType.I8 || instr.Operand2.Type == ASTType.I8 ||
                     instr.Operand1.Type == ASTType.Ptr || instr.Operand2.Type == ASTType.Ptr)
            {
                tr.Instructions.Add(new ILInstruction(ILOpCode.CMP_QWORD));
            }

            else if (instr.Operand1.Type == ASTType.R8 || instr.Operand2.Type == ASTType.R8)
            {
                tr.Instructions.Add(new ILInstruction(ILOpCode.CMP_R64));
            }

            else if (instr.Operand1.Type == ASTType.R4 || instr.Operand2.Type == ASTType.R4)
            {
                tr.Instructions.Add(new ILInstruction(ILOpCode.CMP_R32));
            }

            else
            {
                tr.Instructions.Add(new ILInstruction(ILOpCode.CMP_DWORD));
            }
        }
Beispiel #11
0
 public IRMoveInstruction(IRInstruction pInstruction) : base(IROpcode.Move)
 {
     ILOffset     = pInstruction.ILOffset;
     IRIndex      = pInstruction.IRIndex;
     ParentMethod = pInstruction.ParentMethod;
     Sources.AddRange(pInstruction.Sources);
     Destination = pInstruction.Destination;
 }
Beispiel #12
0
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand2);
            tr.PushOperand(instr.Operand1);
            var rawType = ((PointerInfo)instr.Annotation).PointerType.ToTypeSig();

            tr.Instructions.Add(new ILInstruction(TranslationHelpers.GetSIND(instr.Operand2.Type, rawType)));
        }
 public void Translate(IRInstruction instr, ILTranslator tr)
 {
     tr.PushOperand(instr.Operand1);
     tr.Instructions.Add(new ILInstruction(ILOpCode.JMP)
     {
         Annotation = InstrAnnotation.JUMP
     });
 }
Beispiel #14
0
 public void Translate(IRInstruction instr, ILTranslator tr)
 {
     tr.PushOperand(instr.Operand1);
     tr.Instructions.Add(new ILInstruction(ILOpCode.LEAVE)
     {
         Annotation = instr.Annotation
     });
 }
        // 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);
        }
Beispiel #16
0
 public void Translate(IRInstruction instr, ILTranslator tr)
 {
     if (instr.Operand1 != null)
     {
         tr.PushOperand(instr.Operand1);
         tr.Instructions.Add(new ILInstruction(ILOpCode.POP, ILRegister.R0));
     }
     tr.Instructions.Add(new ILInstruction(ILOpCode.RET));
 }
Beispiel #17
0
 public void Translate(IRInstruction instr, ILTranslator tr)
 {
     if (instr.Operand2 != null)
     {
         tr.PushOperand(instr.Operand2);
     }
     tr.PushOperand(instr.Operand1);
     tr.Instructions.Add(new ILInstruction(ILOpCode.VCALL));
 }
Beispiel #18
0
 public IRMoveInstruction(IRInstruction pInstruction)
     : base(IROpcode.Move)
 {
     ILOffset = pInstruction.ILOffset;
     IRIndex = pInstruction.IRIndex;
     ParentMethod = pInstruction.ParentMethod;
     Sources.AddRange(pInstruction.Sources);
     Destination = pInstruction.Destination;
 }
Beispiel #19
0
        public static void Replace(this List <IRInstruction> list, int index, IEnumerable <IRInstruction> newItems)
        {
            IRInstruction instr = list[index];

            list.RemoveAt(index);
            foreach (IRInstruction i in newItems)
            {
                i.ILAST = instr.ILAST;
            }
            list.InsertRange(index, newItems);
        }
Beispiel #20
0
 public void Translate(IRInstruction instr, ILTranslator tr)
 {
     if (instr.Operand2 != null)
     {
         tr.PushOperand(instr.Operand2);
     }
     tr.PushOperand(instr.Operand1);
     tr.Instructions.Add(new ILInstruction(ILOpCode.TRY)
     {
         Annotation = instr.Annotation
     });
 }
Beispiel #21
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)
         });
     }
 }
Beispiel #22
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);
         }
     }
 }
Beispiel #23
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;
            }
            }
        }
		private static bool IsBaseCallInstruction(IRMethod pMethod, IRInstruction instr)
		{
			if (((IRCallInstruction)instr).Target.ParentType != pMethod.ParentType.BaseType)
			{
				int i43 = 0;
				i43++;
			}
			return
				instr.Sources.Count == 1 &&
				instr.Sources[0].Type == IRLinearizedLocationType.Parameter &&
				instr.Sources[0].Parameter.ParameterIndex == 0 &&
				((IRCallInstruction)instr).Target.ParentType == pMethod.ParentType.BaseType
			;
		}
        public static Dictionary <BasicBlock <IRInstrList>, BlockLiveness> ComputeLiveness(
            IList <BasicBlock <IRInstrList> > blocks)
        {
            var liveness    = new Dictionary <BasicBlock <IRInstrList>, BlockLiveness>();
            var entryBlocks = blocks.Where(block => block.Sources.Count == 0).ToList();
            var order       = new List <BasicBlock <IRInstrList> >();
            var visited     = new HashSet <BasicBlock <IRInstrList> >();

            foreach (BasicBlock <IRInstrList> entry in entryBlocks)
            {
                PostorderTraversal(entry, visited, block => order.Add(block));
            }

            bool worked = false;

            do
            {
                foreach (BasicBlock <IRInstrList> currentBlock in order)
                {
                    var blockLiveness = BlockLiveness.Empty();

                    foreach (BasicBlock <IRInstrList> successor in currentBlock.Targets)
                    {
                        if (!liveness.TryGetValue(successor, out BlockLiveness successorLiveness))
                        {
                            continue;
                        }
                        blockLiveness.OutLive.UnionWith(successorLiveness.InLive);
                    }

                    var live = new HashSet <IRVariable>(blockLiveness.OutLive);
                    for (int i = currentBlock.Content.Count - 1; i >= 0; i--)
                    {
                        IRInstruction instr = currentBlock.Content[i];
                        ComputeInstrLiveness(instr, live);
                    }
                    blockLiveness.InLive.UnionWith(live);

                    if (!worked && liveness.TryGetValue(currentBlock, out BlockLiveness prevLiveness))
                    {
                        worked = !prevLiveness.InLive.SetEquals(blockLiveness.InLive) ||
                                 !prevLiveness.OutLive.SetEquals(blockLiveness.OutLive);
                    }
                    liveness[currentBlock] = blockLiveness;
                }
            } while(worked);

            return(liveness);
        }
        public static Dictionary <IRInstruction, HashSet <IRVariable> > ComputeLiveness(
            BasicBlock <IRInstrList> block, BlockLiveness liveness)
        {
            var ret  = new Dictionary <IRInstruction, HashSet <IRVariable> >();
            var live = new HashSet <IRVariable>(liveness.OutLive);

            for (int i = block.Content.Count - 1; i >= 0; i--)
            {
                IRInstruction instr = block.Content[i];
                ComputeInstrLiveness(instr, live);
                ret[instr] = new HashSet <IRVariable>(live);
            }
            Debug.Assert(live.SetEquals(liveness.InLive));
            return(ret);
        }
 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)
         });
     }
 }
        private void VisitInstr(IRInstrList instrs, IRInstruction instr, ref int index, IRTransformer tr)
        {
            if (!(instr.Annotation is InstrCallInfo callInfo) || callInfo.ReturnValue == null)
            {
                return;
            }

            if (instr.Operand1 is IRRegister && ((IRRegister)instr.Operand1).SourceVariable == callInfo.ReturnValue)
            {
                callInfo.ReturnRegister = (IRRegister)instr.Operand1;
            }
            else if (instr.Operand1 is IRPointer && ((IRPointer)instr.Operand1).SourceVariable == callInfo.ReturnValue)
            {
                callInfo.ReturnSlot = (IRPointer)instr.Operand1;
            }
        }
Beispiel #29
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;
     }
 }
Beispiel #31
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);
        }
        public void Translate(IRInstruction instr, ILTranslator tr)
        {
            tr.PushOperand(instr.Operand2);
            tr.PushOperand(instr.Operand1);

            ILInstruction lastInstr = tr.Instructions[tr.Instructions.Count - 1];

            Debug.Assert(lastInstr.OpCode == ILOpCode.PUSHI_DWORD && lastInstr.Operand is ILJumpTable);

            var switchInstr = new ILInstruction(ILOpCode.SWT)
            {
                Annotation = InstrAnnotation.JUMP
            };

            tr.Instructions.Add(switchInstr);

            var jmpTable = (ILJumpTable)lastInstr.Operand;

            jmpTable.Chunk.runtime = tr.Runtime;
            jmpTable.RelativeBase  = switchInstr;
            tr.Runtime.AddChunk(jmpTable.Chunk);
        }