Exemple #1
0
        public static tAsyncCall *Resize(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            /*HEAP_PTR*/ byte **ppArray_, pHeap;
            tSystemArray *      pOldArray, pNewArray;
            uint         newSize, oldSize;
            tMD_TypeDef *pArrayTypeDef;
            byte *       pOldElements, pNewElements;

            ppArray_ = (*((byte ***)(pParams + 0)));
            newSize  = (*((uint *)(pParams + Sys.S_PTR)));

            pOldArray = (tSystemArray *)*ppArray_;
            oldSize   = pOldArray->length;

            if (oldSize == newSize)
            {
                // Do nothing if new length equals the current length.
                return(null);
            }

            pArrayTypeDef = Heap.GetType(*ppArray_);
            pHeap         = (byte **)System_Array.NewVector(pArrayTypeDef, newSize);
            pNewArray     = (tSystemArray *)pHeap;
            *ppArray_ = (byte *)pHeap;
            pOldElements = tSystemArray.GetElements(pOldArray);
            pNewElements = tSystemArray.GetElements(pNewArray);
            Mem.memcpy(pNewElements, pOldElements,
                       (SIZE_T)(pArrayTypeDef->pArrayElementType->arrayElementSize * ((newSize < oldSize)?newSize:oldSize)));

            return(null);
        }
Exemple #2
0
        public static void GetConstant(tMetaData *pThis, /*IDX_TABLE*/ uint idx, byte *pResultMem)
        {
            tMD_Constant *pConst = null;

            switch (MetaData.TABLE_ID(idx))
            {
            case MetaDataTable.MD_TABLE_FIELDDEF:
            {
                tMD_FieldDef *pField = (tMD_FieldDef *)MetaData.GetTableRow(pThis, idx);
                pConst = (tMD_Constant *)pField->pMemory;
            }
            break;

            default:
                Sys.Crash("MetaData.GetConstant() Cannot handle idx: 0x%08x", idx);
                break;
            }

            switch (pConst->type)
            {
            case Type.ELEMENT_TYPE_I4:
                //*(uint*)pReturnMem = MetaData.DecodeSigEntry(
                Mem.memcpy(pResultMem, pConst->value + 1, 4);
                return;

            default:
                Sys.Crash("MetaData.GetConstant() Cannot handle value type: 0x%02x", pConst->type);
                break;
            }
        }
Exemple #3
0
        public static void LoadElement(/*HEAP_PTR*/ byte *pThis_, uint index, byte *value)
        {
            tSystemArray *pArray = (tSystemArray *)pThis_;
            tMD_TypeDef * pArrayTypeDef;
            uint          elemSize;
            byte *        pElements;

            pArrayTypeDef = Heap.GetType(pThis_);
            elemSize      = pArrayTypeDef->pArrayElementType->arrayElementSize;
            pElements     = tSystemArray.GetElements(pArray);
            switch (elemSize)
            {
            case 1:
                *(byte *)value = ((byte *)pElements)[index];
                break;

            case 2:
                *(ushort *)value = ((ushort *)pElements)[index];
                break;

            case 4:
                *(uint *)value = ((uint *)pElements)[index];
                break;

            default:
                Mem.memcpy(value, &pElements[index * elemSize], (SIZE_T)elemSize);
                break;
            }
        }
Exemple #4
0
        public static tRVA_Item *Create(tRVA *pThis, void *pFile, void *pSectionHeader)
        {
            tRVA_Item *pRet;
            uint       rawOfs;
            uint       rawSize;

            pRet = ((tRVA_Item *)Mem.malloc((SIZE_T)sizeof(tRVA_Item)));
            pRet->baseAddress = *(uint *)&((byte *)pSectionHeader)[12];
            pRet->size        = *(uint *)&((byte *)pSectionHeader)[8];
            pRet->pData       = Mem.malloc(pRet->size);
            Mem.memset(pRet->pData, 0, pRet->size);
            pRet->pNext      = pThis->pFirstRVA;
            pThis->pFirstRVA = pRet;

            rawOfs  = *(uint *)&((byte *)pSectionHeader)[20];
            rawSize = *(uint *)&((byte *)pSectionHeader)[16];
            if (rawOfs > 0)
            {
                if (rawSize > pRet->size)
                {
                    rawSize = pRet->size;
                }
                Mem.memcpy(pRet->pData, ((byte *)pFile) + rawOfs, rawSize);
            }

            return(pRet);
        }
