Пример #1
0
        public static void Fill_FieldDef(tMD_TypeDef *pParentType, FieldInfo fieldInfo, tMD_FieldDef *pFieldDef,
                                         uint memOffset, uint *pAlignment, tMD_TypeDef **ppClassTypeArgs)
        {
            tMetaData *pMetaData;
            uint       fieldSize;
            uint       fieldAlignment;

            if (pFieldDef->isFilled == 1)
            {
                return;
            }
            pFieldDef->isFilled = 1;

            pFieldDef->pParentType = pParentType;

            pFieldDef->pType = MonoType.GetTypeForMonoType(fieldInfo.FieldType, ppClassTypeArgs, null);
            if (pFieldDef->pType == null)
            {
                // If the field is a core generic type definition, then we can't do anything more
                return;
            }
            if (pFieldDef->pType->fillState < Type.TYPE_FILL_LAYOUT)
            {
                MetaData.Fill_TypeDef(pFieldDef->pType, null, null);
            }
            else if (pFieldDef->pType->fillState < Type.TYPE_FILL_ALL)
            {
                MetaData.Fill_Defer(pFieldDef->pType, null, null);
            }
            if (pFieldDef->pType->isValueType != 0)
            {
                fieldSize      = pFieldDef->pType->instanceMemSize;
                fieldAlignment = (pFieldDef->pType->isValueType == 0 || pFieldDef->pType->alignment == 0) ? sizeof(PTR) : pFieldDef->pType->alignment;
            }
            else
            {
                fieldSize = fieldAlignment = sizeof(PTR);
            }
            if (pAlignment != null && *pAlignment < fieldAlignment)
            {
                *pAlignment = fieldAlignment;
            }
            pFieldDef->memOffset = (memOffset + fieldAlignment - 1) & ~(fieldAlignment - 1);
            pFieldDef->memSize   = fieldSize;
            pFieldDef->pFieldDef = pFieldDef;

            pFieldDef->monoFieldInfo = new H(fieldInfo);
            pFieldDef->monoGetter    = new H(GetFieldTrampoline);
            pFieldDef->monoSetter    = new H(SetFieldTrampoline);

            pMetaData = pFieldDef->pMetaData;
        }
