Пример #1
0
 public HighPhi(HighSsaRegister dest, HighPhiLink[] links)
 {
     if (dest.IsConstant)
         throw new ArgumentException("Can't use a constant as a phi destination");
     m_dest = dest;
     m_links = links;
 }
Пример #2
0
        private CppTranslatedOutboundEdge InternOutboundEdge(CfgNode node, CfgOutboundEdge edge)
        {
            CppTranslatedOutboundEdge outboundEdge;
            if (m_translatedOutboundEdges.TryGetValue(edge, out outboundEdge))
                return outboundEdge;

            bool needRegTranslation = false;

            int survivingRegsCount = edge.SurvivingRegs.Length;
            CfgNode successorNode = edge.SuccessorNode;

            for (int i = 0; i < survivingRegsCount; i++)
            {
                CLR.CLRTypeSpec outType = edge.SurvivingRegs[i].VType.TypeSpec;
                CLR.CLRTypeSpec inType = successorNode.EntryTypes[i].TypeSpec;

                if (!outType.Equals(inType))
                {
                    needRegTranslation = true;
                    break;
                }
            }

            Clarity.Rpa.HighCfgNodeHandle prevNode = InternHighCfgNode(node);

            if (!needRegTranslation)
            {
                List<Clarity.Rpa.HighSsaRegister> regs = new List<Clarity.Rpa.HighSsaRegister>();
                foreach (SsaRegister reg in edge.SurvivingRegs)
                    regs.Add(InternSsaRegister(reg));
                Clarity.Rpa.HighCfgNodeHandle nextNode = InternHighCfgNode(edge.SuccessorNode);
                outboundEdge = new CppTranslatedOutboundEdge(prevNode, nextNode, regs);
            }
            else
            {
                List<Clarity.Rpa.HighInstruction> instrs = new List<Clarity.Rpa.HighInstruction>();
                List<Clarity.Rpa.HighSsaRegister> regs = new List<Clarity.Rpa.HighSsaRegister>();
                List<Clarity.Rpa.HighPhi> phis = new List<Clarity.Rpa.HighPhi>();

                Clarity.Rpa.HighCfgNodeHandle nextNode = InternHighCfgNode(edge.SuccessorNode);

                MidInstruction[] midInstrs = edge.SuccessorNode.MidInstructions;
                for (int i = 0; i < survivingRegsCount; i++)
                {
                    MidInstruction midInstr = midInstrs[i];
                    if (midInstr.Opcode != MidInstruction.OpcodeEnum.EntryReg)
                        throw new Exception("Internal error");

                    Clarity.Rpa.HighSsaRegister sourceReg = InternSsaRegister(edge.SurvivingRegs[i]);
                    Clarity.Rpa.HighSsaRegister targetReg = InternSsaRegister(midInstr.RegArg);

                    if (!targetReg.IsConstant)
                    {
                        HighSsaRegister importReg = new HighSsaRegister(sourceReg.ValueType, sourceReg.Type, sourceReg.ConstantValue);
                        HighSsaRegister exportReg = new HighSsaRegister(targetReg.ValueType, targetReg.Type, targetReg.ConstantValue);

                        HighPhiLink phiLink = new HighPhiLink(prevNode, sourceReg);
                        phis.Add(new HighPhi(importReg, new HighPhiLink[] { phiLink }));

                        instrs.Add(new Clarity.Rpa.Instructions.PassiveConvertInstruction(
                            midInstr.CodeLocation,
                            exportReg,
                            importReg
                            ));
                        regs.Add(exportReg);
                    }
                    else
                        regs.Add(targetReg);
                }

                instrs.Add(new Clarity.Rpa.Instructions.BranchInstruction(edge.CodeLocation, nextNode));

                Clarity.Rpa.HighCfgNode cfgNode = new HighCfgNode(new Clarity.Rpa.HighCfgNodeHandle[] { prevNode }, phis.ToArray(), instrs.ToArray());
                Clarity.Rpa.HighCfgNodeHandle cfgNodeHandle = new Clarity.Rpa.HighCfgNodeHandle(cfgNode);

                outboundEdge = new CppTranslatedOutboundEdge(cfgNodeHandle, cfgNodeHandle, regs);
            }

            m_translatedOutboundEdges.Add(edge, outboundEdge);
            return outboundEdge;
        }
