Ejemplo n.º 1
0
        public static int Call(tMD_MethodDef *pMethod, byte *pParams, byte *pReturnValue)
        {
            uint     status;
            tThread *pThread;

            // Check to see if we have a call thread already available
            if (pCallThread == null)
            {
                pCallThread = Thread.New();
            }

            // Hang on to this thread in case the method returns async..
            pThread     = pLastCallThread = pCallThread;
            pCallThread = null;

            // Set up the initial MethodState
            pThread->pCurrentMethodState = MethodState.Direct(pThread, pMethod, null, 0);

            // Insert initial parameters (if any)
            if (pParams != null)
            {
                MethodState.SetParameters(pThread->pCurrentMethodState, pMethod, pParams);
            }

            // Set the initial thread to the RUNNING state.
            pThread->state = THREADSTATE_RUNNING;
            // Set the initial CurrentThread
            pCurrentThread = pThread;

            pLastCallThread = pThread;

            status = THREAD_STATUS_RUNNING;
            while (status == THREAD_STATUS_RUNNING)
            {
                status = JIT_Execute.Execute(pThread, 1000000);
                switch (status)
                {
                case Thread.THREAD_STATUS_EXIT:
                    if (pReturnValue != null)
                    {
                        MethodState.GetReturnValue(pThread->pCurrentMethodState, pReturnValue);
                    }
                    // Thread exited normally, put it back so it can be reused by next call
                    Thread.Reset(pThread);
                    pCallThread = pThread;
                    break;

                case Thread.THREAD_STATUS_RUNNING:
                case Thread.THREAD_STATUS_LOCK_EXIT:
                    // Nothing to do
                    break;

                case Thread.THREAD_STATUS_ASYNC:
                    pThread->pAsync->startTime = Sys.msTime();
                    break;
                }
            }

            return((int)status);
        }
Ejemplo n.º 2
0
        static void * /*fnInternalCall*/ Map_Delegate(tMD_MethodDef *pMethod)
        {
//            // Note that it is not neccessary to check argument type here, as delegates are very tightly controlled
//            if (S.strcmp(pMethod->name, ".ctor") == 0) {
//                return ctor;
//            }

            return(null);
        }
Ejemplo n.º 3
0
        public static tMD_MethodDef *GetMethodDefFromCoreMethod(tMD_MethodDef *pCoreMethod,
                                                                tMD_TypeDef *pParentType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs,
                                                                HashSet <PTR> resolveTypes = null)
        {
            tGenericMethodInstance *pInst;
            tMD_MethodDef *         pMethod;
            int i;

            Mem.heapcheck();

            // See if we already have an instance with the given type args
            pInst = pCoreMethod->pGenericMethodInstances;
            while (pInst != null)
            {
                if (pInst->numTypeArgs == numTypeArgs &&
                    Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0)
                {
                    return(pInst->pInstanceMethodDef);
                }
                pInst = pInst->pNext;
            }

            // We don't have an instance so create one now.
            pInst        = (tGenericMethodInstance *)Mem.mallocForever((SIZE_T)(sizeof(tGenericMethodInstance)));
            pInst->pNext = pCoreMethod->pGenericMethodInstances;
            pCoreMethod->pGenericMethodInstances = pInst;
            pInst->numTypeArgs = numTypeArgs;
            pInst->ppTypeArgs  = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));
            Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));

            pInst->pInstanceMethodDef = pMethod = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef)));
            Mem.memset(pMethod, 0, (SIZE_T)sizeof(tMD_MethodDef));
            pMethod->pMethodDef       = pMethod;
            pMethod->pMetaData        = pCoreMethod->pMetaData;
            pMethod->pCIL             = pCoreMethod->pCIL;
            pMethod->implFlags        = pCoreMethod->implFlags;
            pMethod->flags            = pCoreMethod->flags;
            pMethod->name             = pCoreMethod->name;
            pMethod->signature        = pCoreMethod->signature;
            pMethod->vTableOfs        = pCoreMethod->vTableOfs;
            pMethod->ppMethodTypeArgs = pInst->ppTypeArgs;

            MetaData.Fill_MethodDef(pParentType, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs);

            Mem.heapcheck();

            return(pMethod);
        }
Ejemplo n.º 4
0
 public static /*fnInternalCall*/ void *Map(tMD_MethodDef *pMethod)
 {
     if (pMethod->monoMethodCall != null)
     {
         return(pMethod->monoMethodCall);
     }
     else if (pMethod->pParentType->pParent == Type.types[Type.TYPE_SYSTEM_MULTICASTDELEGATE])
     {
         // Special case to handle delegates
         /*fnInternalCall*/ void *fn = Map_Delegate(pMethod);
         if (fn != null)
         {
             return(fn);
         }
     }
     else
     {
         /*STRING*/ byte *curNameSpace = null;
         /*STRING*/ byte *curType      = null;
         for (int i = 0; i < internalCalls.Length; i++)
         {
             fixed(tInternalCall *pCall = &internalCalls[i])
             {
                 if (pCall->nameSpace != null)
                 {
                     curNameSpace = pCall->nameSpace;
                 }
                 if (pCall->type != null)
                 {
                     curType = pCall->type;
                 }
                 if (S.strcmp(pMethod->pParentType->nameSpace, curNameSpace) == 0)
                 {
                     if (S.strcmp(pMethod->pParentType->name, curType) == 0)
                     {
                         if (Type.IsMethod(pMethod, pCall->method, Type.types[pCall->returnType], pCall->numParameters, pCall->parameterTypes) != 0)
                         {
                             return(pCall->fn);
                         }
                     }
                 }
             }
         }
     }
     Sys.Crash("InternalCall_Map(): Cannot map [%s]%s.%s", (PTR)pMethod->pParentType->nameSpace, (PTR)pMethod->pParentType->name, (PTR)pMethod->name);
     return(null);
 }
Ejemplo n.º 5
0
        public static tMethodState *Direct(tThread *pThread, tMD_MethodDef *pMethod, tMethodState *pCaller, uint isInternalNewObjCall)
        {
            tMethodState *pThis;

            Mem.heapcheck();

            if (pMethod->isFilled == 0)
            {
                tMD_TypeDef *pTypeDef;

                pTypeDef = MetaData.GetTypeDefFromMethodDef(pMethod);
                MetaData.Fill_TypeDef(pTypeDef, null, null);
            }

            pThis = (tMethodState *)Thread.StackAlloc(pThread, (uint)sizeof(tMethodState));
            pThis->finalizerThis = null;
            pThis->pCaller       = pCaller;
            pThis->pMetaData     = pMethod->pMetaData;
            pThis->pMethod       = pMethod;
            if (pMethod->pJITted == null)
            {
                // If method has not already been JITted
                JIT.Prepare(pMethod, 0);
            }
            pThis->pJIT                 = pMethod->pJITted;
            pThis->ipOffset             = 0;
            pThis->pEvalStack           = (byte *)Thread.StackAlloc(pThread, pThis->pMethod->pJITted->maxStack);
            pThis->stackOfs             = 0;
            pThis->isInternalNewObjCall = isInternalNewObjCall;
            pThis->pNextDelegate        = null;
            pThis->pDelegateParams      = null;

            pThis->pParamsLocals = (byte *)Thread.StackAlloc(pThread, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize);
            Mem.memset(pThis->pParamsLocals, 0, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize);

#if DIAG_METHOD_CALLS
            // Keep track of the number of times this method is called
            pMethod->callCount++;
            pThis->startTime = microTime();
#endif

            Mem.heapcheck();

            return(pThis);
        }