Пример #2
0
        public static void Fill_TypeDef(tMD_TypeDef *pTypeDef, tMD_TypeDef **ppClassTypeArgs,
                                        tMD_TypeDef **ppMethodTypeArgs, uint resolve = Type.TYPE_FILL_ALL)
        {
            uint         instanceMemSize, staticMemSize, virtualOfs, isDeferred, i, j;
            int          lastPeriod;
            tMetaData *  pMetaData;
            tMD_TypeDef *pParent;

            System.Type    monoType;
            tMD_FieldDef * pFieldDefs;
            tMD_MethodDef *pMethodDefs;

            FieldInfo[] fieldInfos = null;
            FieldInfo   fieldInfo;

            MethodInfo[]      methodInfos      = null;
            ConstructorInfo[] constructorInfos = null;
            MethodBase        methodBase;
            tMD_MethodDef *   pMethodDef;

            if (pTypeDef->fillState >= resolve)
            {
                return;
            }

            if (pTypeDef->monoType == null)
            {
                MetaData.Fill_TypeDef(pTypeDef, ppClassTypeArgs, ppMethodTypeArgs, resolve);
                return;
            }

            //Sys.printf("FILLING TYPE: %s\n", (PTR)pTypeDef->name);

            if (MetaData.typesToFill == null)
            {
                MetaData.Fill_StartDefer();
                isDeferred = 1;
            }
            else
            {
                isDeferred = 0;
            }

            if (resolve < Type.TYPE_FILL_ALL)
            {
                MetaData.Fill_Defer(pTypeDef, ppClassTypeArgs, ppMethodTypeArgs);
            }

            MetaData.Fill_GetDeferredTypeArgs(pTypeDef, ref ppClassTypeArgs, ref ppMethodTypeArgs);

            monoType  = H.ToObj(pTypeDef->monoType) as System.Type;
            pMetaData = pTypeDef->pMetaData;

            if (pTypeDef->fillState < Type.TYPE_FILL_PARENTS)
            {
                pTypeDef->fillState = Type.TYPE_FILL_PARENTS;

                // For Methods, we get only public if sealed, or public/protected if not sealed
                methodInfos = GetMethods(monoType);
                // For fields, we only get private fields for value types
                fieldInfos = GetFields(monoType);
                // For constructors, we get only public if sealed, or public/protected if not sealed
                constructorInfos = GetConstructors(monoType);

                pTypeDef->pTypeDef = pTypeDef;

                pTypeDef->pParent = MonoType.GetTypeForMonoType(monoType.BaseType, null, null);
                pParent           = pTypeDef->pParent;

                pTypeDef->isValueType = (byte)(monoType.IsValueType ? 1 : 0);

                if (pParent != null)
                {
                    MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_PARENTS);
                    if (pParent->hasMonoBase == 0)
                    {
                        // If we have a mono base type, we have at least 1 non-blittable field
                        pTypeDef->blittable      = pParent->blittable;
                        pTypeDef->fixedBlittable = pParent->fixedBlittable;
                    }
                    else
                    {
                        pTypeDef->blittable = pTypeDef->fixedBlittable = 0;
                    }
                }
                else
                {
                    // For mono types - reference types are NEVER blittable in our implementation
                    pTypeDef->blittable = pTypeDef->fixedBlittable = pTypeDef->isValueType;
                }

                pTypeDef->alignment = 1;

                // Mark all ref types as having a base Mono Handle pointer as the first slot in their instance data.  This allows
                // the Heap system to call FREE on this Handle whenever we garbage collect mono wrapped or derived heap objects.
                pTypeDef->hasMonoBase = (byte)(monoType.IsValueType ? 0 : 1);

                // If not primed, then work out how many methods & fields there are.
                if (pTypeDef->isPrimed == 0)
                {
                    // Methods
                    pTypeDef->numMethods = (uint)(constructorInfos.Length + methodInfos.Length);
                    // Fields
                    pTypeDef->numFields = (uint)fieldInfos.Length;
                }

                // If this is an enum type, then pretend its stack type is its underlying type
                if (pTypeDef->pParent == Type.types[Type.TYPE_SYSTEM_ENUM])
                {
                    pTypeDef->stackType        = EvalStack.EVALSTACK_INT32;
                    pTypeDef->stackSize        = sizeof(PTR);
                    pTypeDef->instanceMemSize  = 4;
                    pTypeDef->arrayElementSize = 4;
                    pTypeDef->blittable        = pTypeDef->fixedBlittable = 1;
                }

                if (pTypeDef->fillState >= resolve)
                {
                    return;
                }
            }
            else
            {
                pParent = pTypeDef->pParent;
            }

            if (pTypeDef->fillState < Type.TYPE_FILL_LAYOUT)
            {
                pTypeDef->fillState = Type.TYPE_FILL_LAYOUT;

                if (pParent != null)
                {
                    if (pParent->fillState < Type.TYPE_FILL_LAYOUT)
                    {
                        MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_LAYOUT);
                    }
                    else if (pParent->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pParent, null, null);
                    }
                }

                // This only needs to be done for non-generic Type.types, or for generic type that are not a definition
                // I.e. Fully instantiated generic Type.types
                if (pTypeDef->isGenericDefinition == 0)
                {
                    // For fields, we only get private fields for value types
                    if (fieldInfos == null)
                    {
                        fieldInfos = GetFields(monoType);
                    }

                    // Resolve fields, members, interfaces.
                    // Only needs to be done if it's not a generic definition type

                    // It it's not a value-type and the stack-size is not preset, then set it up now.
                    // It needs to be done here as non-static fields in non-value type can point to the containing type
                    if (pTypeDef->stackSize == 0 && pTypeDef->isValueType == 0)
                    {
                        pTypeDef->stackType = EvalStack.EVALSTACK_O;
                        pTypeDef->stackSize = sizeof(PTR);
                        pTypeDef->alignment = sizeof(PTR);
                    }
                    // Resolve all fields - instance ONLY at this point,
                    // because static fields in value-Type.types can be of the containing type, and the size is not yet known.
                    staticMemSize = 0;
                    if (pTypeDef->numFields > 0)
                    {
                        pTypeDef->ppFields = (tMD_FieldDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numFields * sizeof(tMD_FieldDef *)));
                        pFieldDefs         = (tMD_FieldDef *)Mem.mallocForever((SIZE_T)(pTypeDef->numFields * sizeof(tMD_FieldDef)));
                        Mem.memset(pFieldDefs, 0, (SIZE_T)(pTypeDef->numFields * sizeof(tMD_FieldDef)));
                    }
                    else
                    {
                        pFieldDefs = null;
                    }
                    instanceMemSize = 0;
                    for (i = 0; i < fieldInfos.Length; i++)
                    {
                        fieldInfo = fieldInfos[i];
                        tMD_FieldDef *pFieldDef = &pFieldDefs[i];

                        pFieldDef->name  = new S(fieldInfo.Name);
                        pFieldDef->flags = (ushort)(
                            (fieldInfo.IsStatic ? MetaData.FIELDATTRIBUTES_STATIC : 0) |
                            (fieldInfo.IsLiteral ? MetaData.FIELDATTRIBUTES_LITERAL : 0)
                            );

                        if (!fieldInfo.IsStatic)
                        {
                            if (fieldInfo.IsLiteral /*|| MetaData.FIELD_HASFIELDRVA(pFieldDef)*/)
                            {
                                // If it's a literal, then analyse the field, but don't include it in any memory allocation
                                // If is has an RVA, then analyse the field, but don't include it in any memory allocation
                                MonoType.Fill_FieldDef(pTypeDef, fieldInfo, pFieldDef, 0, null, ppClassTypeArgs);
                            }
                            else
                            {
                                MonoType.Fill_FieldDef(pTypeDef, fieldInfo, pFieldDef, instanceMemSize, &(pTypeDef->alignment), ppClassTypeArgs);
                                instanceMemSize = pFieldDef->memOffset + pFieldDef->memSize;
                            }
                            // Update blittable and fixedBlittable status for type - if any non-blittable fields are included set to 0
                            if (pTypeDef->blittable != 0 || pTypeDef->fixedBlittable != 0)
                            {
                                if (pFieldDef->pType->isValueType == 0 || pFieldDef->pType->blittable == 0)
                                {
                                    pTypeDef->blittable = pTypeDef->fixedBlittable = 0;
                                }
                                else if (pFieldDef->pType->typeInitId == Type.TYPE_SYSTEM_INTPTR ||
                                         pFieldDef->pType->typeInitId == Type.TYPE_SYSTEM_UINTPTR)
                                {
                                    pTypeDef->fixedBlittable = 0;
                                }
                            }
                            pTypeDef->ppFields[i] = pFieldDef;
                        }
                    }
                    if (pTypeDef->instanceMemSize == 0)
                    {
                        if (pTypeDef->isValueType != 0)
                        {
                            // Our dna value types are the same size as they are in mono (hopefully!)
                            pTypeDef->instanceMemSize = (instanceMemSize + (pTypeDef->alignment - 1)) & ~(pTypeDef->alignment - 1);
                        }
                        else
                        {
                            // For mono reference types, the instance size is ALWAYS ptr size because we're wrapping a mono GCHandle pointer
                            pTypeDef->instanceMemSize = sizeof(PTR);
                        }
                    }

                    // Sort out stack type and size.
                    // Note that this may already be set, as some basic type have this preset;
                    // or if it's not a value-type it'll already be set
                    if (pTypeDef->stackSize == 0)
                    {
                        // if it gets here then it must be a value type
                        pTypeDef->stackType = EvalStack.EVALSTACK_VALUETYPE;
                        pTypeDef->stackSize = pTypeDef->instanceMemSize;
                    }

                    // Sort out array element size. Note that some basic type will have this preset.
                    if (pTypeDef->arrayElementSize == 0)
                    {
                        pTypeDef->arrayElementSize = pTypeDef->stackSize;
                    }

                    // Make sure stack size is even multiple of stack alignment
                    pTypeDef->stackSize = (pTypeDef->stackSize + (STACK_ALIGNMENT - 1)) & ~(STACK_ALIGNMENT - 1);

                    // Handle static fields
                    for (i = 0; i < fieldInfos.Length; i++)
                    {
                        fieldInfo = fieldInfos[i];
                        tMD_FieldDef *pFieldDef = &pFieldDefs[i];

                        if (fieldInfo.IsStatic)
                        {
                            if (fieldInfo.IsLiteral /*|| MetaData.FIELD_HASFIELDRVA(pFieldDef)*/)
                            {
                                // If it's a literal, then analyse the field, but don't include it in any memory allocation
                                // If is has an RVA, then analyse the field, but don't include it in any memory allocation
                                MonoType.Fill_FieldDef(pTypeDef, fieldInfo, pFieldDef, 0, null, ppClassTypeArgs);
                            }
                            else
                            {
                                MonoType.Fill_FieldDef(pTypeDef, fieldInfo, pFieldDef, staticMemSize, null, ppClassTypeArgs);
                                staticMemSize += pFieldDef->memSize;
                            }
                            pTypeDef->ppFields[i] = pFieldDef;
                        }
                    }
                }

                if (pTypeDef->fillState >= resolve)
                {
                    return;
                }
            }

            if (pTypeDef->fillState < Type.TYPE_FILL_VTABLE)
            {
                pTypeDef->fillState = Type.TYPE_FILL_VTABLE;

                if (pParent != null)
                {
                    if (pParent->fillState < Type.TYPE_FILL_VTABLE)
                    {
                        MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_VTABLE);
                    }
                    else if (pParent->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pParent, null, null);
                    }
                }

                // This only needs to be done for non-generic Type.types, or for generic type that are not a definition
                // I.e. Fully instantiated generic Type.types
                if (pTypeDef->isGenericDefinition == 0)
                {
                    virtualOfs = (pParent != null) ? pParent->numVirtualMethods : 0;

                    // For Methods, we get only public if sealed, or public/protected if not sealed
                    if (methodInfos == null)
                    {
                        methodInfos = GetMethods(monoType);
                    }
                    // For constructors, we get only public if sealed, or public/protected if not sealed
                    if (constructorInfos == null)
                    {
                        constructorInfos = GetConstructors(monoType);
                    }

                    // Populate methods
                    pTypeDef->ppMethods = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numMethods * sizeof(tMD_MethodDef *)));
                    pMethodDefs         = (tMD_MethodDef *)Mem.mallocForever((SIZE_T)(pTypeDef->numMethods * sizeof(tMD_MethodDef)));
                    Mem.memset(pMethodDefs, 0, (SIZE_T)(pTypeDef->numMethods * sizeof(tMD_MethodDef)));
                    for (i = 0; i < pTypeDef->numMethods; i++)
                    {
                        methodBase = (i < constructorInfos.Length) ?
                                     (MethodBase)constructorInfos[i] : methodInfos[i - constructorInfos.Length];
                        pMethodDef = &pMethodDefs[i];

                        lastPeriod = methodBase.Name.LastIndexOf('.');
                        if (methodBase is ConstructorInfo || lastPeriod == -1)
                        {
                            pMethodDef->name = new S(methodBase.Name);
                        }
                        else
                        {
                            string nameMinusExclInterfaceName = methodBase.Name.Substring(lastPeriod + 1);
                            pMethodDef->name = new S(nameMinusExclInterfaceName);
                        }

                        pMethodDef->monoMethodInfo = new H(methodBase);
                        pMethodDef->pMetaData      = pMetaData;
                        pMethodDef->pParentType    = pTypeDef;
                        pMethodDef->flags          = (ushort)(
                            (methodBase.IsVirtual ? MetaData.METHODATTRIBUTES_VIRTUAL : 0) |
                            (methodBase.IsStatic ? MetaData.METHODATTRIBUTES_STATIC : 0));

                        // NOTE: All mono calls are considered internal calls
                        pMethodDef->implFlags  = (ushort)MetaData.METHODIMPLATTRIBUTES_INTERNALCALL;
                        pTypeDef->ppMethods[i] = pMethodDef;

                        // Assign vtable slots
                        if (methodBase.IsVirtual)
                        {
                            if (((MethodInfo)methodBase).GetBaseDefinition().DeclaringType == monoType)
                            {
                                // Allocate a new vTable slot if method is explicitly marked as NewSlot, or
                                // this is of type Object.
                                pMethodDef->vTableOfs = virtualOfs++;
                            }
                            else
                            {
                                tMD_MethodDef *pVirtualOveriddenMethod;
                                pVirtualOveriddenMethod = MetaData.FindVirtualOverriddenMethod(pTypeDef->pParent, pMethodDef);
                                if (pVirtualOveriddenMethod == null)
                                {
                                    if (pTypeDef->pParent->monoType == null)
                                    {
                                        // DNA types don't always have all base methods that Unity/Mono has.  In those
                                        // cases, just add the missing method to the VTable as a new virtual method.
                                        pMethodDef->vTableOfs = virtualOfs++;
                                    }
                                    else
                                    {
                                        Sys.Crash("Unable to find virtual override %s", (PTR)(pMethodDef->name));
                                    }
                                }
                                else
                                {
                                    pMethodDef->vTableOfs = pVirtualOveriddenMethod->vTableOfs;
                                }
                            }
                        }
                        else
                        {
                            // Dummy value - make it obvious it's not valid!
                            pMethodDef->vTableOfs = 0xffffffff;
                        }

                        pTypeDef->ppMethods[i] = pMethodDef;
                    }

                    // Create the virtual method table
                    pTypeDef->numVirtualMethods = virtualOfs;

                    // Resolve all members
                    pTypeDef->pVTable = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numVirtualMethods * sizeof(tMD_MethodDef *)));
                    // Copy initial vTable from parent
                    if (pTypeDef->pParent != null)
                    {
                        Mem.memcpy(pTypeDef->pVTable, pTypeDef->pParent->pVTable, (SIZE_T)(pTypeDef->pParent->numVirtualMethods * sizeof(tMD_MethodDef *)));
                    }
                    for (i = 0; i < pTypeDef->numMethods; i++)
                    {
                        pMethodDef = pTypeDef->ppMethods[i];
                        methodBase = H.ToObj(pMethodDef->monoMethodInfo) as MethodBase;

                        if (methodBase.IsStatic && methodBase.Name == ".cctor")
                        {
                            // This is a static constructor
                            pTypeDef->pStaticConstructor = pMethodDef;
                        }
                        if (methodBase.IsStatic && pTypeDef->pParent != null &&
                            methodBase.Name == "Finalize")
                        {
                            // This is a Finalizer method, but not for Object.
                            // Delibrately miss out Object's Finalizer because it's empty and will cause every object
                            // of any type to have a Finalizer which will be terrible for performance.
                            pTypeDef->pFinalizer = pMethodDef;
                        }
                        if (methodBase.IsVirtual)
                        {
                            if (pMethodDef->vTableOfs == 0xffffffff)
                            {
                                Sys.Crash("Illegal vtableoffset");
                            }
                            if (pMethodDef->vTableOfs >= pTypeDef->numVirtualMethods)
                            {
                                Sys.Crash("Illegal vtableoffset");
                            }
                            pTypeDef->pVTable[pMethodDef->vTableOfs] = pMethodDef;
                        }
                    }

                    // Find inherited Finalizer, if this type doesn't have an explicit Finalizer, and if there is one
                    if (pTypeDef->pFinalizer == null)
                    {
                        tMD_TypeDef *pInheritedType = pTypeDef->pParent;
                        while (pInheritedType != null)
                        {
                            if (pInheritedType->pFinalizer != null)
                            {
                                pTypeDef->pFinalizer = pInheritedType->pFinalizer;
                                break;
                            }
                            pInheritedType = pInheritedType->pParent;
                        }
                    }
                }

                if (pTypeDef->fillState >= resolve)
                {
                    return;
                }
            }

            if (pTypeDef->fillState < Type.TYPE_FILL_MEMBERS)
            {
                pTypeDef->fillState = Type.TYPE_FILL_MEMBERS;

                if (pParent != null)
                {
                    if (pParent->fillState < Type.TYPE_FILL_MEMBERS)
                    {
                        MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_MEMBERS);
                    }
                    else if (pParent->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pParent, null, null);
                    }
                }

                // This only needs to be done for non-generic Type.types, or for generic type that are not a definition
                // I.e. Fully instantiated generic Type.types
                if (pTypeDef->isGenericDefinition == 0)
                {
                    // Fill all method definitions for this type
                    for (i = 0; i < pTypeDef->numMethods; i++)
                    {
                        pMethodDef = pTypeDef->ppMethods[i];
                        methodBase = H.ToObj(pMethodDef->monoMethodInfo) as MethodBase;
                        MonoType.Fill_MethodDef(pTypeDef, methodBase, pTypeDef->ppMethods[i], ppClassTypeArgs, ppMethodTypeArgs);
                    }
                }

                if (pTypeDef->fillState >= resolve)
                {
                    return;
                }
            }

            if (pTypeDef->fillState < Type.TYPE_FILL_INTERFACES)
            {
                pTypeDef->fillState = Type.TYPE_FILL_INTERFACES;

                if (pParent != null)
                {
                    if (pParent->fillState < Type.TYPE_FILL_INTERFACES)
                    {
                        MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_INTERFACES);
                    }
                    else if (pParent->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pParent, null, null);
                    }
                }

                // This only needs to be done for non-generic Type.types, or for generic type that are not a definition
                // I.e. Fully instantiated generic Type.types
                if (pTypeDef->isGenericDefinition == 0)
                {
                    // Map all interface method calls. This only needs to be done for Classes, not Interfaces
                    // And is not done for generic definitions.
                    if (!monoType.IsInterface)
                    {
                        System.Type[] interfaceTypes = monoType.GetInterfaces();
                        pTypeDef->numInterfaces = (uint)interfaceTypes.Length;
                        if (interfaceTypes.Length > 0 && pTypeDef->isGenericDefinition == 0)
                        {
                            if (pTypeDef->pInterfaceMaps == null)
                            {
                                pTypeDef->pInterfaceMaps = (tInterfaceMap *)Mem.mallocForever((SIZE_T)(pTypeDef->numInterfaces * sizeof(tInterfaceMap)));
                            }
                            for (i = 0; i < interfaceTypes.Length; i++)
                            {
                                // Get the interface that this type implements
                                tMD_TypeDef *pInterface = MonoType.GetTypeForMonoType(interfaceTypes[i], ppClassTypeArgs, ppMethodTypeArgs);
                                Fill_TypeDef(pInterface, ppClassTypeArgs, null, Type.TYPE_FILL_VTABLE);
                                InterfaceMapping interfaceMapping = monoType.GetInterfaceMap(interfaceTypes[i]);
                                MetaData.Fill_TypeDef(pInterface, null, null);
                                tInterfaceMap *pMap = &pTypeDef->pInterfaceMaps[i];
                                pMap->pInterface      = pInterface;
                                pMap->pVTableLookup   = (uint *)Mem.mallocForever((SIZE_T)(pInterface->numVirtualMethods * sizeof(uint)));
                                pMap->ppMethodVLookup = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pInterface->numVirtualMethods * sizeof(tMD_MethodDef *)));
                                MethodInfo[] interfaceMethods = interfaceMapping.InterfaceMethods;
                                MethodInfo[] targetMethods    = interfaceMapping.TargetMethods;
                                // Discover interface mapping for each interface method
                                for (j = 0; j < pInterface->numVirtualMethods; j++)
                                {
                                    tMD_MethodDef *pInterfaceMethod  = pInterface->pVTable[j];
                                    tMD_MethodDef *pOverriddenMethod = FindInterfaceOverriddenMethod(pInterfaceMethod, interfaceMethods, targetMethods);
                                    if (pOverriddenMethod == null)
                                    {
                                        Sys.Crash("Unable to find override method %s in type %s.%s for interface %s.%s", (PTR)(pInterfaceMethod->name),
                                                  (PTR)pTypeDef->nameSpace, (PTR)pTypeDef->name,
                                                  (PTR)pInterface->nameSpace, (PTR)pInterface->name);
                                    }
                                    pMap->pVTableLookup[j]   = pOverriddenMethod->vTableOfs;
                                    pMap->ppMethodVLookup[j] = pOverriddenMethod;
                                }
                            }
                        }
                    }
                }

                if (pTypeDef->fillState >= resolve)
                {
                    return;
                }
            }

            if (pTypeDef->fillState < Type.TYPE_FILL_ALL)
            {
                pTypeDef->fillState = Type.TYPE_FILL_ALL;

                if (pParent != null && pParent->fillState < Type.TYPE_FILL_ALL)
                {
                    MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_ALL);
                }

                if (isDeferred != 0)
                {
                    MetaData.Fill_ResolveDeferred();
                }
            }

            Sys.log_f(2, "Mono Type:  %s.%s\n", (PTR)pTypeDef->nameSpace, (PTR)pTypeDef->name);
        }
