2010-06-13 4 views
1

Я пишу специальный мини-компилятор, и я часто рассматриваю разобранный CIL, чтобы выяснить, как это делать. Но часто неясно, как перевести дизассемблированный код на вызовы Reflection.Emit. Существует ли справочное руководство или какой-либо другой источник информации для этого перевода?В общем, как преобразовать синтаксис ilasm в Reflection.Emit calls?

Редактировать: да, сопоставление опкодов с ILGenerator довольно просто; Я говорю обо всех других вещах, таких как директивы и атрибуты. Например, как вы узнаете, как написать Reflection.Emit эквивалент чего-то вроде Dictionary<TKey,TValue>?

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue> 
    extends System.Object 
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>, 
    System.Collections.Generic.ICollection`1<valuetype 
     System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ... 
{ 
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute:: 
     .ctor(string) = { string('Count = {Count}') } 

    .method public hidebysig newslot virtual final instance bool TryGetValue 
     (!TKey key, [out] !TValue& 'value') cil managed 
    { 
     .maxstack 3 
     .locals init ([0] int32 num) 
     ... 

Или как насчет директивы «param»?

// public static void SayHello(string s = "Hello World!") 
.method public hidebysig static void SayHello([opt] string s) cil managed 
{ 
    .param [1] = "Hello World!" 
+0

Не является ли класс OpCodes сопоставлением один к одному? http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.aspx –

+0

В зависимости от того, что вы делаете, гораздо проще использовать деревья выражений, которые затем можно скомпилировать в CIL : http://msdn.microsoft.com/en-us/library/bb397951.aspx – porges

+0

Деревья выражений касаются главным образом выражений здания, а не создания метаданных классов и методов. Я задал этот вопрос, потому что хочу знать, как его создать. (Я еще не использую .NET 4, но я слышал, что деревья выражений несколько расширились в .NET 4). – Qwertie

ответ

1

Поскольку никто не мог ответить на этот вопрос, я заключаю, никакой документации не существует, чтобы показать взаимосвязь между синтаксисом ILASM и Reflection.Emit вызовы.

В качестве побочного примечания я обнаружил, что обычно лучше создавать код во время выполнения, используя RunSharp, чем Reflection.Emit. Когда у меня будет время, я попытаюсь вычислить новую версию Cecil.

+0

+1, полезно знать о RunSharp. В вашем опыте, насколько он зрелый? Может ли он генерировать полный набор объектов и CIL для .NET (какая версия?) Кажется, что отсутствует постоянная разработка. –

+0

Я не думаю, что он активно развивается, но я смог поговорить с разработчиком. Я не думаю, что эта функция достаточно полна для использования в компиляторе, но она может генерировать типы, конструкторы, поля, методы, события, настраиваемые атрибуты, методы и выражения. Я думаю, что я дал неверную ссылку на сайт; это должно быть http://code.google.com/p/runsharp/ – Qwertie

+0

Приятно знать, спасибо. –

1

Вы смотрите на IL для класса> System.Collections.Generic.Dictionary <. Имя класса «Словарь» - это строка, которую вы передаете ModuleBuilder.DefineType().

Атрибут .param генерируется в C# версии 4 или VB.NET для параметров, имеющих значение по умолчанию. Вы устанавливаете его с помощью ParameterBuilder, который вы возвращаете из MethodBuilder.DefineParameter(). Используйте метод SetConstant().

4

Для этого я использовал бы EmitHelper componentBLToolkit. Он обеспечивает свободный API, похожий на IL-код, обертывающий Reflection.Emit. Пример извлеченный из связанного статьи:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll") 
    .DefineType ("Hello", typeof(object), typeof(IHello)) 
    .DefineMethod(typeof(IHello).GetMethod("SayHello")) 
    .Emitter; 
emit 
    // string.Format("Hello, {0}!", toWhom) 
    // 
    .ldstr ("Hello, {0}!") 
    .ldarg_1 
    .call (typeof(string), "Format", typeof(string), typeof(object)) 

    // Console.WriteLine("Hello, World!"); 
    // 
    .call (typeof(Console), "WriteLine", typeof(string)) 
    .ret(); 

Type type = emit.Method.Type.Create(); 

 Смежные вопросы

  • Нет связанных вопросов^_^