标签: il

为.Net平台生成IL

我正在用C#编写一个小编译器,并计划使用.Net平台生成IL指令System.Reflection.Emit.我的问题是,建议System.Reflection.Emit用于为生产编译器生成IL.

如果不建议System.Reflection.Emit用于为生产编译器生成IL,我们是否有用于此目的的替代库/工具?

c# compiler-construction il

5
推荐指数
1
解决办法
2167
查看次数

为匿名方法生成IL

我想为多线程应用程序生成IL.作为第一步,我编写了一个简单的应用程序并进行了检查,使用ILSpy生成了IL.

public class ThreadTesting
{
    public static void Main()
    {
        Thread thread = new Thread(() => Print("Hello from t!"));
        thread.Start();
    }

    public static void Print(string message)
    {
        Console.WriteLine(message);
    }
}
Run Code Online (Sandbox Code Playgroud)
.method public hidebysig static 
    void Main () cil managed 
{
    // Method begins at RVA 0x2060
    // Code size 46 (0x2e)
    .maxstack 3
    .entrypoint
    .locals init (
        [0] class [mscorlib]System.Threading.Thread
    )

    IL_0000: nop
    IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0006: brtrue.s IL_001b

    IL_0008: ldnull
    IL_0009: ldftn void ThreadTesting::'<Main>b__0'()
    IL_000f: newobj instance …
Run Code Online (Sandbox Code Playgroud)

.net clr il

5
推荐指数
1
解决办法
688
查看次数

如何在 Mono.Cecil 中为 MethodReference 创建 GenericParameter 返回类型?

我正在尝试使用 Mono.Cecil 重现以下 IL:

call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [System]System.ComponentModel.PropertyChangedEventHandler>(!!0&, !!0, !!0)
Run Code Online (Sandbox Code Playgroud)

当我使用 Mono.Cecil 检查这个 IL 时,我看到指令的操作数是一个 GenericInstanceMethod,它包含一个 MethodReference 类型的 ElementMethod。此 MethodReference 又具有 GenericParameter 类型的返回类型。

我想手动创建相同的对象,但似乎达到了 catch-22。要创建 GenericParameter,我需要一个 IGenericParameterOwner,它似乎与上面的 MethodReference 完全相同。所以我想将 MethodReference 传递给 GenericParameter 构造函数。但是,如果没有返回类型的 TypeReference,我也无法创建 MethodReference,我认为它应该是 GenericParameter。

我该如何解决?我误解了什么?

.net il mono.cecil

5
推荐指数
1
解决办法
839
查看次数

C#托管代码中的"AccessViolationException未处理"错误

我有新问题.我的代码:

.method public static void  Main() cil managed
{
  .entrypoint
  // Code size       3 (0x3)
  .maxstack  1
  IL_0000:  ldnull
  IL_0001:  stloc.0
  IL_0002:  ret
} // end of method Program::Main
Run Code Online (Sandbox Code Playgroud)

C#代码:

il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ret);
Run Code Online (Sandbox Code Playgroud)

我通过System.Reflection和System.Reflection.Emit类生成此代码.有谁知道为什么这不起作用?请帮忙.

我的错误

一个小问题 - 我应该生成构造函数吗?

c# il exception reflection.emit .net-assembly

5
推荐指数
1
解决办法
1014
查看次数

通过元数据令牌访问 PropertyInfo 以从 IL 使用?

我有一个应用程序,其中有一个采用 PropertyInfo 参数的方法,并且希望从 IL 调用此方法。例如,对于采用 MethodInfo 的类似方法,我可以创建一个采用RuntimeMethodHandle 的中间方法并使用GetMethodFromHandle。然后 IL 可以使用Ldtoken来传递句柄。

但是,似乎没有等效的属性元数据标记。我可以理解为什么会出现这种情况(因为属性实际上只是将方法捆绑在一起的一种方式,并且永远不会从 IL 中“调用”),但肯定存在与该类型关联的属性元数据。我可以在发出时访问此属性元数据,因此我想要一种能够直接传递此属性的方法,而不必在运行时通过名称诉诸反射(即,向 GetProperty 发出反射调用,并采用将在以下位置执行的字符串)运行时。)有办法做到这一点吗?


根据评论中的请求,这是应用程序:

我正在创建一个适配器类,它通过属性公开属性引用作为其组件位bool this[int index]。我的应用程序将 PLC 代码编译为 .NET 程序集,因此我尝试创建诊断访问器,该访问器近似于 PLC 提供的简单按位访问(您在其中写入MyTag.2以指示 tag 的位 2 MyTag)。此语法不能用于C# 的消耗,但这PLC.GetBits().MyTag[2]是一个合理的近似值。

