Closed sakno closed 2 years ago
Hi Roman!
This is an interesting idea, but as you've pointed out, it would require quite a bit of work to implement. I feel that handling the arguments correctly wouldn't be easy (it would be nice to be able to call a macro multiple times with different parameters in a given method). Also, if the macro has locals, these would need to be handled in some way.
Therefore I'm not sure if this really belongs to the scope of this project, but I'll think about it a bit more.
In the meantime, I can suggest you to use a T4 template to keep code duplication under control. It helped me in many projects (see here for a good example, the template is here). It may not be as convenient as IL macros, but it should help solve the code duplication issue quite well. Roslyn generators are also an option, but I think T4 is more suitable for this usage.
Here's what I'm thinking: this kind of feature seems out of scope for this project, but it could be implemented as a separate weaver.
Suppose there's a weaver which inlines the IL code of methods marked with a [ForceInline]
attribute, and does the necessary mapping. If you execute this weaver before InlineIL is run, then calls like Constructor(Type<TDelegate>(), ...)
would be mapped to Constructor(Type<Action>(), ...)
for instance, and that would work fine.
There would be a few issues, but I think they can be worked around:
IL.Emit.Ldarg(2)
, they would refer to arguments of the target method, not of the inlined method. It would be better to use IL.Push
because of this, as the argument would be able to be mapped properly by the weaver.IL.DeclareLocals
into another one which also calls IL.DeclareLocals
. I don't think that's a big issue.IL.Return
could be a problem as it would require the target method to return
the result of the inlined method immediately (just like your example does), but this can be worked around if necessary with stuff like IL.Pop
.throw IL.Unreachable();
would also be inlined as-is which would be unwanted in some cases.I may experiment with the idea, but I don't have a lot of time so I can't promise anything.
I found this weaver which seems to implement what I described above (it also copy/pasted some of my code without attribution, but oh well 🙄). Maybe running it before InlineIL could be helpful.
In any case, I'd rather keep InlineIL itself pretty low-level, which makes this feature out of scope.
Hi Lucas!
Now I'm working on the set of factory methods that allow to create delegates from function pointers:
As you can see, I have to use code duplication. I would like to propose the support of macros by your library. The macro is a method with the following restrictions:
ILMacroAttribute
which is declared in your libraryS.R.CS.AsyncStateMachineAttribute
attribute)S.R.CS.IteratorStateMachineAttribute
attribute)With the macro functionality, I'll be able to rewrite the methods shown above as follows:
I understand that the feature requires a lot of efforts.