Ejemplo n.º 6
0
        public static tMD_TypeDef *GetTypeDefFromMethodDef(tMD_MethodDef *pMethodDef)
        {
            tMetaData *pMetaData;
            uint       i;

            pMetaData = pMethodDef->pMetaData;
            for (i = pMetaData->tables.numRows[MetaDataTable.MD_TABLE_TYPEDEF]; i > 0; i--)
            {
                tMD_TypeDef *pTypeDef;

                pTypeDef = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_TYPEDEF, i));
                if (pTypeDef->methodList <= pMethodDef->tableIndex)
                {
                    return(pTypeDef);
                }
            }

            Sys.Crash("MetaData.GetTypeDefFromMethodDef(): Cannot find type for method: %s", (PTR)pMethodDef->name);
            return(null);
        }
Ejemplo n.º 7
0
        public static /*char*/ byte *GetMethodDesc(tMD_MethodDef *pMethod)
        {
            int i;

            byte *namePos = methodNameBuf;
            byte *nameEnd = namePos + METHOD_NAME_BUF_SIZE;

            namePos = S.scatprintf(namePos, nameEnd, "%s.%s.%s(", (PTR)pMethod->pParentType->nameSpace, (PTR)pMethod->pParentType->name, (PTR)pMethod->name);
            for (i = MetaData.METHOD_ISSTATIC(pMethod) ? 0 : 1; i < pMethod->numberOfParameters; i++)
            {
                if (i > (int)(MetaData.METHOD_ISSTATIC(pMethod) ? 0 : 1))
                {
                    namePos = S.scatprintf(namePos, nameEnd, ",");
                }
                tParameter *param = &(pMethod->pParams[i]);
                namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)param->pStackTypeDef->name);
            }
            S.scatprintf(namePos, nameEnd, ")");

            return(methodNameBuf);
        }
Ejemplo n.º 8
0
        public static tAsyncCall *GetMethod(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            // Read param
            byte *methodName = stackalloc byte[256];

            DotNetStringToCString(methodName, (uint)256, ((tSystemString **)pParams)[0]);

            // Get metadata for the 'this' type
            tRuntimeType *pRuntimeType = (tRuntimeType *)pThis_;
            tMD_TypeDef * pTypeDef     = pRuntimeType->pTypeDef;

            // Search for the method by name
            for (int i = 0; i < pTypeDef->numMethods; i++)
            {
                if (S.strcmp(pTypeDef->ppMethods[i]->name, methodName) == 0)
                {
                    tMD_MethodDef *pMethodInstDef = pTypeDef->ppMethods[i];

                    // Instantiate a MethodInfo
                    tMethodInfo *pMethodInfo = (tMethodInfo *)Heap.AllocType(Type.types[Type.TYPE_SYSTEM_REFLECTION_METHODINFO]);

                    // Assign ownerType
                    pMethodInfo->methodBase.ownerType = pThis_;

                    // Assign name
                    pMethodInfo->methodBase.name = System_String.FromCharPtrASCII(pMethodInstDef->name);

                    // Assign method def
                    pMethodInfo->methodBase.methodDef = pMethodInstDef;

                    *(/*HEAP_PTR*/ byte **)pReturnValue = (/*HEAP_PTR*/ byte *)pMethodInfo;
                    return(null);
                }
            }

            // Not found
            *(/*HEAP_PTR*/ byte **)pReturnValue = null;
            return(null);
        }
