Current dynamic method implementation does not have built-in support to pre-check whether the dynamic method code is verifiable. With bad IL sequence, very often you will get "System.InvalidProgramException: Common Language Runtime detected an invalid program" when it gets executed. See the code example below, where C1, C2 are 2 simple reference types. Btw I understand only me write such "fun" IL code.
ilgen.EmitWriteLine("I got called");
Even if you did not get InvalidProgramException, it does not mean the code-gen is correct. When the following code get invoked, "I got called too" will be printed; but the code is not verifiable. When the SkipVerification permission is refused, executing this dynamic method causes JIT to verify first: "System.Security.VerficationException: Operation could destabilize the runtime" throws.
ilgen.EmitWriteLine("I got called too");
However both exception messages contain no much useful information: they do not tell which instruction could be blamed. For any production code using DynamicMethod, to ensure the code-gen quality, it is a good practice to have another implementation which have Reflection.Emit to emit the same IL code to disk, and call Peverify.exe to verify it. IronPython's code-gen has both approaches: at the beginning when we enforced this check, we caught several code-gen issues. This is what peverify.exe shows for the 2 scenarios above:
[IL]: Error: [D:\snippets.dll : Sample::M][offset 0x00000011] Stack must be empty on return from a void function.
[IL]: Error: [D:\snippets.dll : Sample::M][offset 0x00000005][found ref 'C1'][expected ref 'C2'] Unexpected type on the stack.