kekyo / IL2C

IL2C - A translator for ECMA-335 CIL/MSIL to C language.
Apache License 2.0
401 stars 36 forks source link

Better way how implement in IL2C/Invoke method. #120

Open kekyo opened 2 years ago

kekyo commented 2 years ago

In commit d23f681b2a789228c7bedde4232edb2aad92d249 I have modified the IL2C/Invoke test code.

Originally, the test case was configured to run only when it was native code, but as a result of the standardization of the unit testing method, it tries to run this code under CoreCLR as well. From CoreCLR's point of view, the InternalCall implementation is left out, so the error ECall undefined is raised.

I got around this by defining a property called IL2CServices.IsInNativeExecution, but had to place the method call in one call farther away to cheat the JIT.

In real-world code, such a situation is quite possible, but it is somewhat tedious to write such code every time. Also, due to a limitation of the C# compiler, if we use an extern reserved word, we have to mark it as InternalCall, which also seems to be an unintelligible promise (to a beginner).

So, I started to wonder if it might be a good idea to prepare an empty implementation, which was considered in the very first IL2C/Invoke but rejected because of its poor symmetry with DllImport. I started to think about it. In other words, in this case :

[NativeMethod("time.h")]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern long mktime(in tm tmValue);

This code is simply:

[NativeMethod("time.h")]
private static long mktime(in tm tmValue) => 0L;

This means that it is also considered to be good. In this case, the MethodBody is simply ignored during IL2C conversion, with the same result as using extern.

Moreover, the nice thing about this method is that you can prepare the default behavior when working with CoreCLR.