我最初的方法是使用 PropertyInfo 实现的(这就是我遇到此问题的方式),但我当然可以通过将 PropertyInfo 中的适用元数据作为多个参数传递来解决此问题。我主要只是好奇是否可以直接传递 PropertyInfo,因为我以前从未遇到过这种情况。

.net c# reflection il reflection.emit

5
推荐指数
1
解决办法
956
查看次数

是否有通用的CIL代码将任何类型的实例转换为字符串?

是否可以编写通用CIL指令,将任何类型的实例(值和引用)转换为System.String?特别是,我对Mono.Cecil代码很感兴趣,它会将这些指令注入到方法中.

分析一个通用方法我想出了这些Mono.Cecil调用:(它应该将第i个方法参数转换为字符串)

System.Reflection.MethodInfo to_string_method_info = typeof( System.Object ).GetMethod( "ToString" );
Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import( to_string_method_info );

Mono.Cecil.TypeReference argument_type = method_definition.Parameters[ i ].ParameterType;
method_definition.Body.Instructions.Add( processor.Create( Mono.Cecil.Cil.OpCodes.Constrained, argument_type ) );
method_definition.Body.Instructions.Add( processor.Create( Mono.Cecil.Cil.OpCodes.Callvirt, to_string_reference ) );
Run Code Online (Sandbox Code Playgroud)

但是,在调试时,我从注入的方法中获得"JIT编译器遇到内部限制"的异常.

.net il cil mono.cecil

5
推荐指数
1
解决办法
598
查看次数

数组在CLR中有直接支持

在Jon Skeet的"C#in depth"中,我正在阅读(第511页):

所有数组都派生自System.Array,它们是CLR中唯一直接支持的集合(我的重点).

我想知道这意味着什么,特别是与没有这种支持的类型有关.在解释IL时,所有没有此类支持的类型是否都是由CLR所做的类型组合而成的?CLR没有"知道"没有这种支持的类型吗?

也在p.本书512:

C#编译器以多种方式内置了对数组的支持.

这在某种程度上与Array类型在CLR中的直接支持有关,还是这两个单独的东西?

.net c# arrays clr il

5
推荐指数
1
解决办法
243
查看次数

为什么 Mono.Cecil 主张方法导入,而我已经这样做了?

这是我的代码:

    private void ModifyMethods()
    {
        SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(@"
using System;

namespace ToIL
{
    public class Class1
    {
        public void Write()
        {
            Console.WriteLine(""Hello"");
        }
    }
}");


        string assemblyName = System.IO.Path.GetRandomFileName();
        MetadataReference[] references = new MetadataReference[]
        {
            MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
            MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location)
        };

        CSharpCompilation compilation = CSharpCompilation.Create( assemblyName, syntaxTrees: new[] { syntaxTree }, references: references,
            options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));


        Mono.Cecil.AssemblyDefinition asm = null;
        using (var ms = new MemoryStream())
        {
            var emitResult = compilation.Emit(ms);
            if (emitResult.Success)
            {
                ms.Seek(0, SeekOrigin.Begin);
                asm = Mono.Cecil.AssemblyDefinition.ReadAssembly(ms); 
            }
        }


        var …
Run Code Online (Sandbox Code Playgroud)

c# il cil mono.cecil roslyn

5
推荐指数
1
解决办法
1377
查看次数

在JIT/AOT编译期间,CIL ldstr是否被替换为对string.Intern的常量引用?

假设我有一个需要优化但同时易于调试的代码.因此,我会为我使用的每个值分配一个字符串.该字符串是否会造成重大性能损失,或者它是否变成了一个从string.Intern在JIT/ AOTcompilation中获得的常量引用,从而变成一条简单的指令?

例:

在IL中它会是ldstr "gazilion lines".

它是在JIT/AOT编译期间变成类似的东西ldsflda string.InternCache.ID_0000647516166 并被const string ID_0000647516166 = "gazilion lines"; 添加到string.InternCache

是的,我理论上可以查看https://github.com/mono/mono但我不知道如何找到它.

是的,我正在混合使用CIL,C#以及编译的CIL,但是你明白了.

ldstr保证是O(1)

是的,它是CLR的"实现细节",但如果以这种方式进行优化,那将是有意义的.

c# string il cil

5
推荐指数
1
解决办法
208
查看次数

简短说明有更好的表现吗?

我真的需要关心可以发出.s指令的地方吗?或者它只会影响尺寸,但真正的性能会是一样的吗?

生成的dll也将在AOT平台上使用.有.s和没有IL的结果AOT-ed dll是否相同?

我的意思是br.s,ldloca.s等.

c# il opcode aot

5
推荐指数
1
解决办法
185
查看次数