public static string GetProtectedStaticsProxyName(DefType type) { string name = type.FullNativeName; name = name.Substring(name.IndexOf("::") + 2); name = name.Replace("::", "_"); name = "Mogre::" + name + "_ProtectedStaticsProxy"; return name; }
public RuntimeMethodDesc(bool unboxingStub, DefType owningType, MethodNameAndSignature nameAndSignature, int hashcode) { _owningType = owningType; _nameAndSignature = nameAndSignature; _unboxingStub = unboxingStub; SetHashCode(hashcode); #if DEBUG DebugName = this.ToString(); #endif }
public static bool IsInternalTypeDef(DefType type) { if (!(type is DefTypeDef)) return false; if (type.IsSharedPtr) return false; DefTypeDef explicitType = (type.IsNested) ? type.ParentClass.FindType<DefTypeDef>(type.Name) : type.NameSpace.FindType<DefTypeDef>(type.Name); if (explicitType.IsSTLContainer) return false; if (explicitType.BaseType is DefInternal) return true; return false; }
public NoMetadataType(TypeSystemContext context, RuntimeTypeHandle genericTypeDefinition, DefType genericTypeDefinitionAsDefType, Instantiation instantiation, int hashcode) { _hashcode = hashcode; _context = context; _genericTypeDefinition = genericTypeDefinition; _genericTypeDefinitionAsDefType = genericTypeDefinitionAsDefType; if (_genericTypeDefinitionAsDefType == null) { _genericTypeDefinitionAsDefType = this; } _instantiation = instantiation; // Instantiation must either be: // Something valid (if the type is generic, or a generic type definition) // or Empty (if the type isn't a generic of any form) unsafe { Debug.Assert(((_instantiation.Length > 0) && _genericTypeDefinition.ToEETypePtr()->IsGenericTypeDefinition) || ((_instantiation.Length == 0) && !_genericTypeDefinition.ToEETypePtr()->IsGenericTypeDefinition)); } // Base type is not initialized _baseType = this; }
protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) { AppendName(sb, containingType); sb.Append('/'); sb.Append(nestedType.Name); }
public virtual void CppCheckTypeForDependancy(DefType type) { if (!(type is DefEnum) && !type.IsNested && !type.IsPureManagedClass && !(type is DefInternal) && !type.IsValueType) { AddTypeDependancy(type); } }
public Template(Guid id, DefType defType) { _id = id; _defType = defType; }
public override void GetDefaultParamValueConversion(DefParam param, out string preConversion, out string conversion, out string postConversion, out DefType dependancyType) { preConversion = postConversion = ""; dependancyType = null; switch (param.PassedByType) { case PassedByType.Pointer: if (param.DefaultValue == "NULL" || param.DefaultValue == "0") { conversion = "nullptr"; return; } else throw new Exception("Unexpected"); default: throw new Exception("Unexpected"); } }
public virtual void AddPragmaMakePublicForType(DefType type) { if (!PragmaMakePublicTypes.Contains(type)) PragmaMakePublicTypes.Add(type); }
/// <summary> /// Compute the static field layout for a DefType. Must not depend on static field layout for any other type. /// </summary> public abstract ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind);
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { if (type.Context.Target.Architecture == TargetArchitecture.ARM64) { return(type.InstanceFieldSize.AsInt switch { 16 => ValueTypeShapeCharacteristics.Vector128Aggregate, _ => ValueTypeShapeCharacteristics.None });
/// <summary> /// Prepare the StaticGCLayout/ThreadStaticGCLayout/GcStaticDesc/ThreadStaticDesc fields by /// reading native layout or metadata as appropriate. This method should only be called for types which /// are actually to be created. /// </summary> public void PrepareStaticGCLayout() { if (!_staticGCLayoutPrepared) { _staticGCLayoutPrepared = true; DefType defType = TypeBeingBuilt as DefType; if (defType == null) { // Array/pointer types do not have static fields } else if (defType.IsTemplateCanonical()) { // Canonical templates get their layout directly from the NativeLayoutInfo. // Parse it and pull that info out here. NativeParser typeInfoParser = GetParserForNativeLayoutInfo(); BagElementKind kind; while ((kind = typeInfoParser.GetBagElementKind()) != BagElementKind.End) { switch (kind) { case BagElementKind.GcStaticDesc: GcStaticDesc = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned()); break; case BagElementKind.ThreadStaticDesc: ThreadStaticDesc = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned()); break; case BagElementKind.GcStaticEEType: GcStaticEEType = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned()); break; default: typeInfoParser.SkipInteger(); break; } } } else { // Compute GC layout boolean array from field information. IEnumerable <FieldDesc> fields = GetFieldsForGCLayout(); LowLevelList <bool> threadStaticLayout = null; LowLevelList <bool> gcStaticLayout = null; foreach (FieldDesc field in fields) { if (!field.IsStatic) { continue; } if (field.IsLiteral) { continue; } LowLevelList <bool> gcLayoutInfo = null; if (field.IsThreadStatic) { if (threadStaticLayout == null) { threadStaticLayout = new LowLevelList <bool>(); } gcLayoutInfo = threadStaticLayout; } else if (field.HasGCStaticBase) { if (gcStaticLayout == null) { gcStaticLayout = new LowLevelList <bool>(); } gcLayoutInfo = gcStaticLayout; } else { // Non-GC static no need to record information continue; } TypeBuilder.GCLayout fieldGcLayout = GetFieldGCLayout(field.FieldType); fieldGcLayout.WriteToBitfield(gcLayoutInfo, field.Offset.AsInt); } if (gcStaticLayout != null && gcStaticLayout.Count > 0) { StaticGCLayout = gcStaticLayout; } if (threadStaticLayout != null && threadStaticLayout.Count > 0) { ThreadStaticGCLayout = threadStaticLayout; } } } }
private bool ComputeIsBlocked(EcmaType type, ModuleBlockingMode blockingMode) { // If the type is explicitly blocked, it's always blocked. if (type.HasCustomAttribute("System.Runtime.CompilerServices", "ReflectionBlockedAttribute")) { return(true); } // If no blocking is applied to the module, the type is not blocked if (blockingMode == ModuleBlockingMode.None) { return(false); } // <Module> type always gets metadata if (type.IsModuleType) { return(false); } // The various SR types used in Resource Manager always get metadata if (type.Name == "SR") { return(false); } // Event sources are not blocked if (type.HasCustomAttribute("System.Diagnostics.Tracing", "EventSourceAttribute")) { return(false); } // We block everything else if the module is blocked if (blockingMode == ModuleBlockingMode.FullyBlocked) { return(true); } DefType containingType = type.ContainingType; var typeDefinition = type.MetadataReader.GetTypeDefinition(type.Handle); // [Serializable] types may be serialized by reflection-based serializers, so we need to // permit limited reflection over them. Details are at https://msdn.microsoft.com/en-us/library/system.serializableattribute(v=vs.110).aspx bool blockIfNotVisibleOrAccessible = true; if (type.IsSerializable) { blockIfNotVisibleOrAccessible = false; } if (containingType == null) { if ((typeDefinition.Attributes & TypeAttributes.Public) == 0) { return(blockIfNotVisibleOrAccessible); } } else { if ((typeDefinition.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) { return(ComputeIsBlocked((EcmaType)containingType, blockingMode)); } else { return(blockIfNotVisibleOrAccessible || ComputeIsBlocked((EcmaType)containingType, blockingMode)); } } return(false); }
public void VerifyInterfaces() { TypeDefinition typeDefinition = _module.MetadataReader.GetTypeDefinition(_typeDefinitionHandle); EcmaType type = (EcmaType)_module.GetType(_typeDefinitionHandle); if (type.IsInterface) { return; } InterfaceImplementationHandleCollection interfaceHandles = typeDefinition.GetInterfaceImplementations(); int count = interfaceHandles.Count; if (count == 0) { return; } // Look for duplicates and prepare distinct list of implemented interfaces to avoid // subsequent error duplication VirtualMethodAlgorithm virtualMethodAlg = _typeSystemContext.GetVirtualMethodAlgorithmForType(type); List <InterfaceMetadataObjects> implementedInterfaces = new List <InterfaceMetadataObjects>(); foreach (InterfaceImplementationHandle interfaceHandle in interfaceHandles) { InterfaceImplementation interfaceImplementation = _module.MetadataReader.GetInterfaceImplementation(interfaceHandle); DefType interfaceType = _module.GetType(interfaceImplementation.Interface) as DefType; if (interfaceType == null) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } InterfaceMetadataObjects imo = new InterfaceMetadataObjects { DefType = interfaceType, InterfaceImplementationHandle = interfaceHandle }; if (!implementedInterfaces.Contains(imo)) { implementedInterfaces.Add(imo); } else { VerificationError(VerifierError.InterfaceImplHasDuplicate, Format(type), Format(interfaceType)); } } foreach (InterfaceMetadataObjects implementedInterface in implementedInterfaces) { if (!type.IsAbstract) { // Look for missing method implementation foreach (MethodDesc method in implementedInterface.DefType.GetAllMethods()) { MethodDesc resolvedMethod = virtualMethodAlg.ResolveInterfaceMethodToVirtualMethodOnType(method, type); if (resolvedMethod is null) { VerificationError(VerifierError.InterfaceMethodNotImplemented, Format(type), Format(implementedInterface.DefType), Format(method)); } } } } }
private string Format(DefType interfaceTypeDef) { return(interfaceTypeDef.ToString()); }
private void AddVirtualMethodUseDependencies(DependencyList dependencyList, NodeFactory factory) { DefType closestDefType = _type.GetClosestDefType(); if (_type.RuntimeInterfaces.Length > 0 && !factory.VTable(closestDefType).HasFixedSlots) { foreach (var implementedInterface in _type.RuntimeInterfaces) { // If the type implements ICastable, the methods are implicitly necessary if (implementedInterface == factory.ICastableInterface) { MethodDesc isInstDecl = implementedInterface.GetKnownMethod("IsInstanceOfInterface", null); MethodDesc getImplTypeDecl = implementedInterface.GetKnownMethod("GetImplType", null); MethodDesc isInstMethodImpl = _type.ResolveInterfaceMethodTarget(isInstDecl); MethodDesc getImplTypeMethodImpl = _type.ResolveInterfaceMethodTarget(getImplTypeDecl); if (isInstMethodImpl != null) { dependencyList.Add(factory.VirtualMethodUse(isInstMethodImpl), "ICastable IsInst"); } if (getImplTypeMethodImpl != null) { dependencyList.Add(factory.VirtualMethodUse(getImplTypeMethodImpl), "ICastable GetImplType"); } } // If any of the implemented interfaces have variance, calls against compatible interface methods // could result in interface methods of this type being used (e.g. IEnumberable<object>.GetEnumerator() // can dispatch to an implementation of IEnumerable<string>.GetEnumerator()). // For now, we will not try to optimize this and we will pretend all interface methods are necessary. bool allInterfaceMethodsAreImplicitlyUsed = false; if (implementedInterface.HasVariance) { TypeDesc interfaceDefinition = implementedInterface.GetTypeDefinition(); for (int i = 0; i < interfaceDefinition.Instantiation.Length; i++) { if (((GenericParameterDesc)interfaceDefinition.Instantiation[i]).Variance != 0 && !implementedInterface.Instantiation[i].IsValueType) { allInterfaceMethodsAreImplicitlyUsed = true; break; } } } if (!allInterfaceMethodsAreImplicitlyUsed && (_type.IsArray || _type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) && implementedInterface.HasInstantiation) { // NOTE: we need to also do this for generic interfaces on arrays because they have a weird casting rule // that doesn't require the implemented interface to be variant to consider it castable. // For value types, we only need this when the array is castable by size (int[] and ICollection<uint>), // or it's a reference type (Derived[] and ICollection<Base>). TypeDesc elementType = _type.IsArray ? ((ArrayType)_type).ElementType : _type.Instantiation[0]; allInterfaceMethodsAreImplicitlyUsed = CastingHelper.IsArrayElementTypeCastableBySize(elementType) || (elementType.IsDefType && !elementType.IsValueType); } if (allInterfaceMethodsAreImplicitlyUsed) { foreach (var interfaceMethod in implementedInterface.GetAllMethods()) { if (interfaceMethod.Signature.IsStatic) { continue; } // Generic virtual methods are tracked by an orthogonal mechanism. if (interfaceMethod.HasInstantiation) { continue; } MethodDesc implMethod = closestDefType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod); if (implMethod != null) { dependencyList.Add(factory.VirtualMethodUse(interfaceMethod), "Variant interface method"); dependencyList.Add(factory.VirtualMethodUse(implMethod), "Variant interface method"); } } } } } }
protected virtual void AddNestedType(DefType nested) { }
//If the template is null, then use the templateID //The caller is expected to set the TransactionScope public static string GetTemplateDef(Template template, Guid templateID, DefType defType) { Guid localTemplateID = template == null ? templateID : template.ID; string sTemplateDef = null; DataSet ds; try { switch (defType) { case DefType.NotAssigned: throw new Exception(string.Format("DefType not assigned for TemplateID {0}",templateID.ToString())); case DefType.Draft: ds = Data.Template.GetDraftTemplateDef(localTemplateID); sTemplateDef = (string)ds.Tables[0].Rows[0][Data.DataNames._C_DraftTemplateDef]; break; case DefType.Final: ds = Data.Template.GetFinalTemplateDef(localTemplateID); sTemplateDef = (string)ds.Tables[0].Rows[0][Data.DataNames._C_FinalTemplateDef]; break; case DefType.ManagedItem: if (template == null) throw new Exception("Failed to provide Template object for GetTemplateDef call"); if (!template.IsManagedItem) throw new Exception(string.Format("Failed to cast TemplateID {0} to ManagedItem", localTemplateID.ToString())); ManagedItem managedItem = template as ManagedItem; sTemplateDef = Data.ManagedItem.GetTemplateDef(managedItem.ManagedItemID); break; } if (string.IsNullOrEmpty(sTemplateDef)) return null; } catch { return null; } return sTemplateDef; }
private static bool Load <T>(DefType type, out T t) { return(Load <T>(type.ToString(), out t)); }
public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind) { return(_fallbackAlgorithm.ComputeStaticFieldLayout(type, layoutKind)); }
/// <summary> /// Compute the shape of a valuetype. The shape information is used to control code generation and allocation /// (such as vectorization, passing the valuetype by value across method calls, or boxing alignment). /// </summary> public abstract ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type);
private static bool Save <T>(DefType type, T t) { return(Save <T>(type.ToString(), t)); }
public override void GetDefaultParamValueConversion(DefParam param, out string preConversion, out string conversion, out string postConversion, out DefType dependancyType) { preConversion = postConversion = ""; dependancyType = null; switch (param.PassedByType) { case PassedByType.Reference: case PassedByType.Value: conversion = param.DefaultValue.Trim(); if (!conversion.StartsWith("\"") && conversion.Contains("::")) { //It's a static string of a class if (conversion == "StringUtil::BLANK") { //Manually translate "StringUtil::BLANK" so that there's no need to wrap the StringUtil class conversion = "String::Empty"; return; } string name = conversion.Substring(0, conversion.LastIndexOf("::")); dependancyType = FindType<DefType>(name); } break; default: throw new Exception("Unexpected"); } }
public static bool IsGeneric(this TypeDesc type) { DefType typeAsDefType = type as DefType; return(typeAsDefType != null && typeAsDefType.HasInstantiation); }
public bool TypeIsWrappable(DefType type) { if (type.Name.StartsWith("DLL_")) { //It's DLL function pointers of OgrePlatformManager.h return false; } // Get explicit type or a new type if type has ReplaceBy attribute type = (type.IsNested) ? type.ParentClass.FindType<DefType>(type.Name) : type.NameSpace.FindType<DefType>(type.Name); if (type.HasAttribute<CustomIncClassDefinitionAttribute>()) return true; if (type.IsIgnored) return false; if (type.HasAttribute<WrapTypeAttribute>()) return true; if (type.IsSharedPtr) { type.Attributes.Add(new WrapTypeAttribute(WrapTypes.SharedPtr)); return true; } else if (type is DefClass) { DefClass cls = type as DefClass; if (cls.HasAttribute<CLRObjectAttribute>(true)) { if (cls.HasAttribute<OverridableAttribute>(true)) cls.Attributes.Add(new WrapTypeAttribute(WrapTypes.Overridable)); else cls.Attributes.Add(new WrapTypeAttribute(WrapTypes.NonOverridable)); return true; } if (cls.IsSingleton) { cls.Attributes.Add(new WrapTypeAttribute(WrapTypes.Singleton)); return true; } return false; } else if (type is DefTypeDef) { if (type.IsSTLContainer) { foreach (ITypeMember m in (type as DefTypeDef).TypeMembers) { DefType mt = m.Type; if (!mt.IsValueType && !mt.IsPureManagedClass && !TypeIsWrappable(mt)) return false; } return true; } else if (type is DefIterator) { if (TypeIsWrappable((type as DefIterator).TypeMembers[0].Type)) { if ((type as DefIterator).IsConstIterator) { try { DefType notconst = type.FindType<DefType>(type.Name.Substring("Const".Length), true); return false; } catch { return true; } } else return true; } else return false; } else if ((type as DefTypeDef).BaseType is DefInternal || (type as DefTypeDef).BaseType.HasAttribute<ValueTypeAttribute>()) return true; else return false; } else return false; }
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { if (type.Context.Target.Architecture == TargetArchitecture.ARM) { unsafe { // On ARM, the HFA type is encoded into the EEType directly type.RetrieveRuntimeTypeHandleIfPossible(); Debug.Assert(!type.RuntimeTypeHandle.IsNull()); EEType *eeType = type.RuntimeTypeHandle.ToEETypePtr(); if (!eeType->IsHFA) { return(ValueTypeShapeCharacteristics.None); } if (eeType->RequiresAlign8) { return(ValueTypeShapeCharacteristics.Float64Aggregate); } else { return(ValueTypeShapeCharacteristics.Float32Aggregate); } } } else { Debug.Assert( type.Context.Target.Architecture == TargetArchitecture.X86 || type.Context.Target.Architecture == TargetArchitecture.X64); return(ValueTypeShapeCharacteristics.None); } }
public virtual void CheckTypeForDependancy(DefType type) { if (type is DefEnum || (!(type is IDefString) && type is DefTypeDef && (type as DefTypeDef).BaseType is DefInternal) || type.HasWrapType(WrapTypes.NativePtrValueType) || type.HasWrapType(WrapTypes.ValueType)) AddTypeDependancy(type); else if (type.ParentClass != null) AddTypeDependancy(type.ParentClass); else if (type is DefTypeDef) CheckTypeForDependancy((type as DefTypeDef).BaseType); if (!type.IsNested && type is DefClass) AddPragmaMakePublicForType(type); }
public unsafe override bool ComputeContainsGCPointers(DefType type) { return(type.RuntimeTypeHandle.ToEETypePtr()->HasGCPointers); }
public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type) { return(_metadataFieldLayoutAlgorithm); }
/// <summary> /// Constructs a new instance of <see cref="DelegateCreationInfo"/> set up to construct a delegate of type /// '<paramref name="delegateType"/>' pointing to '<paramref name="targetMethod"/>'. /// </summary> public static DelegateCreationInfo Create(TypeDesc delegateType, MethodDesc targetMethod, NodeFactory factory, bool followVirtualDispatch) { TypeSystemContext context = delegateType.Context; DefType systemDelegate = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; int paramCountTargetMethod = targetMethod.Signature.Length; if (!targetMethod.Signature.IsStatic) { paramCountTargetMethod++; } DelegateInfo delegateInfo = context.GetDelegateInfo(delegateType.GetTypeDefinition()); int paramCountDelegateClosed = delegateInfo.Signature.Length + 1; bool closed = false; if (paramCountDelegateClosed == paramCountTargetMethod) { closed = true; } else { Debug.Assert(paramCountDelegateClosed == paramCountTargetMethod + 1); } if (targetMethod.Signature.IsStatic) { MethodDesc invokeThunk; MethodDesc initMethod; if (!closed) { // Open delegate to a static method if (targetMethod.IsNativeCallable) { // If target method is native callable, create a reverse PInvoke delegate initMethod = systemDelegate.GetKnownMethod("InitializeReversePInvokeThunk", null); invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ReversePinvokeThunk]; // You might hit this when the delegate is generic: you need to make the delegate non-generic. // If the code works on Project N, it's because the delegate is used in connection with // AddrOf intrinsic (please validate that). We don't have the necessary AddrOf expansion in // the codegen to make this work without actually constructing the delegate. You can't construct // the delegate if it's generic, even on Project N. // TODO: Make this throw something like "TypeSystemException.InvalidProgramException"? Debug.Assert(invokeThunk != null, "Delegate with a non-native signature for a NativeCallable method"); } else { initMethod = systemDelegate.GetKnownMethod("InitializeOpenStaticThunk", null); invokeThunk = delegateInfo.Thunks[DelegateThunkKind.OpenStaticThunk]; } } else { // Closed delegate to a static method (i.e. delegate to an extension method that locks the first parameter) invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ClosedStaticThunk]; initMethod = systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null); } var instantiatedDelegateType = delegateType as InstantiatedType; if (instantiatedDelegateType != null) { invokeThunk = context.GetMethodForInstantiatedType(invokeThunk, instantiatedDelegateType); } return(new DelegateCreationInfo( factory.MethodEntrypoint(initMethod), targetMethod, TargetKind.ExactCallableAddress, factory.MethodEntrypoint(invokeThunk))); } else { if (!closed) { throw new NotImplementedException("Open instance delegates"); } string initializeMethodName = "InitializeClosedInstance"; MethodDesc targetCanonMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); TargetKind kind; if (targetMethod.HasInstantiation) { if (followVirtualDispatch && targetMethod.IsVirtual) { initializeMethodName = "InitializeClosedInstanceWithGVMResolution"; kind = TargetKind.MethodHandle; } else { if (targetMethod != targetCanonMethod) { // Closed delegates to generic instance methods need to be constructed through a slow helper that // checks for the fat function pointer case (function pointer + instantiation argument in a single // pointer) and injects an invocation thunk to unwrap the fat function pointer as part of // the invocation if necessary. initializeMethodName = "InitializeClosedInstanceSlow"; } kind = TargetKind.ExactCallableAddress; } } else { if (followVirtualDispatch && targetMethod.IsVirtual) { if (targetMethod.OwningType.IsInterface) { kind = TargetKind.InterfaceDispatch; initializeMethodName = "InitializeClosedInstanceToInterface"; } else { kind = TargetKind.VTableLookup; targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); } } else { kind = TargetKind.CanonicalEntrypoint; targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); } } return(new DelegateCreationInfo( factory.MethodEntrypoint(systemDelegate.GetKnownMethod(initializeMethodName, null)), targetMethod, kind)); } }
/// <summary> /// This is used to set base type for generic types without metadata /// </summary> public void SetBaseType(DefType baseType) { Debug.Assert(_baseType == this || _baseType == baseType); _baseType = baseType; }
public bool TryGetDynamicLayout(DefType instantiatedType, out FieldAndOffset[] fieldMap) { return(_genericTypeToFieldMap.TryGetValue(instantiatedType, out fieldMap)); }
protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type) { switch (type.Category) { case TypeFlags.Void: sb.Append("void"); return; case TypeFlags.Boolean: sb.Append("bool"); return; case TypeFlags.Char: sb.Append("char"); return; case TypeFlags.SByte: sb.Append("int8"); return; case TypeFlags.Byte: sb.Append("uint8"); return; case TypeFlags.Int16: sb.Append("int16"); return; case TypeFlags.UInt16: sb.Append("uint16"); return; case TypeFlags.Int32: sb.Append("int32"); return; case TypeFlags.UInt32: sb.Append("uint32"); return; case TypeFlags.Int64: sb.Append("int64"); return; case TypeFlags.UInt64: sb.Append("uint64"); return; case TypeFlags.IntPtr: sb.Append("native int"); return; case TypeFlags.UIntPtr: sb.Append("native uint"); return; case TypeFlags.Single: sb.Append("float32"); return; case TypeFlags.Double: sb.Append("float64"); return; } if (type.IsString) { sb.Append("string"); return; } if (type.IsObject) { sb.Append("object"); return; } AppendNameForNamespaceTypeWithoutAliases(sb, type); }
public FieldAndOffset[] GetOrAddDynamicLayout(DefType instantiatedType, FieldAndOffset[] fieldMap) { return(_genericTypeToFieldMap.GetOrAdd(instantiatedType, fieldMap)); }
/// <summary> /// Given a type, and vtable slot index, compute either the NativeFormatMethod that defines that vtable slot, /// OR the implementation function pointer if the method doesn't have sufficient metadata to be interesting /// to use the virtual function resolution algorithm on. /// </summary> /// <param name="type">Type on which virtual resolution is to be completed</param> /// <param name="vtableSlotIndex">Virtual slot index which is to be examined</param> /// <param name="functionPointer">If there is no corresponding method defined in metadata, this is /// the function pointer that should be used for calls to this vtable slot</param> /// <returns>MethodDesc of function that defined the slot if possible.</returns> private static unsafe MethodDesc ResolveVTableSlotIndexToMethodDescOrFunctionPointer(DefType type, int vtableSlotIndex, out IntPtr functionPointer) { Debug.Assert(type.RetrieveRuntimeTypeHandleIfPossible()); Debug.Assert(type.RuntimeTypeHandle.ToEETypePtr()->NumVtableSlots > vtableSlotIndex); DefType definingTypeScan = type; DefType previousDefiningType = null; EEType *typePtr = null; DefType definingType = null; functionPointer = IntPtr.Zero; while (true) { definingTypeScan.RetrieveRuntimeTypeHandleIfPossible(); Debug.Assert(!definingTypeScan.RuntimeTypeHandle.IsNull()); typePtr = definingTypeScan.RuntimeTypeHandle.ToEETypePtr(); if (typePtr->NumVtableSlots > vtableSlotIndex) { previousDefiningType = definingTypeScan; definingTypeScan = definingTypeScan.BaseType; // We found a slot on System.Object if (definingTypeScan == null) { definingType = previousDefiningType; break; } } else { // We've gone past the type in the type hierarchy that declared this vtable slot // the defining type is the one we looked at previously definingType = previousDefiningType; break; } } // At this point, we know the type that definined the virtual slot // There are 4 possibilities here // 1. The definingType is a R2R type with full metadata. Compute the MethodDesc, by scanning the list of virtuals present in metadata // 2. The definingType is pregenerated, but we can go from the slot index to metadata via the runtime mapping tables. Do so, then run // normal algorithm // 3. The definingType is pregenerated, but we cannot go from the slot index to metadata via the runtime mapping tables. There is // only 1 pointer in the vtable of the most derived pregenerated type that has the same value. That's the valuable pointer. // 4. The definingType is pregenerated, but we cannot go from the slot index to metadata via the runtime mapping tables. There are // multiple pointers in the vtable of the most derived pregenerated types which have this same value. // - Take that pointer value, and attempt to resolve back to a method from the implementation. If that succeeds, then // treat that as the correct vtable slot. Otherwise, return that function pointer. (This is a very rare scenario.) MethodDesc slotDefiningMethod = null; if (!IsPregeneratedOrTemplateTypeLoaded(definingType)) { // Case 1 MetadataType definingMetadataType = (MetadataType)definingType; int baseTypeSlotCount = 0; if (definingMetadataType.BaseType != null) { baseTypeSlotCount = definingMetadataType.BaseType.GetRuntimeTypeHandle().ToEETypePtr()->NumVtableSlots; } int slotOnType = vtableSlotIndex - baseTypeSlotCount; Debug.Assert(slotOnType >= 0); // R2R types create new slots only for methods that are marked as NewSlot if (definingMetadataType.ConvertToCanonForm(CanonicalFormKind.Specific) != definingType) { // Deal with the space reserved for the canonical dictionary slotOnType--; } Debug.Assert(slotOnType >= 0); int currentSlot = 0; foreach (MethodDesc method in definingMetadataType.GetMethods()) { if (!MethodDefinesVTableSlot(method)) { continue; } if (currentSlot == slotOnType) { Debug.Assert(VirtualMethodToSlotIndex(method) == vtableSlotIndex); return(method); } else { currentSlot++; } } Environment.FailFast("Unexpected failure to find virtual function that defined slot"); return(null); } else if (TryGetVirtualMethodFromSlot(definingType, vtableSlotIndex, out slotDefiningMethod)) { // Case 2 Debug.Assert(VirtualMethodToSlotIndex(slotDefiningMethod) == vtableSlotIndex); return(slotDefiningMethod); } else { TypeDesc mostDerivedPregeneratedType = GetMostDerivedPregeneratedOrTemplateLoadedType(type); EEType *mostDerivedTypeEEType = mostDerivedPregeneratedType.GetRuntimeTypeHandle().ToEETypePtr(); IntPtr *vtableStart = (IntPtr *)(((byte *)mostDerivedTypeEEType) + sizeof(EEType)); IntPtr possibleFunctionPointerReturn = vtableStart[vtableSlotIndex]; int functionPointerMatches = 0; for (int i = 0; i < mostDerivedTypeEEType->NumVtableSlots; i++) { if (vtableStart[i] == possibleFunctionPointerReturn) { functionPointerMatches++; } } if (functionPointerMatches == 1) { // Case 3 functionPointer = possibleFunctionPointerReturn; return(null); } else { // Case 4 // While this case is theoretically possible, it requires MethodImpl to MethodImpl overloading for virtual functions // in the non-ready to run portions of the binary. Given our current shipping plans, as this does not occur in non-obfuscated // code, we will throw NotImplementedException here. // The real implementation would look something like // if (!TryGetNativeFormatMethodFromFunctionPointer(possibleFunctionPointerReturn, out method)) // { // // this method could not have been overriden in dynamically loaded code // functionPointer = possibleFunctionPointerReturn; // return null; // } // else // { // return VirtualFunctionAlgorithm.GetDefiningMethod(method) // } // throw NotImplemented.ByDesign; } } }
/// <summary> /// If given <param name="type"/> is an <see cref="EcmaType"/> precompute its mangled type name /// along with all the other types from the same module as <param name="type"/>. /// Otherwise, it is a constructed type and to the EcmaType's mangled name we add a suffix to /// show what kind of constructed type it is (e.g. appending __Array for an array type). /// </summary> /// <param name="type">Type to mangled</param> /// <returns>Mangled name for <param name="type"/>.</returns> private string ComputeMangledTypeName(TypeDesc type) { if (type is EcmaType) { EcmaType ecmaType = (EcmaType)type; string assemblyName = ((EcmaAssembly)ecmaType.EcmaModule).GetName().Name; bool isSystemPrivate = assemblyName.StartsWith("System.Private."); // Abbreviate System.Private to S.P. This might conflict with user defined assembly names, // but we already have a problem due to running SanitizeName without disambiguating the result // This problem needs a better fix. if (isSystemPrivate && !_mangleForCplusPlus) { assemblyName = "S.P." + assemblyName.Substring(15); } string prependAssemblyName = SanitizeName(assemblyName); var deduplicator = new HashSet <string>(); // Add consistent names for all types in the module, independent on the order in which // they are compiled lock (this) { bool isSystemModule = ecmaType.Module == ecmaType.Context.SystemModule; if (!_mangledTypeNames.ContainsKey(type)) { foreach (MetadataType t in ecmaType.EcmaModule.GetAllTypes()) { string name = t.GetFullName(); // Include encapsulating type DefType containingType = t.ContainingType; while (containingType != null) { name = containingType.GetFullName() + "_" + name; containingType = containingType.ContainingType; } name = SanitizeName(name, true); if (_mangleForCplusPlus) { // Always generate a fully qualified name name = "::" + prependAssemblyName + "::" + name; } else { name = prependAssemblyName + "_" + name; // If this is one of the well known types, use a shorter name // We know this won't conflict because all the other types are // prefixed by the assembly name. if (isSystemModule) { switch (t.Category) { case TypeFlags.Boolean: name = "Bool"; break; case TypeFlags.Byte: name = "UInt8"; break; case TypeFlags.SByte: name = "Int8"; break; case TypeFlags.UInt16: name = "UInt16"; break; case TypeFlags.Int16: name = "Int16"; break; case TypeFlags.UInt32: name = "UInt32"; break; case TypeFlags.Int32: name = "Int32"; break; case TypeFlags.UInt64: name = "UInt64"; break; case TypeFlags.Int64: name = "Int64"; break; case TypeFlags.Char: name = "Char"; break; case TypeFlags.Double: name = "Double"; break; case TypeFlags.Single: name = "Single"; break; case TypeFlags.IntPtr: name = "IntPtr"; break; case TypeFlags.UIntPtr: name = "UIntPtr"; break; default: if (t.IsObject) { name = "Object"; } else if (t.IsString) { name = "String"; } break; } } } // Ensure that name is unique and update our tables accordingly. name = DisambiguateName(name, deduplicator); deduplicator.Add(name); _mangledTypeNames = _mangledTypeNames.Add(t, name); } } } return(_mangledTypeNames[type]); } string mangledName; switch (type.Category) { case TypeFlags.Array: case TypeFlags.SzArray: mangledName = GetMangledTypeName(((ArrayType)type).ElementType) + "__"; if (type.IsMdArray) { mangledName += NestMangledName("ArrayRank" + ((ArrayType)type).Rank.ToStringInvariant()); } else { mangledName += NestMangledName("Array"); } break; case TypeFlags.ByRef: mangledName = GetMangledTypeName(((ByRefType)type).ParameterType) + NestMangledName("ByRef"); break; case TypeFlags.Pointer: mangledName = GetMangledTypeName(((PointerType)type).ParameterType) + NestMangledName("Pointer"); break; default: // Case of a generic type. If `type' is a type definition we use the type name // for mangling, otherwise we use the mangling of the type and its generic type // parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_ // in C++ compilation. var typeDefinition = type.GetTypeDefinition(); if (typeDefinition != type) { mangledName = GetMangledTypeName(typeDefinition); var inst = type.Instantiation; string mangledInstantiation = ""; for (int i = 0; i < inst.Length; i++) { string instArgName = GetMangledTypeName(inst[i]); if (_mangleForCplusPlus) { instArgName = instArgName.Replace("::", "_"); } if (i > 0) { mangledInstantiation += "__"; } mangledInstantiation += instArgName; } mangledName += NestMangledName(mangledInstantiation); } else if (type is IPrefixMangledMethod) { mangledName = GetPrefixMangledMethodName((IPrefixMangledMethod)type).ToString(); } else if (type is IPrefixMangledType) { mangledName = GetPrefixMangledTypeName((IPrefixMangledType)type).ToString(); } else { mangledName = SanitizeName(((DefType)type).GetFullName(), true); } break; } lock (this) { // Ensure that name is unique and update our tables accordingly. if (!_mangledTypeNames.ContainsKey(type)) { _mangledTypeNames = _mangledTypeNames.Add(type, mangledName); } } return(mangledName); }
protected virtual void AddNestedTypeBeforeMainType(DefType nested) { }
/// <summary> /// Validates that it will be possible to create an EEType for '<paramref name="type"/>'. /// </summary> public static void CheckCanGenerateEEType(NodeFactory factory, TypeDesc type) { // Don't validate generic definitons if (type.IsGenericDefinition) { return; } // System.__Canon or System.__UniversalCanon if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) { return; } // It must be possible to create an EEType for the base type of this type TypeDesc baseType = type.BaseType; if (baseType != null) { // Make sure EEType can be created for this. factory.NecessaryTypeSymbol(baseType); } // We need EETypes for interfaces foreach (var intf in type.RuntimeInterfaces) { // Make sure EEType can be created for this. factory.NecessaryTypeSymbol(intf); } // Validate classes, structs, enums, interfaces, and delegates DefType defType = type as DefType; if (defType != null) { // Ensure we can compute the type layout defType.ComputeInstanceLayout(InstanceLayoutKind.TypeAndFields); // // The fact that we generated an EEType means that someone can call RuntimeHelpers.RunClassConstructor. // We need to make sure this is possible. // if (factory.TypeSystemContext.HasLazyStaticConstructor(defType)) { defType.ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizesAndFields); } // Make sure instantiation length matches the expectation // TODO: it might be more resonable for the type system to enforce this (also for methods) if (defType.Instantiation.Length != defType.GetTypeDefinition().Instantiation.Length) { throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } foreach (TypeDesc typeArg in defType.Instantiation) { // ByRefs, pointers, function pointers, and System.Void are never valid instantiation arguments if (typeArg.IsByRef || typeArg.IsPointer || typeArg.IsFunctionPointer || typeArg.IsVoid) { throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // TODO: validate constraints } // Check the type doesn't have bogus MethodImpls or overrides and we can get the finalizer. defType.GetFinalizer(); } // Validate parameterized types ParameterizedType parameterizedType = type as ParameterizedType; if (parameterizedType != null) { TypeDesc parameterType = parameterizedType.ParameterType; // Make sure EEType can be created for this. factory.NecessaryTypeSymbol(parameterType); if (parameterizedType.IsArray) { if (parameterType.IsPointer || parameterType.IsFunctionPointer) { // Arrays of pointers and function pointers are not currently supported throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } int elementSize = parameterType.GetElementSize(); if (elementSize >= ushort.MaxValue) { // Element size over 64k can't be encoded in the GCDesc throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadValueClassTooLarge, parameterType); } if (((ArrayType)parameterizedType).Rank > 32) { throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadRankTooLarge, type); } } // Validate we're not constructing a type over a ByRef if (parameterType.IsByRef) { // CLR compat note: "ldtoken int32&&" will actually fail with a message about int32&; "ldtoken int32&[]" // will fail with a message about being unable to create an array of int32&. This is a middle ground. throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // It might seem reasonable to disallow array of void, but the CLR doesn't prevent that too hard. // E.g. "newarr void" will fail, but "newarr void[]" or "ldtoken void[]" will succeed. } // Function pointer EETypes are not currently supported if (type.IsFunctionPointer) { throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } }
/// <summary> /// Compute the instance field layout for a DefType. Must not depend on static field layout for any other type. /// </summary> public abstract ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind);
/// <summary> /// If given <param name="type"/> is an <see cref="EcmaType"/> precompute its mangled type name /// along with all the other types from the same module as <param name="type"/>. /// Otherwise, it is a constructed type and to the EcmaType's mangled name we add a suffix to /// show what kind of constructed type it is (e.g. appending __Array for an array type). /// </summary> /// <param name="type">Type to mangled</param> /// <returns>Mangled name for <param name="type"/>.</returns> private string ComputeMangledTypeName(TypeDesc type) { if (type is EcmaType) { EcmaType ecmaType = (EcmaType)type; string prependAssemblyName = SanitizeName(((EcmaAssembly)ecmaType.EcmaModule).GetName().Name); var deduplicator = new HashSet <string>(); // Add consistent names for all types in the module, independent on the order in which // they are compiled lock (this) { if (!_mangledTypeNames.ContainsKey(type)) { foreach (MetadataType t in ((EcmaType)type).EcmaModule.GetAllTypes()) { string name = t.GetFullName(); // Include encapsulating type DefType containingType = t.ContainingType; while (containingType != null) { name = containingType.GetFullName() + "_" + name; containingType = containingType.ContainingType; } name = SanitizeName(name, true); name = prependAssemblyName + "_" + name; // Ensure that name is unique and update our tables accordingly. name = DisambiguateName(name, deduplicator); deduplicator.Add(name); _mangledTypeNames = _mangledTypeNames.Add(t, name); } } } return(_mangledTypeNames[type]); } string mangledName; switch (type.Category) { case TypeFlags.Array: case TypeFlags.SzArray: mangledName = GetMangledTypeName(((ArrayType)type).ElementType) + "__"; if (type.IsMdArray) { mangledName += NestMangledName("ArrayRank" + ((ArrayType)type).Rank.ToStringInvariant()); } else { mangledName += NestMangledName("Array"); } break; case TypeFlags.ByRef: mangledName = GetMangledTypeName(((ByRefType)type).ParameterType) + NestMangledName("ByRef"); break; case TypeFlags.Pointer: mangledName = GetMangledTypeName(((PointerType)type).ParameterType) + NestMangledName("Pointer"); break; default: // Case of a generic type. If `type' is a type definition we use the type name // for mangling, otherwise we use the mangling of the type and its generic type // parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_ // in C++ compilation. var typeDefinition = type.GetTypeDefinition(); if (typeDefinition != type) { mangledName = GetMangledTypeName(typeDefinition); var inst = type.Instantiation; string mangledInstantiation = ""; for (int i = 0; i < inst.Length; i++) { string instArgName = GetMangledTypeName(inst[i]); if (i > 0) { mangledInstantiation += "__"; } mangledInstantiation += instArgName; } mangledName += NestMangledName(mangledInstantiation); } else { mangledName = SanitizeName(((DefType)type).GetFullName(), true); } break; } lock (this) { // Ensure that name is unique and update our tables accordingly. if (!_mangledTypeNames.ContainsKey(type)) { _mangledTypeNames = _mangledTypeNames.Add(type, mangledName); } } return(mangledName); }
/// <summary> /// Compute whether the fields of the specified type contain a GC pointer. /// </summary> public abstract bool ComputeContainsGCPointers(DefType type);
protected override void AddNestedType(DefType nested) { if (nested.HasWrapType(WrapTypes.NativeDirector)) { //Interface and native director are already declared before the declaration of this class. return; } base.AddNestedType(nested); _wrapper.CppAddType(nested, _sb); }
/// <summary> /// If the type has <see cref="ValueTypeShapeCharacteristics.HomogenousFloatAggregate"/> characteristic, returns /// the element type of the homogenous float aggregate. This will either be System.Double or System.Float. /// </summary> public abstract DefType ComputeHomogeneousFloatAggregateElementType(DefType type);
protected override void AddNestedTypeBeforeMainType(DefType nested) { base.AddNestedType(nested); _wrapper.CppAddType(nested, _sb); }
protected override void AddNestedType(DefType nested) { if (nested.IsSTLContainer) { _sb.AppendLine("typedef " + _t.FullNativeName + "::" + nested.Name + " " + nested.CLRName + ";"); } else throw new Exception("Unexpected"); }
protected override void AddTypeDependancy(DefType type) { _wrapper.CppCheckTypeForDependancy(type); }
public override void GetDefaultParamValueConversion(DefParam param, out string preConversion, out string conversion, out string postConversion, out DefType dependancyType) { preConversion = postConversion = ""; dependancyType = null; if (IsVoid) { conversion = param.DefaultValue; return; } switch (param.PassedByType) { case PassedByType.Pointer: if (!param.IsConst) { preConversion = FullCLRName + " out_" + param.Name + ";"; conversion = "out_" + param.Name; return; } else { throw new Exception("Unexpected"); } default: conversion = param.DefaultValue; break; } }
protected override MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType implType, out CORINFO_DEVIRTUALIZATION_DETAIL devirtualizationDetail) { MethodDesc result = base.ResolveVirtualMethod(declMethod, implType, out devirtualizationDetail); if (result != null && result.IsFinal && result.OwningType is MetadataType mdType && mdType.IsAbstract) { // If this type is abstract check that we saw a non-abstract type deriving from it. // We don't look at virtual methods introduced by abstract classes unless there's a non-abstract // class that needs them (i.e. the non-abstract class doesn't immediately override them). // This lets us optimize out some unused virtual method implementations. // Allowing this to devirtualize would cause trouble because we didn't scan the method // and expected it would be optimized out. if (!_abstractButNonabstractlyOverriddenTypes.Contains(mdType.ConvertToCanonForm(CanonicalFormKind.Specific))) { // FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE is close enough... devirtualizationDetail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE; return(null); } } return(result); }
private void AddAttributesInType(DefType type, XmlElement elem) { foreach (XmlAttribute attr in elem.Attributes) { if (attr.Name != "name") AddAttributeInHolder(type, CreateAttribute(attr)); } foreach (XmlNode child in elem.ChildNodes) { if (!(child is XmlElement)) continue; if (child.Name[0] == '_') { AddAttributeInHolder(type, CreateAttribute(child as XmlElement)); continue; } switch (child.Name) { case "class": case "struct": case "enumeration": case "typedef": AddAttributesInType((type as DefClass).GetNestedType((child as XmlElement).GetAttribute("name")), child as XmlElement); break; case "function": case "variable": foreach (DefMember m in (type as DefClass).GetMembers((child as XmlElement).GetAttribute("name"))) AddAttributesInMember(m, child as XmlElement); break; default: throw new Exception("Unexpected"); } } }
protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForDefType(DefType type) { return(_metadataRuntimeInterfacesAlgorithm); }
private void IncAddSharedPtrType(DefType type, IndentStringBuilder sb) { if (!type.Name.EndsWith("Ptr")) throw new Exception("SharedPtr class that doesn't have a name ending to 'Ptr'"); string basename = null; if (type is DefClass) basename = (type as DefClass).Inherits[0]; else basename = (type as DefTypeDef).BaseTypeName; int s = basename.IndexOf("<"); int e = basename.LastIndexOf(">"); string baseClass = basename.Substring(s + 1, e - s - 1).Trim(); //string nativeClass = _nativePrefix + "::" + baseClass; string nativeClass = type.FindType<DefType>(baseClass).FullNativeName; string className = type.FullCLRName; if (className.Contains("::")) className = className.Substring(className.IndexOf("::") + 2); if (!type.IsNested) { PreDeclarations.Add("ref class " + type.Name + ";"); sb.AppendIndent("public "); } else { sb.AppendIndent(Producer.GetProtectionString(type.ProtectionType) + ": "); } sb.Append("ref class " + type.Name + " : public " + baseClass + "\n"); sb.AppendLine("{"); sb.AppendLine("internal:"); sb.IncreaseIndent(); sb.AppendLine("\t" + type.FullNativeName + "* _sharedPtr;"); sb.AppendLine(); sb.AppendLine(type.Name + "(" + type.FullNativeName + "& sharedPtr) : " + baseClass + "( sharedPtr.getPointer() )"); sb.AppendLine("{"); sb.AppendLine("\t_sharedPtr = new " + type.FullNativeName + "(sharedPtr);"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("!" + type.Name + "()"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("if (_sharedPtr != 0)"); sb.AppendLine("{"); sb.AppendLine("\tdelete _sharedPtr;"); sb.AppendLine("\t_sharedPtr = 0;"); sb.AppendLine("}"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("~" + type.Name + "()"); sb.AppendLine("{"); sb.AppendLine("\tthis->!" + type.Name + "();"); sb.AppendLine("}"); sb.AppendLine(); sb.DecreaseIndent(); sb.AppendLine("public:"); sb.IncreaseIndent(); sb.AppendLine("DEFINE_MANAGED_NATIVE_CONVERSIONS_FOR_SHAREDPTR( " + className + " )"); sb.AppendLine(); if (type is DefClass) { DefClass realType = type.FindType<DefClass>(baseClass, false); if (realType != null && realType.BaseClass != null && realType.BaseClass.Name == "Resource") { // For Resource subclasses (Material etc.) allow implicit conversion of ResourcePtr (i.e ResourcePtr -> MaterialPtr) AddTypeDependancy(realType.BaseClass); sb.AppendLine("static " + type.Name + "^ FromResourcePtr( ResourcePtr^ ptr )"); sb.AppendLine("{"); sb.AppendLine("\treturn (" + type.Name + "^) ptr;"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("static operator " + type.Name + "^ ( ResourcePtr^ ptr )"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("void* castptr = dynamic_cast<" + nativeClass + "*>(ptr->_native);"); sb.AppendLine("if (castptr == 0) throw gcnew InvalidCastException(\"The underlying type of the ResourcePtr object is not of type " + baseClass + ".\");"); sb.AppendLine("return gcnew " + type.Name + "( (" + type.FullNativeName + ") *(ptr->_sharedPtr) );"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); } } //sb.AppendLine(type.Name + "() : " + baseClass + "( (" + nativeClass + "*) 0 )"); //sb.AppendLine("{"); //sb.AppendLine("\t_sharedPtr = new " + type.FullNativeName + "();"); //sb.AppendLine("}"); //sb.AppendLine(); sb.AppendLine(type.Name + "(" + baseClass + "^ obj) : " + baseClass + "( obj->_native )"); sb.AppendLine("{"); sb.AppendLine("\t_sharedPtr = new " + type.FullNativeName + "( static_cast<" + nativeClass + "*>(obj->_native) );"); sb.AppendLine("}"); sb.AppendLine(); //sb.AppendLine("void Bind(" + baseClass + "^ obj)"); //sb.AppendLine("{"); //sb.AppendLine("\t(*_sharedPtr).bind( static_cast<" + nativeClass + "*>(obj->_native) );"); //sb.AppendLine("}"); //sb.AppendLine(); sb.AppendLine("virtual bool Equals(Object^ obj) override"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine(type.Name + "^ clr = dynamic_cast<" + type.Name + "^>(obj);"); sb.AppendLine("if (clr == CLR_NULL)"); sb.AppendLine("{"); sb.AppendLine("\treturn false;"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("return (_native == clr->_native);"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine("bool Equals(" + type.Name + "^ obj)"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("if (obj == CLR_NULL)"); sb.AppendLine("{"); sb.AppendLine("\treturn false;"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("return (_native == obj->_native);"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("static bool operator == (" + type.Name + "^ val1, " + type.Name + "^ val2)"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("if ((Object^)val1 == (Object^)val2) return true;"); sb.AppendLine("if ((Object^)val1 == nullptr || (Object^)val2 == nullptr) return false;"); sb.AppendLine("return (val1->_native == val2->_native);"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("static bool operator != (" + type.Name + "^ val1, " + type.Name + "^ val2)"); sb.AppendLine("{"); sb.AppendLine("\treturn !(val1 == val2);"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("virtual int GetHashCode() override"); sb.AppendLine("{"); sb.AppendLine("\treturn reinterpret_cast<int>( _native );"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("property IntPtr NativePtr"); sb.AppendLine("{"); sb.AppendLine("\tIntPtr get() { return (IntPtr)_sharedPtr; }"); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("property bool Unique"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("bool get()"); sb.AppendLine("{"); sb.AppendLine("\treturn (*_sharedPtr).unique();"); sb.AppendLine("}"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("property int UseCount"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("int get()"); sb.AppendLine("{"); sb.AppendLine("\treturn (*_sharedPtr).useCount();"); sb.AppendLine("}"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); //sb.AppendLine("void SetNull()"); //sb.AppendLine("{"); //sb.AppendLine("\t(*_sharedPtr).setNull();"); //sb.AppendLine("\t_native = 0;"); //sb.AppendLine("}"); //sb.AppendLine(); sb.AppendLine("property bool IsNull"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine("bool get()"); sb.AppendLine("{"); sb.AppendLine("\treturn (*_sharedPtr).isNull();"); sb.AppendLine("}"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("property " + baseClass + "^ Target"); sb.AppendLine("{"); sb.IncreaseIndent(); sb.AppendLine(baseClass + "^ get()"); sb.AppendLine("{"); sb.AppendLine("\treturn static_cast<" + nativeClass + "*>(_native);"); sb.AppendLine("}"); sb.DecreaseIndent(); sb.AppendLine("}"); sb.DecreaseIndent(); sb.AppendLine("};\n\n"); }
public void IsZeroSizedReferenceType_NonEmptyType_ReturnsFalse(string className) { DefType nonEmptyClass = _testModule.GetType("Marshalling", className); Assert.False(nonEmptyClass.IsZeroSizedReferenceType); }
public virtual void AddTypeDependancy(DefType type) { if (!UsedTypes.Contains(type)) this.UsedTypes.Add(type); }
public void IsZeroSizedReferenceType_EmptyType_ReturnsTrue(string className) { DefType emptyClass = _testModule.GetType("Marshalling", className); Assert.True(emptyClass.IsZeroSizedReferenceType); }
public void CppAddType(DefType t, IndentStringBuilder sb) { if (t.HasAttribute<CustomCppClassDefinitionAttribute>()) { string txt = t.GetAttribute<CustomCppClassDefinitionAttribute>().Text; sb.AppendLine(txt); return; } if (t is DefClass) { if (!t.HasAttribute<WrapTypeAttribute>()) { //Ignore } else { switch (t.GetAttribute<WrapTypeAttribute>().WrapType) { case WrapTypes.NonOverridable: new CppNonOverridableClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.Overridable: new CppOverridableClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.Interface: new CppOverridableClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.NativeDirector: new CppNativeDirectorClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.NativePtrValueType: new CppNativePtrValueClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.Singleton: new CppSingletonClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.CLRHandle: new CppCLRHandleClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.PlainWrapper: new CppPlainWrapperClassProducer(this, t as DefClass, sb).Add(); break; } } } else if (t is DefTypeDef) { DefTypeDef explicitType; if (t.IsUnnamedSTLContainer) explicitType = t as DefTypeDef; else explicitType = (t.IsNested) ? t.ParentClass.FindType<DefTypeDef>(t.Name) : t.NameSpace.FindType<DefTypeDef>(t.Name); if (explicitType.IsSTLContainer) { CppAddSTLContainer(explicitType, sb); } else if (explicitType is DefIterator) { CppAddIterator(explicitType as DefIterator, sb); } } }
protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) { AppendName(sb, containingType); sb.Append('+'); string ns = GetTypeNamespace(nestedType); if (ns.Length > 0) { AppendEscapedIdentifier(sb, ns); sb.Append('.'); } AppendEscapedIdentifier(sb, GetTypeName(nestedType)); }
public void IncAddType(DefType t, IndentStringBuilder sb) { if (t.HasAttribute<CustomIncClassDefinitionAttribute>()) { string txt = t.GetAttribute<CustomIncClassDefinitionAttribute>().Text; sb.AppendLine(txt); return; } if (t is DefClass) { if (!t.HasAttribute<WrapTypeAttribute>()) { //Ignore } else { switch (t.GetAttribute<WrapTypeAttribute>().WrapType) { case WrapTypes.NonOverridable: new IncNonOverridableClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.Overridable: new IncOverridableClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.NativeDirector: new IncNativeDirectorClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.Interface: new IncInterfaceClassProducer(this, t as DefClass, sb).Add(); new IncOverridableClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.Singleton: new IncSingletonClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.ReadOnlyStruct: new IncReadOnlyStructClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.ValueType: new IncValueClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.NativePtrValueType: new IncNativePtrValueClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.CLRHandle: new IncCLRHandleClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.PlainWrapper: new IncPlainWrapperClassProducer(this, t as DefClass, sb).Add(); break; case WrapTypes.SharedPtr: IncAddSharedPtrType(t, sb); break; } } } else if (t is DefEnum) { IncAddEnum(t as DefEnum, sb); } else if (t is DefTypeDef) { DefTypeDef explicitType; if (t.IsUnnamedSTLContainer) explicitType = t as DefTypeDef; else explicitType = (t.IsNested) ? t.ParentClass.FindType<DefTypeDef>(t.Name) : t.NameSpace.FindType<DefTypeDef>(t.Name); if (t.HasWrapType(WrapTypes.SharedPtr)) { IncAddSharedPtrType(t, sb); } else if (explicitType.IsSTLContainer) { IncAddSTLContainer(explicitType, sb); } else if (explicitType is DefIterator) { IncAddIterator(explicitType as DefIterator, sb); } else if (explicitType.BaseType is DefInternal) { IncAddInternalTypeDef(explicitType, sb); } else if (explicitType.BaseType.HasAttribute<ValueTypeAttribute>()) { IncAddValueTypeTypeDef(explicitType, sb); } } }
private string GetTypeNamespace(DefType type) { return(type.Namespace); }
protected virtual void AddTypeDependancy(DefType type) { }
protected virtual void CheckTypeForDependancy(DefType type) { _wrapper.CheckTypeForDependancy(type); }