NET ILGenerator? Does it yield a significant size increase in generated code output? InfoQ: What is the performance cost of using Sigil compared to. Which reuses the first slot on the stack (as show by stloc.0 there). When a Local is requested via Emit.DeclareLocal(), Sigil will reuse any previously disposed Locals' slot if the types match.įor example var e = Emit.NewDynamicMethod("foo") In Sigil, locals (variables on the stack) are represented by a Local class which implements IDisposable. There are cases, usually around branches, where Sigil can't determine if an IL stream is valid at exactly the erroneous line - but Sigil still fails as soon as it can (always before the JIT is involved), and with more context than ILGenerator provides.īasically Sigil makes it harder to make common mistakes at compile time, and gives better feedback at runtime when mistakes are made anyway. Sigil also automates opcode selection, using the shortest form possible. We'd get another SigilVerificationException at runtime - this time on line #4 "Add expected a by ref, double, float, int, long, native int, or pointer found System.RuntimeTypeHandle". If instead we "corrected" the example to 1: var e = Emit.NewDynamicMethod("foo") "Correcting" that to 1: var e = Emit.NewDynamicMethod("foo") ĭoes compile, but throws a SigilVerificationException at runtime on line #3 "Add expects 2 values on the stack". This fails to compile, as Add() takes no parameters. The previous example would be rendered as: 1: var e = Emit.NewDynamicMethod("foo") ![]() KM: Sigil provides a less error prone interface, and (by default) validates the IL stream as it is emitted. InfoQ: How does Sigil make IL Generation easier? The raised exception will also lack detail, rarely saying more than "Common Language Runtime detected an invalid program." or "Operation could destabilize the runtime.".Īnother, less significant, difficulty is generating ideal IL such as using shorter forms when possible (Br_S instead of Br, Ldc_I4_0 instead of Ldc_I4 & 0, etc.), and reusing locals (rather than use additional slots on the stack). This typically means the first time a delegate or method is invoked (line #8 in the above example), which can be very far removed from the actual mistake. The second issue with ILGenerator is that it does no validation of the correctness of the emitted IL, correctness is only checked when the JIT gets it. Most opcodes in ILGenerator are emitted with a call to one of Emit's overloads, the problem is that Emit(.) does no checking that the instruction is actual sensible.įor example 1: var dyn = new DynamicMethod("foo", typeof(void), new Type) ħ: var del = (Action)dyn.CreateDelegate(typeof(Action)) ĭoesn't fail to compile, even though line #4 is nonsensical (the Add opcode takes no immediate values). KM: When using ILGenerator, there are two big stumbling blocks. InfoQ: What are the challenges of emitting IL at runtime? * Generic types, in the absence of constraints, could be either structs or reference types which has to be reflected in the emitted IL and handled in validation. Unbound generic types complicate validation and generation*, and since in the typical case all types are known when using Sigil there's been little demand for to support them. Fault blocks aren't really a thing in C#, and aren't legal in DynamicMethod anyway. There are a few use cases Sigil doesn't support (which are possible with ILGenerator): fault blocks and emitting code that uses generic (ie. ![]() ![]() for which reflection is often used can benefit from Sigil/ILGenerator. Kevin Montrose: Typically IL is generated as a faster alternative to reflection, so tasks like (de)serialization, type mapping, mocking, etc. ![]() InfoQ: What are the most suited scenarios for generating IL? Is it possible to replace any piece of code using reflection with ILGenerator/Sigil? InfoQ reached out with Sigil's creator Kevin Montrose, team lead at StackOverflow, to get a better understanding of ILGenerator and Sigil. It wraps ILGenerator in a finer-grained interface, automates some optimizations and provides validations for the generated IL. Sigil is a library for generating Common Intermediate Language (CIL).
0 Comments
Leave a Reply. |