Ejemplo n.º 9
0
        public static tMD_MethodDef *FindInterfaceOverriddenMethod(tMD_MethodDef *pInterfaceMethod, MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
        {
            byte *     targetName          = stackalloc byte[256];
            MethodInfo interfaceMethodInfo = null;

            for (int i = 0; i < interfaceMethods.Length; i++)
            {
                if (S.strcmp(pInterfaceMethod->name, interfaceMethods[i].Name) == 0)
                {
                    interfaceMethodInfo = targetMethods[i];
                    break;
                }
            }
            if (interfaceMethodInfo == null)
            {
                Sys.Crash("Unable to find mapped method %s", (PTR)(pInterfaceMethod->name));
            }
            S.strncpy(targetName, interfaceMethodInfo.Name, 256);
            tMD_MethodDef *pOverriddenMethod    = null;
            tMD_TypeDef *  pInterfaceTargetType = GetTypeForMonoType(interfaceMethodInfo.DeclaringType, null, null);

            for (int i = 0; i < pInterfaceTargetType->numMethods; i++)
            {
                tMD_MethodDef *pMethodDef = pInterfaceTargetType->ppMethods[i];
                MethodInfo     methodInfo = H.ToObj(pMethodDef->monoMethodInfo) as MethodInfo;
                if (methodInfo == interfaceMethodInfo)
                {
                    return(pInterfaceTargetType->ppMethods[i]);
                }
                else if (MetaData.CompareNameAndMethodInfo(targetName, interfaceMethodInfo, pInterfaceMethod->pMetaData,
                                                           pInterfaceMethod->pParentType->ppClassTypeArgs, pInterfaceMethod->ppMethodTypeArgs,
                                                           pMethodDef, pMethodDef->pParentType->ppClassTypeArgs, null) != 0)
                {
                    return(pInterfaceTargetType->ppMethods[i]);
                }
            }
            return(null);
        }
Ejemplo n.º 10
0
 public static bool METHOD_ISVIRTUAL(tMD_MethodDef *pMethod)
 {
     return(((pMethod)->flags & METHODATTRIBUTES_VIRTUAL) != 0);
 }
Ejemplo n.º 11
0
        public static void Fill_MethodDef(tMD_TypeDef *pParentType, MethodBase methodBase, tMD_MethodDef *pMethodDef,
                                          tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs)
        {
            uint i, totalSize, start;

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

            pMethodDef->pParentType         = pParentType;
            pMethodDef->pMethodDef          = pMethodDef;
            pMethodDef->isFilled            = 1;
            pMethodDef->isGenericDefinition = (byte)(methodBase.IsGenericMethodDefinition ? 1 : 0);

            if (methodBase.IsGenericMethodDefinition)
            {
                // Generic definition method, so can't do any more.
                //Sys.log_f("Method<>: %s.%s.%s()\n", pParentType->nameSpace, pParentType->name, pMethodDef->name);
                return;
            }

            ParameterInfo[] paramInfos = methodBase.GetParameters();

            pMethodDef->numberOfParameters = (ushort)(paramInfos.Length + (methodBase.IsStatic ? 0 : 1));
            if (methodBase is MethodInfo)
            {
                pMethodDef->pReturnType = GetTypeForMonoType(((MethodInfo)methodBase).ReturnType,
                                                             ppClassTypeArgs, ppMethodTypeArgs);
            }
            else
            {
                pMethodDef->pReturnType = null;
            }
            if (pMethodDef->pReturnType == Type.types[Type.TYPE_SYSTEM_VOID])
            {
                pMethodDef->pReturnType = null;
            }
            if (pMethodDef->pReturnType != null && pMethodDef->pReturnType->fillState < Type.TYPE_FILL_ALL)
            {
                MetaData.Fill_Defer(pMethodDef->pReturnType, null, null);
            }
            pMethodDef->pParams = (tParameter *)Mem.malloc((SIZE_T)(pMethodDef->numberOfParameters * sizeof(tParameter)));
            totalSize           = 0;
            start = 0;
            if (!methodBase.IsStatic)
            {
                // Fill in parameter info for the 'this' pointer
                pMethodDef->pParams->offset = 0;
                if (pParentType->isValueType != 0)
                {
                    // If this is a value-type then the 'this' pointer is actually an IntPtr to the value-type's location
                    pMethodDef->pParams->size          = sizeof(PTR);
                    pMethodDef->pParams->pStackTypeDef = Type.types[Type.TYPE_SYSTEM_INTPTR];
                }
                else
                {
                    pMethodDef->pParams->size          = sizeof(PTR);
                    pMethodDef->pParams->pStackTypeDef = pParentType;
                }
                totalSize = sizeof(PTR);
                start     = 1;
            }
            for (i = start; i < pMethodDef->numberOfParameters; i++)
            {
                tMD_TypeDef *pStackTypeDef;
                tMD_TypeDef *pByRefTypeDef;
                uint         size;

                // NOTE: Byref values are treated as intptr's in DNA
                System.Type paramType = paramInfos[i - start].ParameterType;
                if (paramType.IsByRef)
                {
                    pStackTypeDef = Type.types[Type.TYPE_SYSTEM_INTPTR];
                    pByRefTypeDef = GetTypeForMonoType(paramType.GetElementType(),
                                                       ppClassTypeArgs, ppMethodTypeArgs);
                }
                else
                {
                    pStackTypeDef = GetTypeForMonoType(paramType,
                                                       ppClassTypeArgs, ppMethodTypeArgs);
                    pByRefTypeDef = null;
                }

                if (pStackTypeDef != null)
                {
                    if (pStackTypeDef->fillState < Type.TYPE_FILL_LAYOUT)
                    {
                        MetaData.Fill_TypeDef(pStackTypeDef, null, null, Type.TYPE_FILL_LAYOUT);
                    }
                    else if (pStackTypeDef->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pStackTypeDef, null, null);
                    }
                    size = pStackTypeDef->stackSize;
                }
                else
                {
                    size = 0;
                }
                if (pByRefTypeDef != null)
                {
                    if (pByRefTypeDef->fillState < Type.TYPE_FILL_LAYOUT)
                    {
                        MetaData.Fill_TypeDef(pByRefTypeDef, null, null, Type.TYPE_FILL_LAYOUT);
                    }
                    else if (pByRefTypeDef->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pByRefTypeDef, null, null);
                    }
                }
                pMethodDef->pParams[i].pStackTypeDef = pStackTypeDef;
                pMethodDef->pParams[i].pByRefTypeDef = pByRefTypeDef;
                pMethodDef->pParams[i].offset        = totalSize;
                pMethodDef->pParams[i].size          = size;
                totalSize += size;
            }
            pMethodDef->parameterStackSize = totalSize;

            if (pMethodDef->monoMethodInfo == null)
            {
                pMethodDef->monoMethodInfo = new H(methodBase);
            }
            if (pMethodDef->monoMethodCall == null)
            {
                pMethodDef->monoMethodCall = new H(CallMethodTrampoline);
            }
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
 public static void SetParameters(tMethodState *pMethodState, tMD_MethodDef *pCallMethod, byte *pParams)
 {
     Mem.memcpy(pMethodState->pParamsLocals, pParams, pCallMethod->parameterStackSize);
 }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Call to a DNA method given it's method def (with a byref this).
        /// </summary>
        /// <param name="methodDef">The method def</param>
        /// <param name="_this">The this object (or null if method is static)</param>
        /// <param name="args">The arguments to pass (or null for no arguments)</param>
        /// <returns>The value returned by the method.</returns>
        public static object CallRefThis(ulong methodDef, ref object _this, object[] args = null)
        {
            tMD_MethodDef *pMethodDef = (tMD_MethodDef *)methodDef;
            uint           start      = 0;
            uint           byRefSize  = 0;
            bool           byRefThis  = false;
            bool           byRefArgs  = false;
            uint           paramsSize = 0;
            uint           retValSize = 0;
            byte *         pByRefPtr;
            byte *         pStackPtr;
            object         ret = null;

            byte *pBuf    = stackalloc byte[256];
            uint  bufSize = 256;

            tMD_TypeDef *pThisType       = null;
            tMD_TypeDef *pMethodThisType = null;

            if (args == null)
            {
                args = noArgs;
            }

            // First pass.. check types and get by ref buf size..

            if (!MetaData.METHOD_ISSTATIC(pMethodDef))
            {
                if (_this == null)
                {
                    throw new System.NullReferenceException("Call to member method can not have null this");
                }
                pThisType       = MonoType.GetTypeForMonoObject(_this, null, null);
                pMethodThisType = MetaData.PARAM_ACTUAL_TYPE(&pMethodDef->pParams[0]);
                if (!MetaData.TYPE_ISASSIGNABLE_TO(pThisType, pMethodThisType))
                {
                    throw new System.InvalidOperationException("This type is not compatible with method this type");
                }
                if (MetaData.PARAM_ISBYREF(&pMethodDef->pParams[0]))
                {
                    byRefSize  += pMethodThisType->stackSize;
                    paramsSize += (uint)sizeof(byte *);
                    byRefThis   = true;
                }
                else
                {
                    paramsSize += pMethodDef->pParams[0].pStackTypeDef->stackSize;
                }
                start = 1;
            }

            if (args.Length != pMethodDef->numberOfParameters - start)
            {
                throw new System.InvalidOperationException("Wrong number of parameters for this method");
            }

            for (uint i = start; i < args.Length; i++)
            {
                tMD_TypeDef *pParamType = MetaData.PARAM_ACTUAL_TYPE(&pMethodDef->pParams[i]);
                tMD_TypeDef *pArgType   = args[i - start] != null?MonoType.GetTypeForMonoObject(args[i - start], null, null) : null;

                if (pArgType == null && pParamType->isValueType == 0)
                {
                    pArgType = pParamType;
                }
                if (!MetaData.TYPE_ISASSIGNABLE_TO(pArgType, pParamType))
                {
                    throw new System.InvalidOperationException("Argument types are not compatible");
                }
                if (MetaData.PARAM_ISBYREF(&pMethodDef->pParams[i]))
                {
                    byRefSize  += pParamType->stackSize;
                    paramsSize += (uint)sizeof(byte *);
                    byRefArgs   = true;
                }
                else
                {
                    paramsSize += pMethodDef->pParams[i].pStackTypeDef->stackSize;
                }
            }

            if (pMethodDef->pReturnType != null)
            {
                retValSize = pMethodDef->pReturnType->stackSize;
            }

            if (byRefSize + paramsSize + retValSize > bufSize)
            {
                throw new System.InvalidOperationException("Buffer overflow for parameter stack");
            }

            // Now actually marshal params to the param buffer

            pByRefPtr = pBuf;
            pStackPtr = pBuf + byRefSize;

            if (!MetaData.METHOD_ISSTATIC(pMethodDef))
            {
                if (MetaData.PARAM_ISBYREF(&pMethodDef->pParams[0]))
                {
                    MonoType.MarshalFromObject(pByRefPtr, ref _this);
                    *(byte **)pStackPtr = pByRefPtr;
                    pByRefPtr          += pMethodDef->pParams[0].pByRefTypeDef->stackSize;
                    pStackPtr          += sizeof(byte *);
                }
                else
                {
                    MonoType.MarshalFromObject(pStackPtr, ref _this);
                    pStackPtr += pMethodDef->pParams[0].pStackTypeDef->stackSize;
                }
            }

            for (uint i = start; i < args.Length; i++)
            {
                if (MetaData.PARAM_ISBYREF(&pMethodDef->pParams[i]))
                {
                    MonoType.MarshalFromObject(pByRefPtr, ref args[i - start]);
                    *(byte **)pStackPtr = pByRefPtr;
                    pByRefPtr          += pMethodDef->pParams[i].pByRefTypeDef->stackSize;
                    pStackPtr          += sizeof(byte *);
                }
                else
                {
                    MonoType.MarshalFromObject(pStackPtr, ref args[i - start]);
                    pStackPtr += pMethodDef->pParams[i].pStackTypeDef->stackSize;
                }
            }

            // Call the method (usuing reusable call thread)

            int status = Thread.Call(pMethodDef, pBuf + byRefSize, pBuf + byRefSize + paramsSize);

            if (status != Thread.THREAD_STATUS_EXIT)
            {
                throw new System.InvalidOperationException("Thread blocked in call to method");
            }

            // Marshal back any byref values

            if (byRefArgs || byRefThis)
            {
                pByRefPtr = pBuf;
                if (byRefThis)
                {
                    object refThis;
                    MonoType.MarshalToObject(pByRefPtr, out refThis);
                    _this      = refThis;
                    pByRefPtr += pMethodDef->pParams[0].pByRefTypeDef->stackSize;
                }
                if (byRefArgs)
                {
                    for (uint i = start; i < args.Length; i++)
                    {
                        if (MetaData.PARAM_ISBYREF(&pMethodDef->pParams[i]))
                        {
                            object refArg;
                            MonoType.MarshalToObject(pByRefPtr, out refArg);
                            args[i - start] = refArg;
                            pByRefPtr      += pMethodDef->pParams[i].pByRefTypeDef->stackSize;
                        }
                    }
                }
            }

            // Marshal the return value

            if (pMethodDef->pReturnType != null)
            {
                MonoType.MarshalToObject(pBuf + byRefSize + paramsSize, out ret);
            }

            return(ret);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 17
0
 public static bool METHOD_ISNEWSLOT(tMD_MethodDef *pMethod)
 {
     return(((pMethod)->flags & METHODATTRIBUTES_NEWSLOT) != 0);
 }
Ejemplo n.º 18
0
        public static void Fill_MethodDef(tMD_TypeDef *pParentType, tMD_MethodDef *pMethodDef,
                                          tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs)
        {
            /*SIG*/ byte *sig;
            uint          i, entry, totalSize, start;

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

            // Note: parent type can be null for module level methods (not typical in C# assemblies)
            pMethodDef->pParentType = pParentType;
            pMethodDef->pMethodDef  = pMethodDef;
            pMethodDef->isFilled    = 1;

            if (pMethodDef->isGenericDefinition != 0)
            {
                // Generic definition method, so can't do any more.
                //Sys.log_f("Method<>: %s.%s.%s()\n", pParentType->nameSpace, pParentType->name, pMethodDef->name);
                return;
            }

            sig   = MetaData.GetBlob(pMethodDef->signature, null);
            entry = MetaData.DecodeSigEntry(&sig);
            if ((entry & SIG_METHODDEF_GENERIC) != 0)
            {
                // Has generic parameters. Read how many, but don't care about the answer
                MetaData.DecodeSigEntry(&sig);
            }
            pMethodDef->numberOfParameters = (ushort)(MetaData.DecodeSigEntry(&sig) + (MetaData.METHOD_ISSTATIC(pMethodDef)?0:1));
            pMethodDef->pReturnType        = Type.GetTypeFromSig(pMethodDef->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, null);
            if (pMethodDef->pReturnType != null && pMethodDef->pReturnType->fillState < Type.TYPE_FILL_ALL)
            {
                Fill_Defer(pMethodDef->pReturnType, ppClassTypeArgs, ppMethodTypeArgs);
            }
            pMethodDef->pParams = (tParameter *)Mem.malloc((SIZE_T)(pMethodDef->numberOfParameters * sizeof(tParameter)));
            totalSize           = 0;
            start = 0;
            if (!MetaData.METHOD_ISSTATIC(pMethodDef))
            {
                // Fill in parameter info for the 'this' pointer
                pMethodDef->pParams->offset = 0;
                if (pParentType->isValueType != 0)
                {
                    // If this is a value-type then the 'this' pointer is actually an IntPtr to the value-type's location
                    pMethodDef->pParams->size          = sizeof(PTR);
                    pMethodDef->pParams->pStackTypeDef = Type.types[Type.TYPE_SYSTEM_INTPTR];
                }
                else
                {
                    pMethodDef->pParams->size          = sizeof(PTR);
                    pMethodDef->pParams->pStackTypeDef = pParentType;
                }
                totalSize = sizeof(PTR);
                start     = 1;
            }
            for (i = start; i < pMethodDef->numberOfParameters; i++)
            {
                tMD_TypeDef *pStackTypeDef;
                tMD_TypeDef *pByRefTypeDef;
                uint         size;

                pByRefTypeDef = null;
                pStackTypeDef = Type.GetTypeFromSig(pMethodDef->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, &pByRefTypeDef);
                if (pStackTypeDef != null)
                {
                    if (pStackTypeDef->fillState < Type.TYPE_FILL_LAYOUT)
                    {
                        MetaData.Fill_TypeDef(pStackTypeDef, null, null, Type.TYPE_FILL_LAYOUT);
                    }
                    else if (pStackTypeDef->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pStackTypeDef, null, null);
                    }
                    size = pStackTypeDef->stackSize;
                }
                else
                {
                    size = 0;
                }
                if (pByRefTypeDef != null)
                {
                    if (pByRefTypeDef->fillState < Type.TYPE_FILL_LAYOUT)
                    {
                        MetaData.Fill_TypeDef(pByRefTypeDef, null, null, Type.TYPE_FILL_LAYOUT);
                    }
                    else if (pByRefTypeDef->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pByRefTypeDef, null, null);
                    }
                }
                pMethodDef->pParams[i].pStackTypeDef = pStackTypeDef;
                pMethodDef->pParams[i].pByRefTypeDef = pByRefTypeDef;
                pMethodDef->pParams[i].offset        = totalSize;
                pMethodDef->pParams[i].size          = size;
                totalSize += size;
            }
            pMethodDef->parameterStackSize = totalSize;
        }