Exemple #5
0
        public static /*HEAP_PTR*/ byte *Box(tMD_TypeDef *pType, byte *pMem)
        {
            /*HEAP_PTR*/ byte *boxed;

            boxed = AllocType(pType);
            Mem.memcpy((void *)boxed, (void *)pMem, pType->instanceMemSize);

            return(boxed);
        }
Exemple #6
0
 public static void SetEntryPoint(tThread *pThis, tMetaData *pMetaData, /*IDX_TABLE*/ uint entryPointToken, byte *_params, uint paramBytes)
 {
     // Set up the initial MethodState
     pThis->pCurrentMethodState = MethodState.New(pThis, pMetaData, entryPointToken, null);
     // Insert initial parameters (if any)
     if (paramBytes > 0)
     {
         Mem.memcpy(pThis->pCurrentMethodState->pParamsLocals, _params, paramBytes);
     }
 }
Exemple #7
0
        public static /*HEAP_PTR*/ byte *Clone(/*HEAP_PTR*/ byte *obj)
        {
            tHeapEntry *       pObj = GET_HEAPENTRY(obj);
            /*HEAP_PTR*/ byte *clone;
            uint  size = GetSize(pObj);
            byte *pMem;

            clone = Alloc(pObj->pTypeDef, size);

            pMem = (byte *)&pObj->pSync + sizeof(PTR);
            Mem.memcpy((void *)clone, pMem, size);

            return(clone);
        }
Exemple #8
0
        public static /*HEAP_PTR*/ byte *FromUserStrings(tMetaData *pMetaData, /*IDX_USERSTRINGS*/ uint index)
        {
            uint stringLen;
            /*STRING2*/ ushort *str;
            tSystemString *     pSystemString;
            char *pSystemStringChars;

            str = MetaData.GetUserString(pMetaData, index, &stringLen);
            // Note: stringLen is in bytes
            pSystemString      = (tSystemString *)CreateStringHeapObj(stringLen >> 1);
            pSystemStringChars = tSystemString.GetChars(pSystemString);
            Mem.memcpy(pSystemStringChars, str, (SIZE_T)stringLen);
            return((/*HEAP_PTR*/ byte *)pSystemString);
        }
Exemple #9
0
        public static /*HEAP_PTR*/ byte *FromCharPtrUTF16(ushort *pStr)
        {
            tSystemString *pSystemString;
            int            strLen = 0;
            char *         pSystemStringChars;

            while (pStr[strLen] != 0)
            {
                strLen++;
            }
            pSystemString      = CreateStringHeapObj((uint)strLen);
            pSystemStringChars = tSystemString.GetChars(pSystemString);
            Mem.memcpy(pSystemStringChars, pStr, (SIZE_T)(strLen << 1));
            return((/*HEAP_PTR*/ byte *)pSystemString);
        }
