Example #1
0
 public void SetAll(HighPhi[] phis, HighInstruction[] instrs)
 {
     m_instructions = instrs;
     m_phis = phis;
 }
Example #2
0
 public HighCfgNode(HighCfgNodeHandle[] predecessors, HighPhi[] phis, HighInstruction[] instructions)
 {
     m_predecessors = predecessors;
     m_phis = phis;
     m_instructions = instructions;
 }
        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);
        }