Пример #3
0
        public static uint CompareNameAndSig(/*STRING*/ byte *name, /*BLOB_*/ byte *sigBlob, tMetaData *pSigMetaData,
                                             tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs,
                                             tMD_TypeDef **ppMethodMethodTypeArgs)
        {
            if (S.strcmp(name, pMethod->name) == 0)
            {
                if (pMethod->signature != null)
                {
                    /*SIG*/ byte *sig, thisSig;
                    uint          e, thisE, paramCount, i;

                    sig     = MetaData.GetBlob(sigBlob, null);
                    thisSig = MetaData.GetBlob(pMethod->signature, null);

                    e     = MetaData.DecodeSigEntry(&sig);
                    thisE = MetaData.DecodeSigEntry(&thisSig);
                    // Check method call type (static, etc...)
                    if (e != thisE)
                    {
                        return(0);
                    }

                    // If method has generic arguments, check the generic type argument count
                    if ((e & SIG_METHODDEF_GENERIC) != 0)
                    {
                        e     = MetaData.DecodeSigEntry(&sig);
                        thisE = MetaData.DecodeSigEntry(&thisSig);
                        // Generic argument count
                        if (e != thisE)
                        {
                            return(0);
                        }
                    }

                    e     = MetaData.DecodeSigEntry(&sig);
                    thisE = MetaData.DecodeSigEntry(&thisSig);
                    // check parameter count
                    if (e != thisE)
                    {
                        return(0);
                    }
                    paramCount = e + 1;         // +1 to include the return type

                    // check all parameters
                    for (i = 0; i < paramCount; i++)
                    {
                        tMD_TypeDef *pParamType;
                        tMD_TypeDef *pThisParamType;

                        pParamType = Type.GetTypeFromSig(pSigMetaData, &sig,
                                                         ppSigClassTypeArgs, ppSigMethodTypeArgs, null);
                        pThisParamType = Type.GetTypeFromSig(pMethod->pMetaData, &thisSig,
                                                             ppMethodClassTypeArgs, ppMethodMethodTypeArgs, null);
                        if (pParamType != pThisParamType)
                        {
                            return(0);
                        }
                    }

                    // All parameters the same, so found the right method
                    return(1);
                }
                else if (pMethod->monoMethodInfo != null)
                {
                    /*SIG*/
                    byte *     sig;
                    uint       e, paramCount, i;
                    MethodBase methodBase = H.ToObj(pMethod->monoMethodInfo) as MethodBase;

                    sig = MetaData.GetBlob(sigBlob, null);

                    e = MetaData.DecodeSigEntry(&sig);
                    // Check method call type (static, etc...)
                    if (methodBase.IsStatic && (e & (SIG_METHODDEF_HASTHIS | SIG_METHODDEF_EXPLICITTHIS)) != 0)
                    {
                        return(0);
                    }

                    // If method has generic arguments, check the generic type argument count
                    if ((e & SIG_METHODDEF_GENERIC) != 0)
                    {
                        if (!methodBase.IsGenericMethod)
                        {
                            return(0);
                        }

                        e = MetaData.DecodeSigEntry(&sig);
                        // Generic argument count
                        if (e != methodBase.GetGenericArguments().Length)
                        {
                            return(0);
                        }
                    }

                    paramCount = MetaData.DecodeSigEntry(&sig);
                    System.Reflection.ParameterInfo[] paramInfos = methodBase.GetParameters();
                    if (paramCount != paramInfos.Length)
                    {
                        return(0);
                    }

                    tMD_TypeDef *pReturnType = Type.GetTypeFromSig(pSigMetaData, &sig,
                                                                   ppSigClassTypeArgs, ppSigMethodTypeArgs, null);
                    if (methodBase is MethodInfo)
                    {
                        tMD_TypeDef *pThisReturnType = MonoType.GetTypeForMonoType(((MethodInfo)methodBase).ReturnType,
                                                                                   ppMethodClassTypeArgs, ppMethodMethodTypeArgs);
                        if (pReturnType == null)
                        {
                            if (pThisReturnType != Type.types[Type.TYPE_SYSTEM_VOID])
                            {
                                return(0);
                            }
                        }
                        else if (pReturnType != pThisReturnType)
                        {
                            return(0);
                        }
                    }

                    // check all parameters
                    for (i = 0; i < paramCount; i++)
                    {
                        tMD_TypeDef *pParamType;
                        tMD_TypeDef *pThisParamType;

                        pParamType = Type.GetTypeFromSig(pSigMetaData, &sig,
                                                         ppSigClassTypeArgs, ppSigMethodTypeArgs, null);
                        pThisParamType = MonoType.GetTypeForMonoType(paramInfos[i].ParameterType,
                                                                     ppMethodClassTypeArgs, ppMethodMethodTypeArgs);
                        if (pParamType != pThisParamType)
                        {
                            return(0);
                        }
                    }

                    // All parameters the same, so found the right method
                    return(1);
                }
                else
                {
                    Sys.Crash("Method with no sig or methodInfo");
                }
            }
            return(0);
        }
