Обновить атрибуты метода во время JIT?

Я ищу метод для обновления атрибутов существующего метода без создания нового определения метода.

Вот код, который у меня есть:

HRESULT STDMETHODCALLTYPE Weaver::JITCompilationStarted(
FunctionID functionId, BOOL fIsSafeToBlock)
{
HRESULT status = S_OK;
MethodInfo methodInfo = GetMethodInfo(functionId);
if (!IsMdVirtual(methodInfo.Attributes) && !IsMdStatic(methodInfo.Attributes)
&& !IsMdPrivate(methodInfo.Attributes) && !IsMdSpecialName(methodInfo.Attributes))
{
CComPtr<IMetaDataEmit> metaDataEmit;
status = m_profilerInfo3->GetModuleMetaData(methodInfo.Module,
ofRead | ofWrite, IID_IMetaDataEmit, (IUnknown**)&metaDataEmit);

// TODO: get module metadata and update method attributes to:  methodInfo.Attributes | mdVirtual
status = metaDataEmit->ApplyEditAndContinue(metaDataEmit /*?*/);
}

return status;
}

Как видите, мне не хватает методов для извлечения метаданных функции и их изменения в строке. Справка MSDN по этому методу очень тонкая и не может найти никаких примеров использования ApplyEditAndContinue,

-2

Решение

Принимая ответ Брайана в комментариях:

JITCompilationStarted слишком поздно для изменения атрибутов, атрибуты могут быть проверены задолго до того, как метод будет вызван или вызван JIT. Метаданные могут быть изменены только из обратного вызова ModuleLoadFinished.

Что переводится в код по типу (сильно сокращено):

HRESULT Weaver::ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus)
{
HRESULT status = S_OK;
// Filter module

// Enum & filter types in module
// Enum & filter methods in type
DWORD attributes, implFlags; ULONG codeRva;
status = pMetaImport->GetMethodProps(tkMethod, NULL, NULL, NULL, NULL, &attributes, NULL, NULL, &codeRva, &implFlags);
status = pMetaEmit->SetMethodProps(tkMethod, attributes | mdVirtual, codeRva, implFlags);

return status;
}

Это позволит высмеивать не виртуальных членов в .NET, например:

public class Foo {
public string Hello() => "test";
}

// ...
var fake = A.Fake<Foo>();
A.CallTo(() => fake.Hello()).Returns("faked");
Assert.Equals("faked", fake.Hello());
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]