Exemple #10
0
        public static tAsyncCall *Internal_Copy(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemArray *pSrc, pDst;
            tMD_TypeDef * pSrcType, pDstType, pSrcElementType;
            byte *        pSrcElements, pDstElements;

            pSrc = (*((tSystemArray **)(pParams + 0)));
            pDst = (*((tSystemArray **)(pParams + Sys.S_PTR + Sys.S_INT32)));

            // Check if we can do a fast-copy with these two arrays
            pSrcType        = Heap.GetType((/*HEAP_PTR*/ byte *)pSrc);
            pDstType        = Heap.GetType((/*HEAP_PTR*/ byte *)pDst);
            pSrcElementType = pSrcType->pArrayElementType;
            if (Type.IsAssignableFrom(pDstType->pArrayElementType, pSrcElementType) != 0)
            {
                // Can do fast-copy
                uint srcIndex, dstIndex, length, elementSize;

                srcIndex = (*((uint *)(pParams + Sys.S_PTR)));
                dstIndex = (*((uint *)(pParams + Sys.S_PTR + Sys.S_INT32 + Sys.S_PTR)));
                length   = (*((uint *)(pParams + Sys.S_PTR + Sys.S_INT32 + Sys.S_PTR + Sys.S_INT32)));

        #if WIN32 && _DEBUG
                // Do bounds check
                if (srcIndex + length > pSrc->length || dstIndex + length > pDst->length)
                {
                    printf("[Array] Internal_Copy() Bounds check failed\n");
                    __debugbreak();
                }
        #endif

                elementSize = pSrcElementType->arrayElementSize;

                pSrcElements = tSystemArray.GetElements(pSrc);
                pDstElements = tSystemArray.GetElements(pDst);

                Mem.memcpy(pDstElements + dstIndex * elementSize, pSrcElements + srcIndex * elementSize, (SIZE_T)(length * elementSize));

                Sys.INTERNALCALL_RESULT_U32(pReturnValue, 1);
            }
            else
            {
                // Cannot do fast-copy
                Sys.INTERNALCALL_RESULT_U32(pReturnValue, 0);
            }

            return(null);
        }
Exemple #11
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);
        }
Exemple #12
0
        // Must return a boxed version of value-Type.types
        public static tAsyncCall *Internal_GetValue(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemArray *pArray = (tSystemArray *)pThis_;
            tMD_TypeDef * pArrayType;
            uint          index, elementSize;
            tMD_TypeDef * pElementType;
            byte *        pElement;

            index        = (*((uint *)(pParams + 0)));
            pArrayType   = Heap.GetType(pThis_);
            pElementType = pArrayType->pArrayElementType;
            elementSize  = pElementType->arrayElementSize;
            pElement     = tSystemArray.GetElements(pArray) + elementSize * index;
            if (pElementType->isValueType != 0)
            {
                // If it's a value-type, then box it
                /*HEAP_PTR*/ byte *boxedValue;
                if (pElementType->pGenericDefinition == Type.types[Type.TYPE_SYSTEM_NULLABLE])
                {
                    // Nullable type, so box specially
                    if (*(uint *)pElement != 0)
                    {
                        // Nullable has value
                        boxedValue = Heap.AllocType(pElementType->ppClassTypeArgs[0]);
                        // Don't copy the .hasValue part
                        Mem.memcpy(boxedValue, pElement + 4, elementSize - 4);
                    }
                    else
                    {
                        // Nullable does not have value
                        boxedValue = null;
                    }
                }
                else
                {
                    boxedValue = Heap.AllocType(pElementType);
                    Mem.memcpy(boxedValue, pElement, elementSize);
                }
                Sys.INTERNALCALL_RESULT_PTR(pReturnValue, boxedValue);
            }
            else
            {
                Sys.INTERNALCALL_RESULT_PTR(pReturnValue, *(byte **)pElement);
            }

            return(null);
        }
Exemple #13
0
        public static tAsyncCall *InternalConcat(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemString *s0, s1, ret;
            char *         pS0Chars, pS1Chars, pRetChars;

            s0        = (*((tSystemString **)(pParams + 0)));
            pS0Chars  = tSystemString.GetChars(s0);
            s1        = (*((tSystemString **)(pParams + Sys.S_PTR)));
            pS1Chars  = tSystemString.GetChars(s1);
            ret       = CreateStringHeapObj(s0->length + s1->length);
            pRetChars = tSystemString.GetChars(ret);
            Mem.memcpy(pRetChars, pS0Chars, (SIZE_T)(s0->length << 1));
            Mem.memcpy(&pRetChars[s0->length], pS1Chars, (SIZE_T)(s1->length << 1));
            Sys.INTERNALCALL_RESULT_PTR(pReturnValue, ret);

            return(null);
        }