Пример #4
0
        /// <summary>
        /// Returns the DNA methodDef for a method given a typeDef, method name, and argument types.
        /// </summary>
        /// <param name="typeDef">The DNA typeDef for a type</param>
        /// <param name="methodName">The method name</param>
        /// <param name="argTypes">The types of the method's arguments or null if no arguments</param>
        /// <returns>The methodDef found or 0 if no method matches</returns>
        public static ulong FindMethod(ulong typeDef, string methodName, System.Type[] argTypes = null)
        {
            if (!_isInitialized)
            {
                Init();
            }

            int numArgs = argTypes != null ? argTypes.Length : 0;

            byte *mName = stackalloc byte[128];

            S.strncpy(mName, methodName, 128);

            // Find any overload of the named method; assume it's the right one.
            // Specifying it exactly (type generic args, method generic args, arguments themselves, picking the
            // inherited methods if needed), is complex and not required at the moment.
            tMD_TypeDef *  pTypeDef   = (tMD_TypeDef *)(PTR)typeDef;
            tMD_MethodDef *pMethodDef = null;
            bool           matches    = false;

            while (pTypeDef != null)
            {
                if (pTypeDef->fillState < Type.TYPE_FILL_ALL)
                {
                    MetaData.Fill_TypeDef(pTypeDef, null, null);
                }
                for (int i = 0; i < pTypeDef->numMethods; i++)
                {
                    tMD_MethodDef *pCheckMethodDef = pTypeDef->ppMethods[i];
                    int            start           = 0;
                    if (!MetaData.METHOD_ISSTATIC(pCheckMethodDef))
                    {
                        start = 1;
                    }
                    matches = false;
                    if (S.strcmp(pCheckMethodDef->name, mName) == 0 &&
                        (pCheckMethodDef->numberOfParameters - start == numArgs))
                    {
                        matches = true;
                        for (int j = start; j < pCheckMethodDef->numberOfParameters; j++)
                        {
                            tMD_TypeDef *pArgType = MonoType.GetTypeForMonoType(argTypes[j - start], null, null);
                            if (pArgType != pCheckMethodDef->pParams[j].pStackTypeDef)
                            {
                                matches = false;
                                break;
                            }
                        }
                    }
                    if (matches)
                    {
                        pMethodDef = pCheckMethodDef;
                        break;
                    }
                }
                if (matches)
                {
                    break;
                }
                pTypeDef = pTypeDef->pParent;
            }

            return((ulong)pMethodDef);
        }