Ejemplo n.º 19
0
        // Find the method that has been overridden by pMethodDef.
        // This is to get the correct vTable offset for the method.
        // This must search the MethodImpl table to see if the default inheritence rules are being overridden.
        // Return null if this method does not override anything.
        public static tMD_MethodDef *FindVirtualOverriddenMethod(tMD_TypeDef *pTypeDef, tMD_MethodDef *pMethodDef)
        {
            uint i;

            do
            {
                // Search MethodImpl table
                for (i = pTypeDef->pMetaData->tables.numRows[MetaDataTable.MD_TABLE_METHODIMPL]; i > 0; i--)
                {
                    tMD_MethodImpl *pMethodImpl;

                    pMethodImpl = (tMD_MethodImpl *)MetaData.GetTableRow(pTypeDef->pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODIMPL, i));
                    if (pMethodImpl->class_ == pTypeDef->tableIndex)
                    {
                        tMD_MethodDef *pMethodDeclDef;

                        pMethodDeclDef = MetaData.GetMethodDefFromDefRefOrSpec(pTypeDef->pMetaData, pMethodImpl->methodDeclaration,
                                                                               pTypeDef->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs);
                        if (pMethodDeclDef->tableIndex == pMethodDef->tableIndex)
                        {
                            /*IDX_TABLE*/ uint methodToken;
                            tMD_MethodDef *    pMethod;

                            methodToken = pMethodImpl->methodBody;
                            pMethod     = (tMD_MethodDef *)MetaData.GetTableRow(pTypeDef->pMetaData, methodToken);
                            return(pMethod);
                        }
                    }
                }

                // Use normal inheritence rules
                // It must be a virtual method that's being overridden.
                for (i = pTypeDef->numMethods - 1; i != 0xffffffff; i--)
                {
                    tMD_MethodDef *pVirtMethodDef = pTypeDef->ppMethods[i];
                    if (MetaData.METHOD_ISVIRTUAL(pVirtMethodDef))
                    {
                        if (pMethodDef->signature != null)
                        {
                            if (MetaData.CompareNameAndSig(pMethodDef->name, pMethodDef->signature, pMethodDef->pMetaData,
                                                           pMethodDef->pParentType->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs,
                                                           pVirtMethodDef, pTypeDef->ppClassTypeArgs, null) != 0)
                            {
                                return(pVirtMethodDef);
                            }
                        }
                        else if (pMethodDef->monoMethodInfo != null)
                        {
                            System.Reflection.MethodBase methodInfo = H.ToObj(pMethodDef->monoMethodInfo) as System.Reflection.MethodBase;
                            if (MetaData.CompareNameAndMethodInfo(pMethodDef->name, methodInfo, pMethodDef->pMetaData,
                                                                  pMethodDef->pParentType->ppClassTypeArgs, pMethodDef->ppMethodTypeArgs, pVirtMethodDef, pTypeDef->ppClassTypeArgs, null) != 0)
                            {
                                return(pVirtMethodDef);
                            }
                        }
                    }
                }
                pTypeDef = pTypeDef->pParent;
            } while (pTypeDef != null);

            return(null);
        }
