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); } }
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(); } }
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(); } }
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 }); }