Exemple #14
0
        public static tAsyncCall *ctor_StringIntInt(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemString *pThis;
            //tSystemString* pStr;
            uint  startIndex, length;
            char *pChars;

            //pStr = (*((tSystemString**)(pParams + 0)));
            startIndex = (*((uint *)(pParams + Sys.S_PTR)));
            length     = (*((uint *)(pParams + Sys.S_PTR + Sys.S_INT32)));

            pThis  = CreateStringHeapObj(length);
            pChars = tSystemString.GetChars(pThis);
            Mem.memcpy(pChars, &pChars[startIndex], (SIZE_T)(length << 1));
            Sys.INTERNALCALL_RESULT_PTR(pReturnValue, pThis);

            return(null);
        }
Exemple #15
0
 public static void GetReturnValue(tMethodState *pMethodState, byte *pReturnValue)
 {
     if (pMethodState->pMethod->pReturnType != null)
     {
         uint stackSize = pMethodState->pMethod->pReturnType->stackSize;
         if (stackSize == 4)
         {
             *(uint *)pReturnValue = *(uint *)pMethodState->pEvalStack;
         }
         else if (stackSize == 8)
         {
             *(ulong *)pReturnValue = *(ulong *)pMethodState->pEvalStack;
         }
         else
         {
             Mem.memcpy(pReturnValue, pMethodState->pEvalStack, stackSize);
         }
     }
 }
Exemple #16
0
        public static tAsyncCall *ctor_CharAIntInt(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemString *    pSystemString;
            /*HEAP_PTR*/ byte *charArray;
            byte *charElements;
            uint  startIndex, length;
            char *pChars;

            charArray  = (*((byte **)(pParams + 0)));
            startIndex = (*((uint *)(pParams + Sys.S_PTR)));
            length     = (*((uint *)(pParams + Sys.S_PTR + Sys.S_INT32)));

            charElements  = System_Array.GetElements(charArray);
            pSystemString = CreateStringHeapObj(length);
            pChars        = tSystemString.GetChars(pSystemString);
            Mem.memcpy(pChars, charElements + (startIndex << 1), (SIZE_T)(length << 1));
            Sys.INTERNALCALL_RESULT_PTR(pReturnValue, pSystemString);

            return(null);
        }
Exemple #17
0
        public static void StoreElement(/*HEAP_PTR*/ byte *pThis_, uint index, byte *value)
        {
            tSystemArray *pArray = (tSystemArray *)pThis_;
            tMD_TypeDef * pArrayTypeDef;
            uint          elemSize;
            byte *        pElements;

        #if WIN32 && _DEBUG
            // Do a bounds check
            if (index >= pArray->length)
            {
                printf("SystemArray.StoreElement() Bounds check failed. Array length: %d  index: %d\n", pArray->length, index);
                __debugbreak();
            }
        #endif

            pArrayTypeDef = Heap.GetType(pThis_);
            elemSize      = pArrayTypeDef->pArrayElementType->arrayElementSize;
            pElements     = tSystemArray.GetElements(pArray);
            switch (elemSize)
            {
            case 1:
                ((byte *)pElements)[index] = *(byte *)value;
                break;

            case 2:
                ((ushort *)pElements)[index] = *(ushort *)value;
                break;

            case 4:
                ((uint *)pElements)[index] = *(uint *)value;
                break;

            default:
                Mem.memcpy(&pElements[index * elemSize], value, (SIZE_T)elemSize);
                break;
            }
        }
Exemple #18
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);
        }