Пример #3
0
        public override RloMethod GenerateMethod(Compiler compiler, MethodInstantiationPath instantiationPath)
        {
            TypeSpecClassTag delegateClassType = m_dt;

            CliClass delegateCls = compiler.GetClosedClass(delegateClassType);

            TypeNameTag delegateTypeName = delegateCls.TypeName;
            HighTypeDef delegateTypeDef = compiler.GetTypeDef(delegateTypeName);
            if (delegateTypeDef.Semantics != TypeSemantics.Delegate)
                throw new RpaCompileException("Delegate-bound class is not a delegate");

            MethodSignatureTag declSignature = delegateTypeDef.DelegateSignature;

            MethodDeclTag invokeDeclTag = new MethodDeclTag("Invoke", declSignature, delegateTypeName);
            invokeDeclTag = compiler.TagRepository.InternMethodDeclTag(invokeDeclTag);

            uint vtableSlotIndex = delegateCls.DeclTagToVTableSlot[invokeDeclTag];
            CliVtableSlot vtableSlot = delegateCls.VTable[vtableSlotIndex];

            MethodSignatureTag delegateMethodSignature = vtableSlot.MethodSignature;

            TypeSpecMulticastDelegateTag mdType = new TypeSpecMulticastDelegateTag(m_dt);
            mdType = (TypeSpecMulticastDelegateTag)compiler.TagRepository.InternTypeSpec(mdType);

            List<HighSsaRegister> loadedParams = new List<HighSsaRegister>();

            HighLocal thisLocal = new HighLocal(mdType, HighLocal.ETypeOfType.Value);

            List<HighLocal> args = new List<HighLocal>();
            HighSsaRegister thisReg = new HighSsaRegister(HighValueType.ReferenceValue, mdType, null);

            List<HighInstruction> entryInstrs = new List<HighInstruction>();
            entryInstrs.Add(new Rpa.Instructions.LoadLocalInstruction(null, thisReg, thisLocal));

            foreach (MethodSignatureParam param in delegateMethodSignature.ParamTypes)
            {
                switch (param.TypeOfType.Value)
                {
                    case MethodSignatureParamTypeOfType.Values.ByRef:
                        {
                            HighSsaRegister paramSsa = new HighSsaRegister(HighValueType.ManagedPtr, param.Type, null);
                            HighLocal local = new HighLocal(param.Type, HighLocal.ETypeOfType.ByRef);
                            args.Add(local);
                            entryInstrs.Add(new Rpa.Instructions.LoadLocalInstruction(null, paramSsa, local));
                            loadedParams.Add(paramSsa);
                        }
                        break;
                    case MethodSignatureParamTypeOfType.Values.Value:
                        {
                            bool isValueType = compiler.TypeIsValueType(param.Type);
                            HighSsaRegister paramSsa = new HighSsaRegister(isValueType ? HighValueType.ValueValue : HighValueType.ReferenceValue, param.Type, null);
                            HighLocal local = new HighLocal(param.Type, HighLocal.ETypeOfType.Value);
                            args.Add(local);
                            entryInstrs.Add(new Rpa.Instructions.LoadLocalInstruction(null, paramSsa, local));
                            loadedParams.Add(paramSsa);
                        }
                        break;
                    case MethodSignatureParamTypeOfType.Values.TypedByRef:
                        throw new NotImplementedException();
                    default:
                        throw new Exception();
                }
            }

            HighSsaRegister returnValue = null;
            if (!(delegateMethodSignature.RetType is TypeSpecVoidTag))
            {
                bool isValueType = compiler.TypeIsValueType(delegateMethodSignature.RetType);
                returnValue = new HighSsaRegister(isValueType ? HighValueType.ValueValue : HighValueType.ReferenceValue, delegateMethodSignature.RetType, null);
            }

            TypeSpecClassTag nativeUIntType = m_vtCache.GetSystemUIntPtrType(compiler);
            HighSsaRegister numDelegatesValue = new HighSsaRegister(HighValueType.ValueValue, nativeUIntType, null);
            HighSsaRegister zeroNativeUIntConstant = new HighSsaRegister(HighValueType.ConstantValue, nativeUIntType, (ulong)0);

            HighCfgNodeHandle entryHdl = new HighCfgNodeHandle();
            HighCfgNodeHandle loopCallHdl = new HighCfgNodeHandle();
            HighCfgNodeHandle loopIncrementHdl = new HighCfgNodeHandle();
            HighCfgNodeHandle returnHdl = new HighCfgNodeHandle();

            HighSsaRegister postIncrementReg = new HighSsaRegister(HighValueType.ValueValue, nativeUIntType, null);

            entryInstrs.Add(new Instructions.GetMulticastDelegateInvocationCountInstruction(null, numDelegatesValue, thisReg));
            entryInstrs.Add(new Rpa.Instructions.BranchInstruction(null, loopCallHdl));

            entryHdl.Value = new HighCfgNode(entryInstrs.ToArray());

            HighSsaRegister currentCountReg = new HighSsaRegister(HighValueType.ValueValue, nativeUIntType, null);

            {
                List<HighInstruction> instrs = new List<HighInstruction>();
                HighSsaRegister delegateValue = new HighSsaRegister(HighValueType.ReferenceValue, m_dt, null);

                HighInstruction callInstr = new Instructions.CallRloVirtualMethodInstruction(null, vtableSlotIndex, returnValue, thisReg, loadedParams.ToArray());
                callInstr.ContinuationEdge = new HighCfgEdge(callInstr, loopIncrementHdl);

                instrs.Add(callInstr);

                HighPhiLink[] loopLinks = new HighPhiLink[] {
                    new HighPhiLink(entryHdl, zeroNativeUIntConstant),
                    new HighPhiLink(loopIncrementHdl, postIncrementReg)
                };
                HighCfgNodeHandle[] loopPredecessors = new HighCfgNodeHandle[] {
                    entryHdl,
                    loopIncrementHdl,
                };

                HighPhi phi = new HighPhi(currentCountReg, loopLinks);

                loopCallHdl.Value = new HighCfgNode(loopPredecessors, new HighPhi[] { phi }, instrs.ToArray());
            }

            {
                List<HighInstruction> instrs = new List<HighInstruction>();
                HighSsaRegister oneConstant = new HighSsaRegister(HighValueType.ConstantValue, nativeUIntType, (ulong)1);
                instrs.Add(new Rpa.Instructions.ArithInstruction(null, postIncrementReg, Rpa.Instructions.NumberArithOp.Add, Rpa.Instructions.NumberArithType.NativeUInt, currentCountReg, oneConstant, false));
                instrs.Add(new Rpa.Instructions.BranchCompareNumbersInstruction(null, Rpa.Instructions.NumberCompareOperation.LessThan, Rpa.Instructions.NumberArithType.NativeUInt, currentCountReg, numDelegatesValue, loopCallHdl, returnHdl));

                loopIncrementHdl.Value = new HighCfgNode(instrs.ToArray());
            }

            {
                List<HighInstruction> instrs = new List<HighInstruction>();
                if (returnValue == null)
                    instrs.Add(new Rpa.Instructions.ReturnInstruction(null));
                else
                    instrs.Add(new Rpa.Instructions.ReturnValueInstruction(null, returnValue));

                returnHdl.Value = new HighCfgNode(instrs.ToArray());
            }

            HighRegion region = new HighRegion(entryHdl);
            RloMethodBody methodBody = new RloMethodBody(thisLocal, args.ToArray(), new HighLocal[0], delegateMethodSignature.RetType, region, delegateMethodSignature, instantiationPath);
            return new RloMethod(methodBody);
        }