Ejemplo n.º 20
0
        private static tCLIFile *LoadPEFile(byte[] image)
        {
            tCLIFile *pRet = ((tCLIFile *)Mem.malloc((SIZE_T)sizeof(tCLIFile)));

            System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(image, GCHandleType.Pinned);
            byte *pData = (byte *)handle.AddrOfPinnedObject();

            byte *pMSDOSHeader = (byte *)&(((byte *)pData)[0]);
            byte *pPEHeader;
            byte *pPEOptionalHeader;
            byte *pPESectionHeaders;
            byte *pCLIHeader;
            byte *pRawMetaData;

            int    i;
            uint   lfanew;
            ushort machine;
            int    numSections;
            //uint imageBase;
            //int fileAlignment;
            uint cliHeaderRVA;
            //uint cliHeaderSize;
            uint metaDataRVA;
            //uint metaDataSize;
            tMetaData *pMetaData;

            pRet->pRVA      = RVA.New();
            pRet->gcHandle  = (PTR)(System.IntPtr)handle;
            pRet->pMetaData = pMetaData = MetaData.New();

            lfanew            = *(uint *)&(pMSDOSHeader[0x3c]);
            pPEHeader         = pMSDOSHeader + lfanew + 4;
            pPEOptionalHeader = pPEHeader + 20;
            pPESectionHeaders = pPEOptionalHeader + 224;

            machine = *(ushort *)&(pPEHeader[0]);
            if (machine != DOT_NET_MACHINE)
            {
                return(null);
            }
            numSections = *(ushort *)&(pPEHeader[2]);

            //imageBase = *(uint*)&(pPEOptionalHeader[28]);
            //fileAlignment = *(int*)&(pPEOptionalHeader[36]);

            for (i = 0; i < numSections; i++)
            {
                byte *pSection = pPESectionHeaders + i * 40;
                RVA.Create(pRet->pRVA, pData, pSection);
            }

            cliHeaderRVA = *(uint *)&(pPEOptionalHeader[208]);
            //cliHeaderSize = *(uint*)&(pPEOptionalHeader[212]);

            pCLIHeader = (byte *)RVA.FindData(pRet->pRVA, cliHeaderRVA);

            metaDataRVA = *(uint *)&(pCLIHeader[8]);
            //metaDataSize = *(uint*)&(pCLIHeader[12]);
            pRet->entryPoint = *(uint *)&(pCLIHeader[20]);
            pRawMetaData     = (byte *)RVA.FindData(pRet->pRVA, metaDataRVA);

            // Load all metadata
            {
                uint  versionLen = *(uint *)&(pRawMetaData[12]);
                uint  ofs, numberOfStreams;
                void *pTableStream    = null;
                uint  tableStreamSize = 0;
                pRet->pVersion = &(pRawMetaData[16]);
                Sys.log_f(1, "CLI version: %s\n", (PTR)pRet->pVersion);
                ofs             = 16 + versionLen;
                numberOfStreams = *(ushort *)&(pRawMetaData[ofs + 2]);
                ofs            += 4;

                for (i = 0; i < (int)numberOfStreams; i++)
                {
                    uint  streamOffset = *(uint *)&pRawMetaData[ofs];
                    uint  streamSize   = *(uint *)&pRawMetaData[ofs + 4];
                    byte *pStreamName  = &pRawMetaData[ofs + 8];
                    void *pStream      = pRawMetaData + streamOffset;
                    ofs += (uint)((S.strlen(pStreamName) + 4) & (~0x3)) + 8;
                    if (S.strcasecmp(pStreamName, "#Strings") == 0)
                    {
                        MetaData.LoadStrings(pMetaData, pStream, streamSize);
                    }
                    else if (S.strcasecmp(pStreamName, "#US") == 0)
                    {
                        MetaData.LoadUserStrings(pMetaData, pStream, streamSize);
                    }
                    else if (S.strcasecmp(pStreamName, "#Blob") == 0)
                    {
                        MetaData.LoadBlobs(pMetaData, pStream, streamSize);
                    }
                    else if (S.strcasecmp(pStreamName, "#GUID") == 0)
                    {
                        MetaData.LoadGUIDs(pMetaData, pStream, streamSize);
                    }
                    else if (S.strcasecmp(pStreamName, "#~") == 0)
                    {
                        pTableStream    = pStream;
                        tableStreamSize = streamSize;
                    }
                }
                // Must load tables last
                if (pTableStream != null)
                {
                    MetaData.LoadTables(pMetaData, pRet->pRVA, pTableStream, (uint)tableStreamSize);
                }
            }

            // Mark all generic definition type and methods as such
            for (i = (int)pMetaData->tables.numRows[MetaDataTable.MD_TABLE_GENERICPARAM]; i > 0; i--)
            {
                tMD_GenericParam * pGenericParam;
                /*IDX_TABLE*/ uint ownerIdx;

                pGenericParam = (tMD_GenericParam *)MetaData.GetTableRow
                                    (pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_GENERICPARAM, (uint)i));
                ownerIdx = pGenericParam->owner;
                switch (MetaData.TABLE_ID(ownerIdx))
                {
                case MetaDataTable.MD_TABLE_TYPEDEF:
                {
                    tMD_TypeDef *pTypeDef = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, ownerIdx);
                    pTypeDef->isGenericDefinition = 1;
                }
                break;

                case MetaDataTable.MD_TABLE_METHODDEF:
                {
                    tMD_MethodDef *pMethodDef = (tMD_MethodDef *)MetaData.GetTableRow(pMetaData, ownerIdx);
                    pMethodDef->isGenericDefinition = 1;
                }
                break;

                default:
                    Sys.Crash("Wrong generic parameter owner: 0x%08x", ownerIdx);
                    break;
                }
            }

            // Mark all nested classes as such
            for (i = (int)pMetaData->tables.numRows[MetaDataTable.MD_TABLE_NESTEDCLASS]; i > 0; i--)
            {
                tMD_NestedClass *pNested;
                tMD_TypeDef *    pParent;
                tMD_TypeDef *    pChild;

                pNested           = (tMD_NestedClass *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_NESTEDCLASS, (uint)i));
                pParent           = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, pNested->enclosingClass);
                pChild            = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, pNested->nestedClass);
                pChild->pNestedIn = pParent;
            }

            return(pRet);
        }