Exemple #19
0
        public static tAsyncCall *InternalTrim(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemString *    pThis = (tSystemString *)pThis_;
            /*HEAP_PTR*/ byte *pWhiteChars;
            uint           trimType, i, j, checkCharsLen;
            uint           ofsStart, ofsEnd;
            ushort *       pCheckChars;
            uint           isWhiteSpace;
            tSystemString *pRet;
            ushort         c;
            char *         pChars, pRetChars;

            pWhiteChars   = (*((/*HEAP_PTR*/ byte **)(pParams + 0)));
            trimType      = (*((uint *)(pParams + Sys.S_PTR)));
            pCheckChars   = (ushort *)System_Array.GetElements(pWhiteChars);
            checkCharsLen = System_Array.GetLength(pWhiteChars);

            ofsStart = 0;
            ofsEnd   = pThis->length;
            pChars   = tSystemString.GetChars(pThis);
            if ((trimType & 1) != 0)
            {
                // Trim start
                for (i = ofsStart; i < ofsEnd; i++)
                {
                    // Check if each char is in the array
                    isWhiteSpace = 0;
                    c            = pChars[i];
                    for (j = 0; j < checkCharsLen; j++)
                    {
                        if (c == pCheckChars[j])
                        {
                            isWhiteSpace = 1;
                            break;
                        }
                    }
                    if (isWhiteSpace == 0)
                    {
                        ofsStart = i;
                        break;
                    }
                }
            }
            if ((trimType & 2) != 0)
            {
                // Trim end
                for (i = ofsEnd - 1; i >= ofsStart; i--)
                {
                    // Check if each char is in the array
                    isWhiteSpace = 0;
                    c            = pChars[i];
                    for (j = 0; j < checkCharsLen; j++)
                    {
                        if (c == pCheckChars[j])
                        {
                            isWhiteSpace = 1;
                            break;
                        }
                    }
                    if (isWhiteSpace == 0)
                    {
                        ofsEnd = i + 1;
                        break;
                    }
                }
            }

            pRet      = CreateStringHeapObj(ofsEnd - ofsStart);
            pRetChars = tSystemString.GetChars(pRet);
            Mem.memcpy(pRetChars, &pChars[ofsStart], (SIZE_T)((ofsEnd - ofsStart) << 1));
            Sys.INTERNALCALL_RESULT_PTR(pReturnValue, pRet);

            return(null);
        }
