コード例 #1
0
ファイル: assemblymd_emit.cpp プロジェクト: 0-wiz-0/coreclr
//*******************************************************************************
// Helper: Set the specified attributes on the given ExportedType token.
//*******************************************************************************
HRESULT RegMeta::_SetExportedTypeProps( // S_OK or error.
    mdExportedType   ct,                // [IN] ExportedType token.
    mdToken     tkImplementation,       // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
    mdTypeDef   tkTypeDef,              // [IN] TypeDef token within the file.
    DWORD       dwExportedTypeFlags)    // [IN] Flags.
{
    ExportedTypeRec  *pRecord;
    HRESULT     hr = S_OK;

    IfFailGo(m_pStgdb->m_MiniMd.GetExportedTypeRecord(RidFromToken(ct), &pRecord));

    if(! IsNilToken(tkImplementation))
        IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation,
                                        pRecord, tkImplementation));
    if (! IsNilToken(tkTypeDef))
    {
        _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef);
        pRecord->SetTypeDefId(tkTypeDef);
    }
    if (dwExportedTypeFlags != ULONG_MAX)
        pRecord->SetFlags(dwExportedTypeFlags);

    IfFailGo(UpdateENCLog(ct));
ErrExit:
    return hr;
}   // RegMeta::_SetExportedTypeProps
コード例 #2
0
int GetVersionResilientTypeHashCode(IMDInternalImport *pMDImport, mdExportedType token)
{
    _ASSERTE(TypeFromToken(token) == mdtTypeDef ||
        TypeFromToken(token) == mdtTypeRef ||
        TypeFromToken(token) == mdtExportedType);
    _ASSERTE(!IsNilToken(token));

    HRESULT hr;
    LPCUTF8 szNamespace;
    LPCUTF8 szName;
    bool hasTypeToken = true;
    int hashcode = 0;

    while (hasTypeToken)
    {
        if (IsNilToken(token))
            ThrowHR(COR_E_BADIMAGEFORMAT);

        switch (TypeFromToken(token))
        {
        case mdtTypeDef:
            if (FAILED(pMDImport->GetNameOfTypeDef(token, &szName, &szNamespace)))
                ThrowHR(COR_E_BADIMAGEFORMAT);
            hr = pMDImport->GetNestedClassProps(token, &token);
            if (hr == CLDB_E_RECORD_NOTFOUND)
                hasTypeToken = false;
            else if (FAILED(hr))
                ThrowHR(COR_E_BADIMAGEFORMAT);
            break;

        case mdtTypeRef:
            if (FAILED(pMDImport->GetNameOfTypeRef(token, &szNamespace, &szName)))
                ThrowHR(COR_E_BADIMAGEFORMAT);
            if (FAILED(pMDImport->GetResolutionScopeOfTypeRef(token, &token)))
                ThrowHR(COR_E_BADIMAGEFORMAT);
            hasTypeToken = (TypeFromToken(token) == mdtTypeRef);
            break;

        case mdtExportedType:
            if (FAILED(pMDImport->GetExportedTypeProps(token, &szNamespace, &szName, &token, NULL, NULL)))
                ThrowHR(COR_E_BADIMAGEFORMAT);
            hasTypeToken = (TypeFromToken(token) == mdtExportedType);
            break;

        default:
            ThrowHR(COR_E_BADIMAGEFORMAT);
        }

        hashcode ^= ComputeNameHashCode(szNamespace, szName);
    }

    return hashcode;
}
コード例 #3
0
ファイル: comdynamic.cpp プロジェクト: DrewScoggins/coreclr
void QCALLTYPE COMDynamicWrite::TermCreateClass(QCall::ModuleHandle pModule, INT32 tk, QCall::ObjectHandleOnStack retType)
{
    QCALL_CONTRACT;
    
    TypeHandle typeHnd;

    BEGIN_QCALL;
    
    _ASSERTE(pModule->GetReflectionModule()->GetClassWriter()); 

    // Use the same service, regardless of whether we are generating a normal
    // class, or the special class for the module that holds global functions
    // & methods.
    pModule->GetReflectionModule()->AddClass(tk);

    // manually load the class if it is not the global type
    if (!IsNilToken(tk))
    {
        TypeKey typeKey(pModule, tk);
        typeHnd = pModule->GetClassLoader()->LoadTypeHandleForTypeKey(&typeKey, TypeHandle());
    }

    if (!typeHnd.IsNull())
    {
        GCX_COOP();
        retType.Set(typeHnd.GetManagedClassObject());
    }

    END_QCALL;

    return;
}
コード例 #4
0
int GetVersionResilientTypeHashCode(TypeHandle type)
{
    if (!type.IsTypeDesc())
    {
        MethodTable *pMT = type.AsMethodTable();

        _ASSERTE(!pMT->IsArray());
        _ASSERTE(!IsNilToken(pMT->GetCl()));

        LPCUTF8 szNamespace;
        LPCUTF8 szName;
        IfFailThrow(pMT->GetMDImport()->GetNameOfTypeDef(pMT->GetCl(), &szName, &szNamespace));
        int hashcode = ComputeNameHashCode(szNamespace, szName);

        MethodTable *pMTEnclosing = pMT->LoadEnclosingMethodTable(CLASS_LOAD_UNRESTOREDTYPEKEY);
        if (pMTEnclosing != NULL)
        {
            hashcode = ComputeNestedTypeHashCode(GetVersionResilientTypeHashCode(TypeHandle(pMTEnclosing)), hashcode);
        }

        if (!pMT->IsGenericTypeDefinition() && pMT->HasInstantiation())
        {
            return ComputeGenericInstanceHashCode(hashcode,
                pMT->GetInstantiation().GetNumArgs(), pMT->GetInstantiation(), GetVersionResilientTypeHashCode);
        }
        else
        {
            return hashcode;
        }
    }
    else
    if (type.IsArray())
    {
        ArrayTypeDesc *pArray = type.AsArray();
        return ComputeArrayTypeHashCode(GetVersionResilientTypeHashCode(pArray->GetArrayElementTypeHandle()), pArray->GetRank());
    }
    else
    if (type.IsPointer())
    {
        return ComputePointerTypeHashCode(GetVersionResilientTypeHashCode(type.AsTypeDesc()->GetTypeParam()));
    }
    else
    if (type.IsByRef())
    {
        return ComputeByrefTypeHashCode(GetVersionResilientTypeHashCode(type.AsTypeDesc()->GetTypeParam()));
    }

    assert(false);
    return 0;
}
コード例 #5
0
ファイル: binder.cpp プロジェクト: ArildF/masters
MethodTable *Binder::LookupClass(BinderClassID id, BOOL fLoad)
{
    _ASSERTE(m_pModule != NULL);
    _ASSERTE(id != CLASS__NIL);
    _ASSERTE(id <= m_cClassRIDs);

    MethodTable *pMT;

    const ClassDescription *d = m_classDescriptions + id - 1;

    NameHandle nh(d->name);

    if (!fLoad)
    {
        nh.SetTokenNotToLoad(tdAllTypes);
        pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh).AsMethodTable();
        if (pMT == NULL)
            return NULL;
    }
    else
    {
        THROWSCOMPLUSEXCEPTION();

        BEGIN_ENSURE_COOPERATIVE_GC();
        OBJECTREF pThrowable = NULL;
        GCPROTECT_BEGIN(pThrowable);

        pMT = m_pModule->GetClassLoader()->FindTypeHandle(&nh, &pThrowable).AsMethodTable();
        if (pMT == NULL)
        {
            _ASSERTE(!"EE expects class to exist");
            COMPlusThrow(pThrowable);
        }
        GCPROTECT_END();
        END_ENSURE_COOPERATIVE_GC();
    }

    _ASSERTE(pMT->GetModule() == m_pModule);

    mdTypeDef td = pMT->GetClass()->GetCl();

    _ASSERTE(!IsNilToken(td));

    _ASSERTE(RidFromToken(td) <= USHRT_MAX);
    m_pClassRIDs[id-1] = (USHORT) RidFromToken(td);

    m_pModule->StoreTypeDef(td, pMT);

    return pMT;
}
コード例 #6
0
//*****************************************************************************
// Given a namespace and a class name, return the typedef
//*****************************************************************************
STDMETHODIMP RegMeta::FindTypeDefByName(// S_OK or error.
    LPCWSTR     wzTypeDef,              // [IN] Name of the Type.
    mdToken     tkEnclosingClass,       // [IN] Enclosing class.
    mdTypeDef   *ptd)                   // [OUT] Put the TypeDef token here.
{
    HRESULT     hr = S_OK;
    BEGIN_ENTRYPOINT_NOTHROW

    LOG((LOGMD, "{%08x} RegMeta::FindTypeDefByName(%S, 0x%08x, 0x%08x)\n", 
            this, MDSTR(wzTypeDef), tkEnclosingClass, ptd));
    START_MD_PERF();
    LOCKREAD();


    if (wzTypeDef == NULL)
        IfFailGo(E_INVALIDARG);
    PREFIX_ASSUME(wzTypeDef != NULL);
    LPSTR       szTypeDef;
    UTF8STR(wzTypeDef, szTypeDef);
    LPCSTR      szNamespace;
    LPCSTR      szName;

    _ASSERTE(ptd);
    _ASSERTE(TypeFromToken(tkEnclosingClass) == mdtTypeDef ||
             TypeFromToken(tkEnclosingClass) == mdtTypeRef ||
             IsNilToken(tkEnclosingClass));

    // initialize output parameter
    *ptd = mdTypeDefNil;

    ns::SplitInline(szTypeDef, szNamespace, szName);
    hr = ImportHelper::FindTypeDefByName(&(m_pStgdb->m_MiniMd), 
                                        szNamespace, 
                                        szName, 
                                        tkEnclosingClass, 
                                        ptd);
ErrExit:
    
    STOP_MD_PERF(FindTypeDefByName);
    END_ENTRYPOINT_NOTHROW;
    
    return hr;
} // STDMETHODIMP RegMeta::FindTypeDefByName()
コード例 #7
0
ファイル: regmeta_vm.cpp プロジェクト: A-And/coreclr
//*****************************************************************************
// Implementation of IMetaDataImport::ResolveTypeRef to resolve a typeref across scopes. 
// 
// Arguments:
//    tr - typeref within this scope to resolve
//    riid - interface on ppIScope to support
//    ppIScope - out-parameter to get metadata scope for typedef (*ptd)
//    ptd - out-parameter to get typedef that the ref resolves to.
// 
// Notes:
// TypeDefs define a type within a scope. TypeRefs refer to type-defs in other scopes
// and allow you to import a type from another scope. This function attempts to determine
// which type-def a type-ref points to.
// 
// This resolve (type-ref, this cope) --> (type-def=*ptd, other scope=*ppIScope)
// 
// However, this resolution requires knowing what modules have been loaded, which is not decided
// until runtime via loader / fusion policy. Thus this interface can't possibly be correct since
// it doesn't have that knowledge. Furthermore, when inspecting metadata from another process
// (such as a debugger inspecting the debuggee's metadata), this API can be truly misleading.
// 
// This API usage should be avoided.
// 
//*****************************************************************************
STDMETHODIMP 
RegMeta::ResolveTypeRef(
    mdTypeRef   tr, 
    REFIID      riid, 
    IUnknown ** ppIScope, 
    mdTypeDef * ptd)
{
#ifdef FEATURE_METADATA_IN_VM
    HRESULT hr;

    BEGIN_ENTRYPOINT_NOTHROW;

    TypeRefRec * pTypeRefRec;
    WCHAR        wzNameSpace[_MAX_PATH];
    CMiniMdRW *  pMiniMd = NULL;

    LOG((LOGMD, "{%08x} RegMeta::ResolveTypeRef(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", 
        this, tr, riid, ppIScope, ptd));

    START_MD_PERF();
    LOCKREAD();

    pMiniMd = &(m_pStgdb->m_MiniMd);

    _ASSERTE((ppIScope != NULL) && (ptd != NULL));

    // Init the output values.
    *ppIScope = NULL;
    *ptd = 0;

    if (IsNilToken(tr))
    {
        if (ptd != NULL) 
        {
            *ptd = mdTypeDefNil;
        }

        if (ppIScope != NULL)
        {
            *ppIScope = NULL;
        }
        
        STOP_MD_PERF(ResolveTypeRef);
        hr = E_INVALIDARG;
        goto ErrExit;
    }

    if (TypeFromToken(tr) == mdtTypeDef)
    {
        // Shortcut when we receive a TypeDef token
        *ptd = tr;
        STOP_MD_PERF(ResolveTypeRef);
        hr = this->QueryInterface(riid, (void **)ppIScope);
        goto ErrExit;
    }

    // Get the class ref row.
    _ASSERTE(TypeFromToken(tr) == mdtTypeRef);

    IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tr), &pTypeRefRec));
    IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, wzNameSpace, lengthof(wzNameSpace), NULL));
    if (hr != NOERROR)
    {
        _ASSERTE(hr == CLDB_S_TRUNCATION);
        // Truncate the namespace string
        wzNameSpace[lengthof(wzNameSpace) - 1] = 0;
    }
    
    //***********************
    // before we go off to CORPATH, check the loaded modules!
    //***********************
    if (LOADEDMODULES::ResolveTypeRefWithLoadedModules(
        tr, 
        this, 
        pMiniMd, 
        riid, 
        ppIScope, 
        ptd) == NOERROR)
    {
        // Done!! We found one match among the loaded modules.
        goto ErrExit;
    }

    IfFailGo(META_E_CANNOTRESOLVETYPEREF);