Ejemplo n.º 21
0
        public static tMD_MethodDef *GetMethodDefFromCoreMethod(tMD_MethodDef *pCoreMethod,
                                                                tMD_TypeDef *pParentType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs,
                                                                HashSet <PTR> resolveTypes = null)
        {
            tGenericMethodInstance *pInst;
            tMD_MethodDef *         pMethod;

            Mem.heapcheck();

            // See if we already have an instance with the given type args
            pInst = pCoreMethod->pGenericMethodInstances;
            while (pInst != null)
            {
                if (pInst->numTypeArgs == numTypeArgs &&
                    Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0)
                {
                    return(pInst->pInstanceMethodDef);
                }
                pInst = pInst->pNext;
            }

            // We don't have an instance so create one now.
            pInst        = (tGenericMethodInstance *)Mem.mallocForever((SIZE_T)(sizeof(tGenericMethodInstance)));
            pInst->pNext = pCoreMethod->pGenericMethodInstances;
            pCoreMethod->pGenericMethodInstances = pInst;
            pInst->numTypeArgs = numTypeArgs;
            pInst->ppTypeArgs  = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));
            Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));

            pInst->pInstanceMethodDef = pMethod = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef)));
            Mem.memset(pMethod, 0, (SIZE_T)sizeof(tMD_MethodDef));
            pMethod->pMethodDef       = pMethod;
            pMethod->pMetaData        = pCoreMethod->pMetaData;
            pMethod->pCIL             = pCoreMethod->pCIL;
            pMethod->implFlags        = pCoreMethod->implFlags;
            pMethod->flags            = pCoreMethod->flags;
            pMethod->name             = pCoreMethod->name;
            pMethod->signature        = pCoreMethod->signature;
            pMethod->vTableOfs        = pCoreMethod->vTableOfs;
            pMethod->ppMethodTypeArgs = pInst->ppTypeArgs;

            if (pCoreMethod->monoMethodInfo != null)
            {
                System.Reflection.MethodInfo methodInfo = H.ToObj(pCoreMethod->monoMethodInfo) as System.Reflection.MethodInfo;
                System.Type[] typeArgs = new System.Type[(int)numTypeArgs];
                for (uint i = 0; i < numTypeArgs; i++)
                {
                    typeArgs[i] = MonoType.GetMonoTypeForType(ppTypeArgs[i]);
                    if (typeArgs[i] == null)
                    {
                        Sys.Crash("Unable to find mono type for type arg %s.%s in for generic method %s",
                                  (PTR)ppTypeArgs[i]->nameSpace, (PTR)ppTypeArgs[i]->name, (PTR)pCoreMethod->name);
                    }
                }
                System.Reflection.MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(typeArgs);
                MonoType.Fill_MethodDef(pParentType, genericMethodInfo, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs);
            }
            else
            {
                MetaData.Fill_MethodDef(pParentType, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs);
            }

            Mem.heapcheck();

            return(pMethod);
        }