Exemple #20
0
        public static tMD_TypeDef *GetGenericTypeFromCoreType(tMD_TypeDef *pCoreType, uint numTypeArgs,
                                                              tMD_TypeDef **ppTypeArgs)
        {
            tGenericInstance *pInst;
            tMD_TypeDef *     pTypeDef;
            uint       i;
            byte *     name = stackalloc byte[NAME_BUF_SIZE];
            byte *     namePos, nameEnd;
            tMetaData *pMetaData;

            Mem.heapcheck();

            pMetaData = pCoreType->pMetaData;
            MetaData.Fill_TypeDef(pCoreType, null, null, Type.TYPE_FILL_PARENTS);

            // See if we have already built an instantiation of this type with the given type args.
            pInst = pCoreType->pGenericInstances;
            while (pInst != null)
            {
                if (pInst->numTypeArgs == numTypeArgs &&
                    Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0)
                {
                    return(pInst->pInstanceTypeDef);
                }
                pInst = pInst->pNext;
            }

            // This has not already been instantiated, so instantiate it now.
            pInst = (tGenericInstance *)Mem.mallocForever((SIZE_T)sizeof(tGenericInstance));
            // Insert this into the chain of instantiations.
            pInst->pNext = pCoreType->pGenericInstances;
            pCoreType->pGenericInstances = pInst;
            // Copy the type args into the instantiation.
            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 *)));

            Mem.heapcheck();

            // Create the new instantiated type
            pInst->pInstanceTypeDef = pTypeDef = ((tMD_TypeDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_TypeDef)));
            Mem.memset(pTypeDef, 0, (SIZE_T)sizeof(tMD_TypeDef));
            // Make the name of the instantiation.
            namePos = name;
            nameEnd = namePos + NAME_BUF_SIZE - 1;
            namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)pCoreType->name);
            namePos = S.scatprintf(namePos, nameEnd, "[");
            for (i = 0; i < numTypeArgs; i++)
            {
                if (i > 0)
                {
                    namePos = S.scatprintf(namePos, nameEnd, ",");
                }
                if (ppTypeArgs[i] != null)
                {
                    namePos = S.scatprintf(namePos, nameEnd, "%s.%s", (PTR)ppTypeArgs[i]->nameSpace, (PTR)ppTypeArgs[i]->name);
                }
                else
                {
                    tMD_GenericParam *pGenericParam = FindGenericParam(pCoreType, i);
                    if (pGenericParam != null)
                    {
                        namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)pGenericParam->name);
                    }
                    else
                    {
                        namePos = S.scatprintf(namePos, nameEnd, "???");
                    }
                }
            }
            namePos = S.scatprintf(namePos, nameEnd, "]");
            // Fill in the basic bits of the new type def.
            pTypeDef->pTypeDef           = pTypeDef;
            pTypeDef->pMetaData          = pMetaData;
            pTypeDef->flags              = pCoreType->flags;
            pTypeDef->pGenericDefinition = pCoreType;
            for (i = 0; i < numTypeArgs; i++)
            {
                if (ppTypeArgs[i] == null)
                {
                    pTypeDef->isGenericDefinition = 1;
                    break;
                }
            }
            pTypeDef->nameSpace = pCoreType->nameSpace;
            int nameLen = S.strlen(name) + 1;

            pTypeDef->name = (/*STRING*/ byte *)Mem.mallocForever((SIZE_T)nameLen);
            S.strncpy(pTypeDef->name, name, nameLen);
            pTypeDef->ppClassTypeArgs   = pInst->ppTypeArgs;
            pTypeDef->extends           = pCoreType->extends;
            pTypeDef->tableIndex        = pCoreType->tableIndex;
            pTypeDef->fieldList         = pCoreType->fieldList;
            pTypeDef->methodList        = pCoreType->methodList;
            pTypeDef->numFields         = pCoreType->numFields;
            pTypeDef->numMethods        = pCoreType->numMethods;
            pTypeDef->numVirtualMethods = pCoreType->numVirtualMethods;
            pTypeDef->pNestedIn         = pCoreType->pNestedIn;
            pTypeDef->isPrimed          = 1;

            MetaData.Fill_TypeDef(pTypeDef, pInst->ppTypeArgs, null, Type.TYPE_FILL_PARENTS);

            Mem.heapcheck();

            return(pTypeDef);
        }
