Beispiel #1
0
        internal bool RegisterGeneric(TypeSig t)
        {
            Debug.Assert(t != null, $"{nameof(t)} != null");

            // This is a temporary fix.
            // Type visibility should be handled in a much better way which would involved some analysis.
            var typeDef = t.ToTypeDefOrRef().ResolveTypeDef();

            if (typeDef != null && !typeDef.IsVisibleOutside())
            {
                return(false);
            }

            // Get proper type.
            t = SignatureUtils.GetLeaf(t);

            // scrambling voids leads to peverify errors, better leave them out.
            if (t.ElementType == ElementType.Void)
            {
                return(false);
            }

            if (!Generics.ContainsKey(t))
            {
                GenericParam newGenericParam;
                if (t.IsGenericMethodParameter)
                {
                    var mVar = t.ToGenericMVar();
                    Debug.Assert(mVar != null, $"{nameof(mVar)} != null");
                    newGenericParam = new GenericParamUser(GenericCount, mVar.GenericParam.Flags, $"T{GenericCount}")
                    {
                        Rid = mVar.Rid
                    };
                }
                else if (t.IsGenericTypeParameter)
                {
                    var tVar = t.ToGenericVar();
                    Debug.Assert(tVar != null, $"{nameof(tVar)} != null");
                    newGenericParam = new GenericParamUser(GenericCount, tVar.GenericParam.Flags, $"T{GenericCount}")
                    {
                        Rid = tVar.Rid
                    };
                }
                else
                {
                    newGenericParam = new GenericParamUser(GenericCount, GenericParamAttributes.NoSpecialConstraint, $"T{GenericCount}");
                }
                Generics.Add(t, newGenericParam);
                GenericCount++;
                _trueTypes.Add(t);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #2
0
        public static void EscapeMethodTypeName(StringBuilder sb, TypeSig cntSig)
        {
            switch (cntSig.ElementType)
            {
            case ElementType.Void:
                sb.Append("void");
                break;

            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.I:
            case ElementType.U:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: false, hasModuleName: false));
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.ValueType:
            case ElementType.Class:
            case ElementType.Object:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: false, hasModuleName: false));
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.SZArray:
                sb.Append("System_SZArray_1_");
                EscapeTypeName(sb, cntSig.Next);
                break;

            case ElementType.Var:
            {
                var var = cntSig.ToGenericVar();
                sb.Append(var.GetName());
            }
            break;

            case ElementType.MVar:
            {
                var mvar = cntSig.ToGenericMVar();
                sb.Append(mvar.GetName());
            }
            break;

            case ElementType.GenericInst:
            {
                var sig = cntSig.ToGenericInstSig();
                sb.Append(EscapeTypeName(sig.GenericType.TypeDefOrRef, hasGen: false, hasModuleName: false));
                sb.Append("_");
                for (int i = 0; i < sig.GenericArguments.Count; i++)
                {
                    EscapeMethodTypeName(sb, sig.GenericArguments[i]);
                    if (i != sig.GenericArguments.Count - 1)
                    {
                        sb.Append("_ ");
                    }
                }
            }
            break;

            case ElementType.ByRef:
                sb.Append("ref_");
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            case ElementType.Ptr:
                sb.Append("ptr_");
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            case ElementType.Pinned:
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            case ElementType.CModReqd:
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #3
0
        public static void EscapeTypeName(StringBuilder sb, TypeSig cntSig, TypeDef declaringType = null, int hasGen = 0, IList <TypeSig> genArgs = null, bool cppBasicType = false)
        {
            switch (cntSig.ElementType)
            {
            case ElementType.Void:
                sb.Append("void");
                break;

            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.I:
            case ElementType.U:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    if (declaringType != null && sig.TypeDef == declaringType)
                    {
                        sb.Append(GetConstantTypeName(cntSig.ElementType));
                    }
                    else
                    {
                        sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: hasGen-- > 0, genArgs: genArgs, cppBasicType: cppBasicType));
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.ValueType:
            case ElementType.Class:
            case ElementType.Object:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    if (sig.IsPrimitive && declaringType != null && sig.TypeDef == declaringType)
                    {
                        sb.Append(GetConstantTypeName(cntSig.ElementType));
                    }
                    else
                    {
                        sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: hasGen-- > 0, genArgs: genArgs, cppBasicType: cppBasicType));
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.SZArray:
                sb.Append("::System_Private_CoreLib::System::SZArray_1<");
                EscapeTypeName(sb, cntSig.Next, declaringType, genArgs: genArgs, cppBasicType: true);
                sb.Append(">");
                break;

            case ElementType.Var:
            {
                var var = cntSig.ToGenericVar();
                if (genArgs != null)
                {
                    var sig = genArgs.OfType <GenericSig>().FirstOrDefault(x => x.Number == var.Number);
                    if (sig != null)
                    {
                        EscapeTypeName(sb, sig, cppBasicType: true);
                    }
                    else
                    {
                        EscapeTypeName(sb, genArgs[(int)var.Number], cppBasicType: true);
                    }
                }
                else
                {
                    if (cppBasicType)
                    {
                        sb.Append(var.GetName());
                    }
                    else
                    {
                        sb.Append($"::natsu::to_clr_type_t<{var.GetName()}>");
                    }
                }
            }
            break;

            case ElementType.MVar:
            {
                var mvar = cntSig.ToGenericMVar();
                if (genArgs != null)
                {
                    EscapeTypeName(sb, genArgs[(int)mvar.Number], cppBasicType: true);
                }
                else
                {
                    if (cppBasicType)
                    {
                        sb.Append(mvar.GetName());
                    }
                    else
                    {
                        sb.Append($"::natsu::to_clr_type_t<{mvar.GetName()}>");
                    }
                }
            }
            break;

            case ElementType.GenericInst:
            {
                var sig = cntSig.ToGenericInstSig();
                sb.Append(EscapeTypeName(sig.GenericType.TypeDefOrRef, hasGen: false, cppBasicType: cppBasicType));
                sb.Append("<");
                for (int i = 0; i < sig.GenericArguments.Count; i++)
                {
                    EscapeTypeName(sb, sig.GenericArguments[i], null, genArgs: genArgs, cppBasicType: true);
                    if (i != sig.GenericArguments.Count - 1)
                    {
                        sb.Append(", ");
                    }
                }
                sb.Append(">");
            }
            break;

            case ElementType.ByRef:
                sb.Append("::natsu::gc_ref<");
                sb.Append(EscapeVariableTypeName(cntSig.Next, declaringType, hasGen, genArgs));
                sb.Append(">");
                break;

            case ElementType.Ptr:
                sb.Append("::natsu::gc_ptr<");
                sb.Append(EscapeVariableTypeName(cntSig.Next, declaringType, hasGen, genArgs));
                sb.Append(">");
                break;

            case ElementType.Pinned:
                EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                break;

            case ElementType.CModReqd:
            {
                var modifier = ((ModifierSig)cntSig).Modifier;
                var modName  = modifier.FullName;
                if (modName == "System.Runtime.InteropServices.InAttribute")
                {
                    EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                }
                else if (modName == "System.Runtime.CompilerServices.IsVolatile")
                {
                    sb.Append("::natsu::clr_volatile<");
                    EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                    sb.Append(">");
                }
                else
                {
                    EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                }
                break;
            }

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #4
0
        public static StackType GetStackType(TypeSig type, IList <TypeSig> genArgs = null)
        {
            StackTypeCode code;

            switch (type.ElementType)
            {
            case ElementType.Void:
                code = StackTypeCode.Void;
                break;

            case ElementType.Boolean:
                code = StackTypeCode.Int32;
                break;

            case ElementType.Char:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I1:
                code = StackTypeCode.Int32;
                break;

            case ElementType.U1:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I2:
                code = StackTypeCode.Int32;
                break;

            case ElementType.U2:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I4:
                code = StackTypeCode.Int32;
                break;

            case ElementType.U4:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I8:
                code = StackTypeCode.Int64;
                break;

            case ElementType.U8:
                code = StackTypeCode.Int64;
                break;

            case ElementType.R4:
                code = StackTypeCode.F;
                break;

            case ElementType.R8:
                code = StackTypeCode.F;
                break;

            case ElementType.String:
                code = StackTypeCode.O;
                break;

            case ElementType.Ptr:
                code = StackTypeCode.NativeInt;
                break;

            case ElementType.ByRef:
                code = StackTypeCode.Ref;
                break;

            case ElementType.ValueType:
                code = StackTypeCode.ValueType;
                break;

            case ElementType.Class:
                code = StackTypeCode.O;
                break;

            case ElementType.Array:
                code = StackTypeCode.O;
                break;

            case ElementType.TypedByRef:
                code = StackTypeCode.ValueType;
                break;

            case ElementType.I:
                code = StackTypeCode.NativeInt;
                break;

            case ElementType.U:
                code = StackTypeCode.NativeInt;
                break;

            case ElementType.R:
                code = StackTypeCode.F;
                break;

            case ElementType.Object:
                code = StackTypeCode.O;
                break;

            case ElementType.SZArray:
                code = StackTypeCode.O;
                break;

            case ElementType.Var:
            {
                var var = type.ToGenericVar();
                if (genArgs != null)
                {
                    var sig = genArgs.OfType <GenericSig>().FirstOrDefault(x => x.Number == var.Number);
                    if (sig != null)
                    {
                        code = GetStackType(sig).Code;
                    }
                    else
                    {
                        code = GetStackType(genArgs[(int)var.Number]).Code;
                    }
                }
                else
                {
                    code = StackTypeCode.Runtime;
                }
            }
            break;

            case ElementType.MVar:
            {
                var mvar = type.ToGenericMVar();
                if (genArgs != null)
                {
                    code = GetStackType(genArgs[(int)mvar.Number]).Code;
                }
                else
                {
                    code = StackTypeCode.Runtime;
                }
            }
            break;

            case ElementType.GenericInst:
            {
                var gen = type.ToGenericInstSig();
                code = GetStackType(gen.GenericType, genArgs).Code;
                break;
            }

            case ElementType.CModReqd:
            case ElementType.CModOpt:
            case ElementType.Pinned:
                return(GetStackType(type.Next, genArgs));

            default:
                throw new NotSupportedException();
            }

            return(new StackType {
                Code = code, Name = EscapeVariableTypeName(type, genArgs: genArgs), TypeSig = type, GenArgs = genArgs
            });
        }