Ejemplo n.º 22
0
        public static void Fill_TypeDef(tMD_TypeDef *pTypeDef,
                                        tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs,
                                        uint resolve = Type.TYPE_FILL_ALL)
        {
            /*IDX_TABLE*/ uint firstIdx, lastIdx, token;
            uint         instanceMemSize, staticMemSize, virtualOfs, isDeferred, i, j;
            tMetaData *  pMetaData = pTypeDef->pMetaData;
            tMD_TypeDef *pParent;

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

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

//            Sys.printf("FILLING TYPE: %s\n", (PTR)pTypeDef->name);
//            string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi((System.IntPtr)pTypeDef->name);


            if (typesToFill == null)
            {
                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);

            // Fill parent info
            if (pTypeDef->fillState < Type.TYPE_FILL_PARENTS)
            {
                pTypeDef->fillState = Type.TYPE_FILL_PARENTS;

                pTypeDef->pTypeDef = pTypeDef;
                if (pTypeDef->alignment == 0)
                {
                    pTypeDef->alignment = 1;
                }

                if (pTypeDef->pParent == null)
                {
                    pTypeDef->pParent = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, pTypeDef->extends, ppClassTypeArgs, ppMethodTypeArgs);
                }
                pParent = pTypeDef->pParent;

                if (pParent != null)
                {
                    if (pParent->fillState < Type.TYPE_FILL_PARENTS)
                    {
                        MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_PARENTS);
                    }
                    else if (pParent->fillState < Type.TYPE_FILL_ALL)
                    {
                        MetaData.Fill_Defer(pParent, null, null);
                    }
                    pTypeDef->hasMonoBase = pParent->hasMonoBase;
                    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
                {
                    pTypeDef->blittable = pTypeDef->fixedBlittable = 1;
                }

                // If this type is an interface, then return 0
                if (pTypeDef->stackSize != 0)
                {
                    pTypeDef->isValueType = (byte)(pTypeDef->stackType != EvalStack.EVALSTACK_O ? 1 : 0);
                }
                else if (MetaData.TYPE_ISINTERFACE(pTypeDef))
                {
                    pTypeDef->isValueType = 0;
                }
                else if (pTypeDef->nameSpace[0] == 'S' && S.strcmp(pTypeDef->nameSpace, new S(ref scSystem, "System")) == 0)
                {
                    if ((pTypeDef->name[0] == 'V' && S.strcmp(pTypeDef->name, new S(ref scValueType, "ValueType")) == 0) ||
                        (pTypeDef->name[0] == 'E' && S.strcmp(pTypeDef->name, new S(ref scEnum, "Enum")) == 0))
                    {
                        pTypeDef->isValueType = 1;
                    }
                    else if (pTypeDef->name[0] == 'O' && S.strcmp(pTypeDef->name, new S(ref scObject, "Object")) == 0)
                    {
                        pTypeDef->isValueType = 0;
                    }
                    else if (pParent != null)
                    {
                        pTypeDef->isValueType = pParent->isValueType;
                    }
                }
                else if (pParent != null)
                {
                    pTypeDef->isValueType = pParent->isValueType;
                }

                // If not primed, then work out how many methods & fields there are.
                if (pTypeDef->isPrimed == 0)
                {
                    // Methods
                    lastIdx = (pTypeDef->isLast != 0) ?
                              MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODDEF, pTypeDef->pMetaData->tables.numRows[MetaDataTable.MD_TABLE_METHODDEF]) :
                              (pTypeDef[1].methodList - 1);
                    pTypeDef->numMethods = lastIdx - pTypeDef->methodList + 1;
                    // Fields
                    lastIdx = (pTypeDef->isLast != 0) ?
                              MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_FIELDDEF, pTypeDef->pMetaData->tables.numRows[MetaDataTable.MD_TABLE_FIELDDEF]) :
                              (pTypeDef[1].fieldList - 1);
                    pTypeDef->numFields = lastIdx - pTypeDef->fieldList + 1;
                }

                // If this is a nested type, then find the namespace of it
                if (pTypeDef->pNestedIn != null)
                {
                    tMD_TypeDef *pRootTypeDef = pTypeDef->pNestedIn;
                    while (pRootTypeDef->pNestedIn != null)
                    {
                        pRootTypeDef = pRootTypeDef->pNestedIn;
                    }
                    pTypeDef->nameSpace = pRootTypeDef->nameSpace;
                }

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

                if (pTypeDef->isGenericDefinition == 0)
                {
                    // 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.
                    firstIdx      = pTypeDef->fieldList;
                    lastIdx       = firstIdx + pTypeDef->numFields - 1;
                    staticMemSize = 0;
                    if (pTypeDef->numFields > 0)
                    {
                        pTypeDef->ppFields = (tMD_FieldDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numFields * sizeof(tMD_FieldDef *)));
                    }
                    instanceMemSize = (pParent == null ? 0 : pTypeDef->pParent->instanceMemSize);
                    if (pTypeDef->hasMonoBase != 0 && pParent->hasMonoBase == 0)
                    {
                        // Some DNA types like String are actually wrappers around mono objects.  In those cases, we need to allocate the
                        // space in the instance memory for the GCHandle to the mono object.  We distinguish this case from the case
                        // where we're just extending a Mono Type object by checking if the parent also has the hasMonoBase flag set.
                        instanceMemSize += (uint)sizeof(void *);
                    }
                    for (token = firstIdx, i = 0; token <= lastIdx; token++, i++)
                    {
                        tMD_FieldDef *pFieldDef;

                        pFieldDef = MetaData.GetFieldDefFromDefOrRef(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs);
                        if (!MetaData.FIELD_ISSTATIC(pFieldDef))
                        {
                            // Only handle non-static fields at the moment
                            if (pTypeDef->pGenericDefinition != null)
                            {
                                // If this is a generic instantiation type, then all field defs need to be copied,
                                // as there will be lots of different instantiations.
                                tMD_FieldDef *pFieldCopy = ((tMD_FieldDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_FieldDef)));
                                Mem.memcpy(pFieldCopy, pFieldDef, (SIZE_T)sizeof(tMD_FieldDef));
                                pFieldDef = pFieldCopy;
                            }
                            if (MetaData.FIELD_ISLITERAL(pFieldDef) || 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
                                MetaData.Fill_FieldDef(pTypeDef, pFieldDef, 0, null, ppClassTypeArgs);
                            }
                            else
                            {
                                MetaData.Fill_FieldDef(pTypeDef, 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)
                    {
                        pTypeDef->instanceMemSize = (instanceMemSize + (pTypeDef->alignment - 1)) & ~(pTypeDef->alignment - 1);
                    }

                    // 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 (token = firstIdx, i = 0; token <= lastIdx; token++, i++)
                    {
                        tMD_FieldDef *pFieldDef;

                        pFieldDef = MetaData.GetFieldDefFromDefOrRef(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs);
                        if (MetaData.FIELD_ISSTATIC(pFieldDef))
                        {
                            // Only handle static fields here
                            if (pTypeDef->pGenericDefinition != null)
                            {
                                // If this is a generic instantiation type, then all field defs need to be copied,
                                // as there will be lots of different instantiations.
                                tMD_FieldDef *pFieldCopy = ((tMD_FieldDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_FieldDef)));
                                Mem.memcpy(pFieldCopy, pFieldDef, (SIZE_T)sizeof(tMD_FieldDef));
                                pFieldDef = pFieldCopy;
                            }
                            if (MetaData.FIELD_ISLITERAL(pFieldDef) || 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
                                MetaData.Fill_FieldDef(pTypeDef, pFieldDef, 0, null, ppClassTypeArgs);
                            }
                            else
                            {
                                MetaData.Fill_FieldDef(pTypeDef, pFieldDef, staticMemSize, null, ppClassTypeArgs);
                                staticMemSize += pFieldDef->memSize;
                            }
                            pTypeDef->ppFields[i] = pFieldDef;
                        }
                    }

                    if (staticMemSize > 0)
                    {
                        pTypeDef->pStaticFields = (byte *)Mem.mallocForever((SIZE_T)staticMemSize);
                        Mem.memset(pTypeDef->pStaticFields, 0, staticMemSize);
                        // Set the field addresses (->pMemory) of all static fields
                        for (i = 0; i < pTypeDef->numFields; i++)
                        {
                            tMD_FieldDef *pFieldDef;

                            pFieldDef = pTypeDef->ppFields[i];
                            if (MetaData.FIELD_ISSTATIC(pFieldDef) && pFieldDef->pMemory == null)
                            {
                                // Only set it if it isn't already set. It will be already set if this field has an RVA
                                pFieldDef->pMemory = pTypeDef->pStaticFields + pFieldDef->memOffset;
                            }
                        }
                        pTypeDef->staticFieldSize = staticMemSize;
                    }
                }

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

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

                if (pTypeDef->isGenericDefinition == 0)
                {
                    virtualOfs = (pParent != null) ? pParent->numVirtualMethods : 0;

                    // Must create the virtual method table BEFORE any other type resolution is done
                    // Note that this must not do ANY filling of type or methods.
                    // This is to ensure that the parent object(s) in any type inheritance hierachy are allocated
                    // their virtual method offset before derived Type.types.
                    firstIdx = pTypeDef->methodList;
                    lastIdx  = firstIdx + pTypeDef->numMethods - 1;
                    for (token = firstIdx; token <= lastIdx; token++)
                    {
                        tMD_MethodDef *pMethodDef;

                        pMethodDef = MetaData.GetMethodDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs);

                        //Sys.printf("Method: %s\n", (PTR)pMethodDef->name);

                        // This is needed, so array resolution can work correctly and FindVirtualOverriddenMethod() can work.
                        pMethodDef->pParentType = pTypeDef;

                        if (MetaData.METHOD_ISVIRTUAL(pMethodDef))
                        {
                            if (MetaData.METHOD_ISNEWSLOT(pMethodDef) || pTypeDef->pParent == null)
                            {
                                // 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 = FindVirtualOverriddenMethod(pTypeDef->pParent, pMethodDef);
                                if (pVirtualOveriddenMethod == null)
                                {
                                    Sys.Crash("Unable to find virtual override method for %s %s", (PTR)pTypeDef->name, (PTR)pMethodDef->name);
                                }
                                pMethodDef->vTableOfs = pVirtualOveriddenMethod->vTableOfs;
                            }
                        }
                        else
                        {
                            // Dummy value - make it obvious it's not valid!
                            pMethodDef->vTableOfs = 0xffffffff;
                        }
                    }

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

                    // Resolve all members
                    firstIdx            = pTypeDef->methodList;
                    lastIdx             = firstIdx + pTypeDef->numMethods - 1;
                    pTypeDef->ppMethods = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numMethods * sizeof(tMD_MethodDef *)));
                    pTypeDef->pVTable   = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numVirtualMethods * sizeof(tMD_MethodDef *)));
                    // Copy initial vTable from parent
                    if (pTypeDef->pParent != null)
                    {
                        if (pTypeDef->pParent->fillState != Type.TYPE_FILL_MEMBERS)
                        {
                            Fill_TypeDef(pTypeDef->pParent, null, null, Type.TYPE_FILL_MEMBERS);
                        }
                        Mem.memcpy(pTypeDef->pVTable, pTypeDef->pParent->pVTable, (SIZE_T)(pTypeDef->pParent->numVirtualMethods * sizeof(tMD_MethodDef *)));
                    }
                    for (token = firstIdx, i = 0; token <= lastIdx; token++, i++)
                    {
                        tMD_MethodDef *pMethodDef;

                        pMethodDef = MetaData.GetMethodDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs);
                        if (pTypeDef->pGenericDefinition != null)
                        {
                            // If this is a generic instantiation type, then all method defs need to be copied,
                            // as there will be lots of different instantiations.
                            tMD_MethodDef *pMethodCopy = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef)));
                            Mem.memcpy(pMethodCopy, pMethodDef, (SIZE_T)sizeof(tMD_MethodDef));
                            pMethodDef = pMethodCopy;
                        }
                        if (MetaData.METHOD_ISSTATIC(pMethodDef) && S.strcmp(pMethodDef->name, ".cctor") == 0)
                        {
                            // This is a static constructor
                            pTypeDef->pStaticConstructor = pMethodDef;
                        }
                        if (!MetaData.METHOD_ISSTATIC(pMethodDef) && pTypeDef->pParent != null &&
                            S.strcmp(pMethodDef->name, "Finalize") == 0)
                        {
                            // 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 (MetaData.METHOD_ISVIRTUAL(pMethodDef))
                        {
                            // This is a virtual method, so enter it in the vTable
                            pTypeDef->pVTable[pMethodDef->vTableOfs] = pMethodDef;
                        }
                        pTypeDef->ppMethods[i] = 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);
                    }
                }

                if (pTypeDef->isGenericDefinition == 0)
                {
                    // Fill all method definitions for this type
                    for (i = 0; i < pTypeDef->numMethods; i++)
                    {
                        MetaData.Fill_MethodDef(pTypeDef, 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);
                    }
                }

                if (pTypeDef->isGenericDefinition == 0 && !MetaData.TYPE_ISINTERFACE(pTypeDef))
                {
                    if (pParent != null && pParent->fillState < Type.TYPE_FILL_INTERFACES)
                    {
                        MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_INTERFACES);
                    }

                    // Map all interface method calls. This only needs to be done for Classes, not Interfaces
                    // And is not done for generic definitions.
                    firstIdx = 0;
                    if (pTypeDef->pParent != null)
                    {
                        j = pTypeDef->numInterfaces = pTypeDef->pParent->numInterfaces;
                    }
                    else
                    {
                        j = 0;
                    }

                    lastIdx = firstIdx;
                    for (i = 1; i <= pMetaData->tables.numRows[MetaDataTable.MD_TABLE_INTERFACEIMPL]; i++)
                    {
                        tMD_InterfaceImpl *pInterfaceImpl;
                        pInterfaceImpl = (tMD_InterfaceImpl *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_INTERFACEIMPL, i));
                        if (pInterfaceImpl->class_ == pTypeDef->tableIndex)
                        {
                            // count how many interfaces are implemented
                            pTypeDef->numInterfaces++;
                            if (firstIdx == 0)
                            {
                                firstIdx = MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_INTERFACEIMPL, i);
                            }
                            lastIdx = MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_INTERFACEIMPL, i);
                        }
                    }

                    if (pTypeDef->numInterfaces > 0)
                    {
                        uint mapNum;

                        pTypeDef->pInterfaceMaps = (tInterfaceMap *)Mem.mallocForever((SIZE_T)(pTypeDef->numInterfaces * sizeof(tInterfaceMap)));
                        // Copy interface maps from parent type
                        if (j > 0)
                        {
                            Mem.memcpy(pTypeDef->pInterfaceMaps, pTypeDef->pParent->pInterfaceMaps, (SIZE_T)(j * sizeof(tInterfaceMap)));
                        }
                        mapNum = j;
                        if (firstIdx > 0)
                        {
                            for (token = firstIdx; token <= lastIdx; token++, mapNum++)
                            {
                                tMD_InterfaceImpl *pInterfaceImpl;

                                pInterfaceImpl = (tMD_InterfaceImpl *)MetaData.GetTableRow(pMetaData, token);
                                if (pInterfaceImpl->class_ == pTypeDef->tableIndex)
                                {
                                    tMD_TypeDef *  pInterface;
                                    tInterfaceMap *pMap;

                                    // Get the interface that this type implements
                                    pInterface = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, pInterfaceImpl->interface_, ppClassTypeArgs, ppMethodTypeArgs);
                                    MetaData.Fill_TypeDef(pInterface, null, null, Type.TYPE_FILL_INTERFACES);
                                    pMap                  = &pTypeDef->pInterfaceMaps[mapNum];
                                    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 *)));
                                    // Discover interface mapping for each interface method
                                    for (i = 0; i < pInterface->numVirtualMethods; i++)
                                    {
                                        tMD_MethodDef *pInterfaceMethod;
                                        tMD_MethodDef *pOverriddenMethod;
                                        pInterfaceMethod         = pInterface->pVTable[i];
                                        pOverriddenMethod        = FindVirtualOverriddenMethod(pTypeDef, pInterfaceMethod);
                                        pMap->pVTableLookup[i]   = pOverriddenMethod->vTableOfs;
                                        pMap->ppMethodVLookup[i] = pOverriddenMethod;
                                    }
                                }
                                else
                                {
                                    Sys.Crash("Problem with interface class");
                                }
                            }
                        }
                    }
                }

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

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

                if (pTypeDef->isGenericDefinition == 0 && pTypeDef->stackSize == 0)
                {
                    j = 0;
                }

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

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

            Sys.log_f(2, "Type:  %s.%s\n", (PTR)pTypeDef->nameSpace, (PTR)pTypeDef->name);
        }
Ejemplo n.º 23
0
 public static bool METHOD_ISSTATIC(tMD_MethodDef *pMethod)
 {
     return(((pMethod)->flags & METHODATTRIBUTES_STATIC) != 0);
 }
Ejemplo n.º 24
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);
        }