Пример #5
0
        public static uint CompareNameAndMethodInfo(/*STRING*/ byte *name, System.Reflection.MethodBase methodBase, tMetaData *pSigMetaData,
                                                    tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs,
                                                    tMD_TypeDef **ppMethodMethodTypeArgs)
        {
            if (S.strcmp(name, pMethod->name) == 0)
            {
                uint i;

                if (METHOD_ISSTATIC(pMethod) != methodBase.IsStatic ||
                    METHOD_ISVIRTUAL(pMethod) != methodBase.IsVirtual)
                {
                    return(0);
                }

                System.Reflection.ParameterInfo[] paramInfos = methodBase.GetParameters();

                uint numberOfParameters = (uint)(paramInfos.Length + (methodBase.IsStatic ? 0 : 1));
                if ((uint)pMethod->numberOfParameters != numberOfParameters)
                {
                    return(0);
                }

                if (methodBase.IsGenericMethod != (pMethod->isGenericDefinition != 0))
                {
                    return(0);
                }

                if (methodBase is MethodInfo)
                {
                    if (pMethod->pReturnType == null)
                    {
                        if (((MethodInfo)methodBase).ReturnType != typeof(void))
                        {
                            return(0);
                        }
                    }
                    else if (pMethod->pReturnType != MonoType.GetTypeForMonoType(((MethodInfo)methodBase).ReturnType,
                                                                                 ppMethodClassTypeArgs, ppMethodMethodTypeArgs))
                    {
                        return(0);
                    }
                }

                uint start = 0;
                if (!methodBase.IsStatic)
                {
//                    if (pMethod->pParams[0].pStackTypeDef != MonoType.GetTypeForMonoType(methodInfo.DeclaringType))
//                        return 0;
                    start = 1;
                }

                for (i = start; i < numberOfParameters; i++)
                {
                    tParameter *pParam = &pMethod->pParams[i];
                    System.Reflection.ParameterInfo paramInfo = paramInfos[i - start];

                    // NOTE: We are not checking to see if params are REF params here.  Potentially a problem.
                    if (pParam->pStackTypeDef != MonoType.GetTypeForMonoType(paramInfo.ParameterType,
                                                                             ppMethodClassTypeArgs, ppMethodMethodTypeArgs))
                    {
                        return(0);
                    }
                }

                return(1);
            }
            return(0);
        }