Exemple #21
0
        public static tAsyncCall *InternalReplace(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemString *pThis = (tSystemString *)pThis_;
            tSystemString *pOld  = (*((tSystemString **)(pParams + 0)));
            tSystemString *pNew  = (*((tSystemString **)(pParams + Sys.S_PTR)));
            tSystemString *pResult;
            uint           thisLen, oldLen, newLen;
            char *         pThisChar0, pOldChar0, pNewChar0, pResultChar0;
            uint           i, j, replacements, dstIndex;
            uint           resultLen;

            // This function (correctly) assumes that the old string is not empty
            thisLen    = pThis->length;
            oldLen     = pOld->length;
            newLen     = pNew->length;
            pThisChar0 = tSystemString.GetChars(pThis);
            pOldChar0  = tSystemString.GetChars(pOld);
            pNewChar0  = tSystemString.GetChars(pNew);

            replacements = 0;
            for (i = 0; i < thisLen - oldLen + 1; i++)
            {
                uint match = 1;
                for (j = 0; j < oldLen; j++)
                {
                    if (pThisChar0[i + j] != pOldChar0[j])
                    {
                        match = 0;
                        break;
                    }
                }
                if (match != 0)
                {
                    i += oldLen - 1;
                    replacements++;
                }
            }
            resultLen    = thisLen - (oldLen - newLen) * replacements;
            pResult      = CreateStringHeapObj(resultLen);
            pResultChar0 = tSystemString.GetChars(pResult);
            dstIndex     = 0;
            for (i = 0; i < thisLen; i++)
            {
                uint match = 1;
                if (i < thisLen - oldLen + 1)
                {
                    for (j = 0; j < oldLen; j++)
                    {
                        match = 1;
                        if (pThisChar0[i + j] != pOldChar0[j])
                        {
                            match = 0;
                            break;
                        }
                    }
                }
                else
                {
                    match = 0;
                }
                if (match != 0)
                {
                    Mem.memcpy(&pResultChar0[dstIndex], pNewChar0, newLen << 1);
                    dstIndex += newLen;
                    i        += oldLen - 1;
                }
                else
                {
                    pResultChar0[dstIndex++] = pThisChar0[i];
                }
            }
            Sys.INTERNALCALL_RESULT_PTR(pReturnValue, pResult);

            return(null);
        }
Exemple #22
0
        // Value-Type.types will be boxed
        public static tAsyncCall *Internal_SetValue(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue)
        {
            tSystemArray *     pArray = (tSystemArray *)pThis_;
            tMD_TypeDef *      pArrayType, pObjType;
            uint               index, elementSize;
            /*HEAP_PTR*/ byte *obj;
            tMD_TypeDef *      pElementType;
            byte *             pElement;

            pArrayType   = Heap.GetType(pThis_);
            obj          = (*((byte **)(pParams + 0)));
            pObjType     = Heap.GetType(obj);
            pElementType = pArrayType->pArrayElementType;
            // Check to see if the Type is ok to put in the array
            if (!(Type.IsAssignableFrom(pElementType, pObjType) != 0 ||
                  (pElementType->pGenericDefinition == Type.types[Type.TYPE_SYSTEM_NULLABLE] &&
                   pElementType->ppClassTypeArgs[0] == pObjType)))
            {
                // Can't be done
                Sys.INTERNALCALL_RESULT_U32(pReturnValue, 0);
                return(null);
            }

            index = (*((uint *)(pParams + Sys.S_PTR)));

        #if WIN32 && _DEBUG
            // Do a bounds-check
            if (index >= pArray->length)
            {
                printf("[Array] Internal_SetValue() Bounds-check failed\n");
                __debugbreak();
            }
        #endif

            elementSize = pElementType->arrayElementSize;
            pElement    = tSystemArray.GetElements(pArray) + elementSize * index;
            if (pElementType->isValueType != 0)
            {
                if (pElementType->pGenericDefinition == Type.types[Type.TYPE_SYSTEM_NULLABLE])
                {
                    // Nullable type, so treat specially
                    if (obj == null)
                    {
                        Mem.memset(pElement, 0, elementSize);
                    }
                    else
                    {
                        *(uint *)pElement = 1;
                        Mem.memcpy(pElement + 4, obj, elementSize - 4);
                    }
                }
                else
                {
                    // Get the value out of the box
                    Mem.memcpy(pElement, obj, elementSize);
                }
            }
            else
            {
                // This must be a reference type, so it must be 32-bits wide
                *(/*HEAP_PTR*/ byte **)pElement = obj;
            }
            Sys.INTERNALCALL_RESULT_U32(pReturnValue, 1);

            return(null);
        }
Exemple #23
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);
        }
Exemple #24
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);
        }
Exemple #25
0
 public static void SetParameters(tMethodState *pMethodState, tMD_MethodDef *pCallMethod, byte *pParams)
 {
     Mem.memcpy(pMethodState->pParamsLocals, pParams, pCallMethod->parameterStackSize);
 }