Esempio n. 1
0
FCIMPLEND

//**************************************************
// LoadInMemoryTypeByName
// Explicitly loading an in memory type
// <TODO>@todo: this function is not dealing with nested type correctly yet.
// We will need to parse the full name by finding "+" for enclosing type, etc.</TODO>
//**************************************************
void QCALLTYPE COMModule::LoadInMemoryTypeByName(QCall::ModuleHandle pModule, LPCWSTR wszFullName)
{
    QCALL_CONTRACT;
    
    TypeHandle      typeHnd;

    BEGIN_QCALL;

    if (!pModule->IsReflection())  
        COMPlusThrow(kNotSupportedException, W("NotSupported_NonReflectedType"));   

    RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
    _ASSERTE(pRCW);

    // it is ok to use public import API because this is a dynamic module anyway. We are also receiving Unicode full name as
    // parameter.
    IMetaDataImport * pImport = pRCW->GetRWImporter();

    if (wszFullName == NULL)
        IfFailThrow( E_FAIL );

    // look up the handle
    mdTypeDef  td;
    HRESULT hr = pImport->FindTypeDefByName(wszFullName, mdTokenNil, &td);
    if (FAILED(hr))
    {
        if (hr != CLDB_E_RECORD_NOTFOUND)
            COMPlusThrowHR(hr);

        // Get the UTF8 version of strFullName
        MAKE_UTF8PTR_FROMWIDE(szFullName, wszFullName);
        pModule->GetAssembly()->ThrowTypeLoadException(szFullName, IDS_CLASSLOAD_GENERAL);
    }

    TypeKey typeKey(pModule, td);
    typeHnd = pModule->GetClassLoader()->LoadTypeHandleForTypeKey(&typeKey, TypeHandle());

    END_QCALL;

    return;
}
Esempio n. 2
0
//**************************************************
// GetTypeRef
// This function will return the type token given full qual name. If the type
// is defined locally, we will return the TypeDef token. Or we will return a TypeRef token 
// with proper resolution scope calculated.
// wszFullName is escaped (TYPE_NAME_RESERVED_CHAR). It should not be byref or contain enclosing type name, 
// assembly name, and generic argument list.
//**************************************************
mdTypeRef QCALLTYPE COMModule::GetTypeRef(QCall::ModuleHandle pModule,
                                          LPCWSTR wszFullName,
                                          QCall::ModuleHandle pRefedModule,
                                          LPCWSTR wszRefedModuleFileName,
                                          INT32 tkResolutionArg)
{
    QCALL_CONTRACT;

    mdTypeRef tr = 0;

    BEGIN_QCALL;
        
    RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
    _ASSERTE(pRCW); 
    
    IMetaDataEmit * pEmit = pRCW->GetEmitter(); 
    IMetaDataImport * pImport = pRCW->GetRWImporter();

    if (wszFullName == NULL) {
        COMPlusThrow(kArgumentNullException, W("ArgumentNull_String"));
    }    

    InlineSString<128> ssNameUnescaped;
    LPCWSTR wszTemp = wszFullName;

    WCHAR c;
    while(0 != (c = *wszTemp++))
    {
        if ( c == W('\\') && 
             IsTypeNameReservedChar(*wszTemp) )
        {
            ssNameUnescaped.Append(*wszTemp++);
        }
        else
        {
            _ASSERTE( ! IsTypeNameReservedChar(c) );
            ssNameUnescaped.Append(c);
        }
    }

    LPCWSTR wszFullNameUnescaped = ssNameUnescaped.GetUnicode();

    Assembly * pThisAssembly = pModule->GetClassLoader()->GetAssembly();
    Assembly * pRefedAssembly = pRefedModule->GetClassLoader()->GetAssembly();

    if (pModule == pRefedModule)
    {
        // referenced type is from the same module so we must be able to find a TypeDef.
        IfFailThrow(pImport->FindTypeDefByName(
            wszFullNameUnescaped,
            RidFromToken(tkResolutionArg) ? tkResolutionArg : mdTypeDefNil,
            &tr)); 
    }
    else
    {
        mdToken tkResolution = mdTokenNil;
        if (RidFromToken(tkResolutionArg))
        {
            // reference to nested type
            tkResolution = tkResolutionArg;
        }
        else
        {
            // reference to top level type
            if ( pThisAssembly != pRefedAssembly )
            {
                SafeComHolderPreemp<IMetaDataAssemblyEmit> pAssemblyEmit;  

                // Generate AssemblyRef
                IfFailThrow( pEmit->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
                tkResolution = pThisAssembly->AddAssemblyRef(pRefedAssembly, pAssemblyEmit);

                // Add the assembly ref token and the manifest module it is referring to this module's rid map.
                // This is needed regardless of whether the dynamic assembly has run access. Even in Save-only
                // or Refleciton-only mode, CreateType() of the referencing type may still need the referenced 
                // type to be resolved and loaded, e.g. if the referencing type is a subclass of the referenced type.
                //
                // Don't cache if there is assembly associated with the token already. The assembly ref resolution
                // can be ambiguous because of reflection emit does not require unique assembly names.
                // We always let the first association win. Ideally, we would disallow this situation by throwing 
                // exception, but that would be a breaking change.
                if(pModule->LookupAssemblyRef(tkResolution) == NULL)
                {
                    pModule->ForceStoreAssemblyRef(tkResolution, pRefedAssembly);
                }
            }
            else
            {
                _ASSERTE(pModule != pRefedModule);                
                _ASSERTE(wszRefedModuleFileName != NULL);

                // Generate ModuleRef
                IfFailThrow(pEmit->DefineModuleRef(wszRefedModuleFileName, &tkResolution));
            }
        }

        IfFailThrow( pEmit->DefineTypeRefByName(tkResolution, wszFullNameUnescaped, &tr) );  
    }

    END_QCALL;

    return tr;
}