ErrExit:
    STOP_MD_PERF(ResolveTypeRef);
    END_ENTRYPOINT_NOTHROW;
    
    return hr;
#else // FEATURE_METADATA_IN_VM
    return E_NOTIMPL;
#endif // FEATURE_METADATA_IN_VM
} // RegMeta::ResolveTypeRef
コード例 #8
0
ファイル: sildasm.cpp プロジェクト: BikS2013/coreclr
//PrettyPrinting type names
PCCOR_SIGNATURE PrettyPrintType(
    PCCOR_SIGNATURE typePtr,            // type to convert,     
    CQuickBytes *out,                   // where to put the pretty printed string   
    IMDInternalImport *pIMDI,           // ptr to IMDInternal class with ComSig
    DWORD formatFlags /*= formatILDasm*/)
{
    mdToken  tk;    
    const char* str;    
    int typ;
    CQuickBytes tmp;
    CQuickBytes Appendix;
    BOOL Reiterate;
    int n;

    do {
        Reiterate = FALSE;
        switch(typ = *typePtr++) {    
            case ELEMENT_TYPE_VOID          :   
                str = "void"; goto APPEND;  
            case ELEMENT_TYPE_BOOLEAN       :   
                str = "bool"; goto APPEND;  
            case ELEMENT_TYPE_CHAR          :   
                str = "char"; goto APPEND; 
            case ELEMENT_TYPE_I1            :   
                str = "int8"; goto APPEND;  
            case ELEMENT_TYPE_U1            :   
                str = "uint8"; goto APPEND; 
            case ELEMENT_TYPE_I2            :   
                str = "int16"; goto APPEND; 
            case ELEMENT_TYPE_U2            :   
                str = "uint16"; goto APPEND;    
            case ELEMENT_TYPE_I4            :   
                str = "int32"; goto APPEND; 
            case ELEMENT_TYPE_U4            :   
                str = "uint32"; goto APPEND;    
            case ELEMENT_TYPE_I8            :   
                str = "int64"; goto APPEND; 
            case ELEMENT_TYPE_U8            :   
                str = "uint64"; goto APPEND;    
            case ELEMENT_TYPE_R4            :   
                str = "float32"; goto APPEND;   
            case ELEMENT_TYPE_R8            :   
                str = "float64"; goto APPEND;   
            case ELEMENT_TYPE_U             :   
                str = "native uint"; goto APPEND;   
            case ELEMENT_TYPE_I             :   
                str = "native int"; goto APPEND;    
            case ELEMENT_TYPE_OBJECT        :   
                str = "object"; goto APPEND;    
            case ELEMENT_TYPE_STRING        :   
                str = "string"; goto APPEND;    
            case ELEMENT_TYPE_TYPEDBYREF        :   
                str = "typedref"; goto APPEND;    
            APPEND: 
                appendStr(out, (char*)str);
                break;  

            case ELEMENT_TYPE_VALUETYPE    :   
                if ((formatFlags & FormatKwInNames) != 0) 
                    str = "valuetype ";   
                else str = "";
                goto DO_CLASS;  
            case ELEMENT_TYPE_CLASS         :   
                if ((formatFlags & FormatKwInNames) != 0) 
                    str = "class "; 
                else str = "";
                goto DO_CLASS;  

            DO_CLASS:
                appendStr(out, (char*)str);
                typePtr += CorSigUncompressToken(typePtr, &tk); 
                if(IsNilToken(tk))
                {
                    appendStr(out, "[ERROR! NIL TOKEN]");
                }
                else PrettyPrintClass(out, tk, pIMDI, formatFlags);
                break;  

            case ELEMENT_TYPE_SZARRAY    :   
                insertStr(&Appendix,"[]");
                Reiterate = TRUE;
                break;
            
            case ELEMENT_TYPE_ARRAY       :   
                {   
                typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags);
                unsigned rank = CorSigUncompressData(typePtr);  
                    // <TODO> what is the syntax for the rank 0 case? </TODO> 
                if (rank == 0) {
                    appendStr(out, "[BAD: RANK == 0!]");
                }
                else {
                    _ASSERTE(rank != 0);
#ifdef _PREFAST_
#pragma warning(push)
#pragma warning(disable:22009) // "Suppress PREfast warnings about integer overflow"
// PREFAST warns about using _alloca in a loop.  However when we're in this switch case we do NOT
// set Reiterate to true, so we only execute through the loop once!
#pragma warning(disable:6263) // "Suppress PREfast warnings about stack overflow due to _alloca in a loop."
#endif
                    int* lowerBounds = (int*) _alloca(sizeof(int)*2*rank);
                    int* sizes       = &lowerBounds[rank];  
                    memset(lowerBounds, 0, sizeof(int)*2*rank); 
                    
                    unsigned numSizes = CorSigUncompressData(typePtr);  
                    _ASSERTE(numSizes <= rank);
                        unsigned i;
                    for(i =0; i < numSizes; i++)
                        sizes[i] = CorSigUncompressData(typePtr);   
                    
                    unsigned numLowBounds = CorSigUncompressData(typePtr);  
                    _ASSERTE(numLowBounds <= rank); 
                    for(i = 0; i < numLowBounds; i++)   
                        typePtr+=CorSigUncompressSignedInt(typePtr,&lowerBounds[i]); 
                    
                    appendChar(out, '[');    
                    if (rank == 1 && numSizes == 0 && numLowBounds == 0)
                        appendStr(out, "...");  
                    else {
                        for(i = 0; i < rank; i++)   
                        {   
                            //if (sizes[i] != 0 || lowerBounds[i] != 0)   
                            {   
                                if (lowerBounds[i] == 0 && i < numSizes)    
                                    appendStrNum(out, sizes[i]);    
                                else    
                                {   
                                    if(i < numLowBounds)
                                    {
                                        appendStrNum(out, lowerBounds[i]);  
                                        appendStr(out, "...");  
                                        if (/*sizes[i] != 0 && */i < numSizes)  
                                            appendStrNum(out, lowerBounds[i] + sizes[i] - 1);   
                                    }
                                }   
                            }   
                            if (i < rank-1) 
                                appendChar(out, ',');    
                        }   
                    }
                    appendChar(out, ']'); 
#ifdef _PREFAST_
#pragma warning(pop)
#endif
                }
                } break;    

            case ELEMENT_TYPE_VAR        :   
                appendChar(out, '!');
                n  = CorSigUncompressData(typePtr);
                appendStrNum(out, n);
                break;

            case ELEMENT_TYPE_MVAR        :   
                appendChar(out, '!');    
                appendChar(out, '!');    
                n  = CorSigUncompressData(typePtr);
                appendStrNum(out, n);
                break;

            case ELEMENT_TYPE_FNPTR :   
                appendStr(out, "method ");  
                appendStr(out, "METHOD"); // was: typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMDI, NULL);
                break;

            case ELEMENT_TYPE_GENERICINST :
            {
              typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags);
              if ((formatFlags & FormatSignature) == 0)
                  break;

              if ((formatFlags & FormatAngleBrackets) != 0)
                  appendStr(out, "<");
              else
                  appendStr(out,"[");
              unsigned numArgs = CorSigUncompressData(typePtr);    
              bool needComma = false;
              while(numArgs--)
              {
                  if (needComma)
                      appendChar(out, ',');
                  typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags);
                  needComma = true;
              }
              if ((formatFlags & FormatAngleBrackets) != 0)
                  appendStr(out, ">");
              else
                  appendStr(out,"]");
              break;
            }

            case ELEMENT_TYPE_PINNED	:
                str = " pinned"; goto MODIFIER;
            case ELEMENT_TYPE_PTR           :
                str = "*"; goto MODIFIER;
            case ELEMENT_TYPE_BYREF         :
                str = "&"; goto MODIFIER;
            MODIFIER:
                insertStr(&Appendix, str);
                Reiterate = TRUE;
                break;  

            default:    
            case ELEMENT_TYPE_SENTINEL      :   
            case ELEMENT_TYPE_END           :   
                //_ASSERTE(!"Unknown Type");
                if(typ)
                {
                    char sz[64];
                    sprintf_s(sz,COUNTOF(sz),"/* UNKNOWN TYPE (0x%X)*/",typ);
                    appendStr(out, sz);
                }
                break;  
        } // end switch
    } while(Reiterate);
    if (Appendix.Size() > 0)
        appendStr(out,asString(&Appendix));

    return(typePtr);    
}
コード例 #9
0
ファイル: corhlpr.cpp プロジェクト: koson/.NETMF_for_LPC17xx
    // emit the section (best format);
    unsigned __stdcall SectEH_Emit(unsigned size, unsigned ehCount,
                                   IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clauses,
                                   BOOL moreSections, BYTE* outBuff,
                                   ULONG* ehTypeOffsets)
    {
        if (size == 0)
            return(0);

        _ASSERTE((((size_t) outBuff) & 3) == 0);               // header is dword aligned
        BYTE* origBuff = outBuff;
        if (ehCount <= 0)
            return 0;

        // Initialize the ehTypeOffsets array.
        if (ehTypeOffsets)
        {
            for (unsigned int i = 0; i < ehCount; i++)
                ehTypeOffsets[i] = (ULONG) -1;
        }

        if (COR_ILMETHOD_SECT_EH_SMALL::Size(ehCount) < COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE) {
            COR_ILMETHOD_SECT_EH_SMALL* EHSect = (COR_ILMETHOD_SECT_EH_SMALL*) outBuff;
            unsigned i;
            for (i = 0; i < ehCount; i++) {
                COR_ILMETHOD_SECT_EH_CLAUSE_FAT* fatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&clauses[i];
                if (fatClause->GetTryOffset() > 0xFFFF ||
                        fatClause->GetTryLength() > 0xFF ||
                        fatClause->GetHandlerOffset() > 0xFFFF ||
                        fatClause->GetHandlerLength() > 0xFF) {
                    break;  // fall through and generate as FAT
                }
                _ASSERTE((fatClause->GetFlags() & ~0xFFFF) == 0);
                _ASSERTE((fatClause->GetTryOffset() & ~0xFFFF) == 0);
                _ASSERTE((fatClause->GetTryLength() & ~0xFF) == 0);
                _ASSERTE((fatClause->GetHandlerOffset() & ~0xFFFF) == 0);
                _ASSERTE((fatClause->GetHandlerLength() & ~0xFF) == 0);

                COR_ILMETHOD_SECT_EH_CLAUSE_SMALL* smallClause = (COR_ILMETHOD_SECT_EH_CLAUSE_SMALL*)&EHSect->Clauses[i];
                smallClause->SetFlags((CorExceptionFlag) fatClause->GetFlags());
                smallClause->SetTryOffset(fatClause->GetTryOffset());
                smallClause->SetTryLength(fatClause->GetTryLength());
                smallClause->SetHandlerOffset(fatClause->GetHandlerOffset());
                smallClause->SetHandlerLength(fatClause->GetHandlerLength());
                smallClause->SetClassToken(fatClause->GetClassToken());
            }
            if (i >= ehCount) {
                // if actually got through all the clauses and they are small enough
                EHSect->Kind = CorILMethod_Sect_EHTable;
                if (moreSections)
                    EHSect->Kind |= CorILMethod_Sect_MoreSects;
                EHSect->DataSize = EHSect->Size(ehCount);
                EHSect->Reserved = 0;
                _ASSERTE(EHSect->DataSize == EHSect->Size(ehCount)); // make sure didn't overflow
                outBuff = (BYTE*) &EHSect->Clauses[ehCount];
                // Set the offsets for the exception type tokens.
                if (ehTypeOffsets)
                {
                    for (i = 0; i < ehCount; i++) {
                        COR_ILMETHOD_SECT_EH_CLAUSE_SMALL* smallClause = (COR_ILMETHOD_SECT_EH_CLAUSE_SMALL*)&EHSect->Clauses[i];
                        if (smallClause->GetFlags() == COR_ILEXCEPTION_CLAUSE_NONE)
                        {
                            _ASSERTE(! IsNilToken(smallClause->GetClassToken()));
                            ehTypeOffsets[i] = (ULONG)((BYTE *)&smallClause->ClassToken - origBuff);
                        }
                    }
                }
                return(size);
            }
        }
        // either total size too big or one of constituent elements too big (eg. offset or length)
        COR_ILMETHOD_SECT_EH_FAT* EHSect = (COR_ILMETHOD_SECT_EH_FAT*) outBuff;
        EHSect->SetKind(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat);
        if (moreSections)
            EHSect->SetKind(EHSect->GetKind() | CorILMethod_Sect_MoreSects);

        EHSect->SetDataSize(EHSect->Size(ehCount));
        memcpy(EHSect->Clauses, clauses, ehCount * sizeof(COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
        outBuff = (BYTE*) &EHSect->Clauses[ehCount];
        _ASSERTE(&origBuff[size] == outBuff);
        // Set the offsets for the exception type tokens.
        if (ehTypeOffsets)
        {
            for (unsigned int i = 0; i < ehCount; i++) {
                COR_ILMETHOD_SECT_EH_CLAUSE_FAT* fatClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)&EHSect->Clauses[i];
                if (fatClause->GetFlags() == COR_ILEXCEPTION_CLAUSE_NONE)
                {
                    _ASSERTE(! IsNilToken(fatClause->GetClassToken()));
                    ehTypeOffsets[i] = (ULONG)((BYTE *)&fatClause->ClassToken - origBuff);
                }
            }
        }
        return(size);
    }
コード例 #10
0
ファイル: custattr_import.cpp プロジェクト: Afshintm/coreclr
//*****************************************************************************
// Enumerate the CustomAttributes for a given token.
//*****************************************************************************
STDMETHODIMP RegMeta::EnumCustomAttributes(
    HCORENUM        *phEnum,            // Pointer to the enum.
    mdToken         tk,                 // Token to scope the enumeration.
    mdToken         tkType,             // Type to limit the enumeration.
    mdCustomAttribute   rCustomAttributes[],    // Put CustomAttributes here.
    ULONG           cMax,               // Max CustomAttributes to put.
    ULONG           *pcCustomAttributes)    // Put # tokens returned here.
{
    HRESULT         hr = S_OK;

    BEGIN_ENTRYPOINT_NOTHROW;

    HENUMInternal   **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum);
    ULONG           ridStart;
    ULONG           ridEnd;
    HENUMInternal   *pEnum = *ppmdEnum;
    CustomAttributeRec  *pRec;
    ULONG           index;
    
    LOG((LOGMD, "RegMeta::EnumCustomAttributes(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", 
            phEnum, tk, tkType, rCustomAttributes, cMax, pcCustomAttributes));
    START_MD_PERF();
    LOCKREAD();

    if ( pEnum == 0 )
    {
        // instantiating a new ENUM
        CMiniMdRW       *pMiniMd = &(m_pStgdb->m_MiniMd);
        CLookUpHash     *pHashTable = pMiniMd->m_pLookUpHashs[TBL_CustomAttribute];

        // Does caller want all custom Values?
        if (IsNilToken(tk))
        {
            IfFailGo( HENUMInternal::CreateSimpleEnum(mdtCustomAttribute, 1, pMiniMd->getCountCustomAttributes()+1, &pEnum) );
        }
        else
        {   // Scope by some object.
            if ( pMiniMd->IsSorted( TBL_CustomAttribute ) )
            {
                // Get CustomAttributes for the object.
                IfFailGo(pMiniMd->getCustomAttributeForToken(tk, &ridEnd, &ridStart));

                if (IsNilToken(tkType))
                {
                    // Simple enumerator for object's entire list.
                    IfFailGo( HENUMInternal::CreateSimpleEnum( mdtCustomAttribute, ridStart, ridEnd, &pEnum) );
                }
                else
                {
                    // Dynamic enumerator for subsetted list.
                
                    IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtCustomAttribute, &pEnum) );               
                    
                    for (index = ridStart; index < ridEnd; index ++ )
                    {
                        IfFailGo(pMiniMd->GetCustomAttributeRecord(index, &pRec));
                        if (tkType == pMiniMd->getTypeOfCustomAttribute(pRec))
                        {
                            IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtCustomAttribute) ) );
                        }
                    }
                }
            }
            else
            {

                if (pHashTable)
                {
                    // table is not sorted but hash is built
                    // We want to create dynmaic array to hold the dynamic enumerator.
                    TOKENHASHENTRY *p;
                    ULONG       iHash;
                    int         pos;
                    mdToken     tkParentTmp;
                    mdToken     tkTypeTmp;

                    // Hash the data.
                    iHash = pMiniMd->HashCustomAttribute(tk);

                    IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtCustomAttribute, &pEnum) );               

                    // Go through every entry in the hash chain looking for ours.
                    for (p = pHashTable->FindFirst(iHash, pos);
                         p;
                         p = pHashTable->FindNext(pos))
                    {
            
                        CustomAttributeRec *pCustomAttribute;
                        IfFailGo(pMiniMd->GetCustomAttributeRecord(RidFromToken(p->tok), &pCustomAttribute));
                        tkParentTmp = pMiniMd->getParentOfCustomAttribute(pCustomAttribute);
                        tkTypeTmp = pMiniMd->getTypeOfCustomAttribute(pCustomAttribute);
                        if (tkParentTmp == tk)
                        {
                            if (IsNilToken(tkType) || tkType == tkTypeTmp)
                            {
                                // compare the blob value
                                IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(p->tok, mdtCustomAttribute )) );
                            }
                        }
                    }
                }
                else
                {

                    // table is not sorted and hash is not built so we have to create dynmaic array 
                    // create the dynamic enumerator and loop through CA table linearly
                    //
                    ridStart = 1;
                    ridEnd = pMiniMd->getCountCustomAttributes() + 1;
                
                    IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtCustomAttribute, &pEnum) );               
                
                    for (index = ridStart; index < ridEnd; index ++ )
                    {
                        IfFailGo(pMiniMd->GetCustomAttributeRecord(index, &pRec));
                        if ( tk == pMiniMd->getParentOfCustomAttribute(pRec) &&
                            (tkType == pMiniMd->getTypeOfCustomAttribute(pRec) || IsNilToken(tkType)))
                        {
                            IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtCustomAttribute) ) );
                        }
                    }
                }
            }
        }

        // set the output parameter
        *ppmdEnum = pEnum;          
    }
    
    // fill the output token buffer
    hr = HENUMInternal::EnumWithCount(pEnum, cMax, rCustomAttributes, pcCustomAttributes);

ErrExit:
    HENUMInternal::DestroyEnumIfEmpty(ppmdEnum);
    
    STOP_MD_PERF(EnumCustomAttributes);
    END_ENTRYPOINT_NOTHROW;
    
    return hr;
} // STDMETHODIMP RegMeta::EnumCustomAttributes()