Replies: 44 comments 5 replies
-
If I recall it was considered quite an effort to try to add IL to the C# specification, including all of the glue syntax that would be required for IL to support C# constructs and vice versa. The team instead is looking to expose "compiler intrinsics", or special methods that would be converted by the compiler into IL operations, in order to represent special IL operations that cannot be generated easily by normal C# code. dotnet/roslyn#11475 |
Beta Was this translation helpful? Give feedback.
-
I couldn't find a previous request for embedded IL on the Roslyn repo or CodePlex. Could be that my Search-Fu is failing me. Anyway, the issue on compiler intrinsics addresses the concept but it's good to have this issue as a place to discuss the concept. |
Beta Was this translation helpful? Give feedback.
-
Edit: Oh hey #226 |
Beta Was this translation helpful? Give feedback.
-
Figures, I was only looking on Roslyn. Anyway, #428 is more like this issue whereas #226 is much more open ended. |
Beta Was this translation helpful? Give feedback.
-
Fwiw I searched dotnet/roslyn |
Beta Was this translation helpful? Give feedback.
-
In MSDN, they have example of using Dynamic binding before DLR and after /*before*/ Scriptobj.SetProperty("Count", ((int)GetProperty("Count")) + 1);
/*after*/ scriptobj.Count += 1; so if it's going to be so much effort to add inline assembler why just not treat it as a dynamic language - which it is from JIT point-of-view - and embed it in the output and let JIT do the checking. and let me say that it is allowed for us to add dynamic IL using |
Beta Was this translation helpful? Give feedback.
-
@muh00mad
The compiler would still be required to take the text of the IL instructions and compile them into the corresponding IL byte code. That has to happen at compile time. The CLR/JIT has no concept what And then there is the issue of integration. What does |
Beta Was this translation helpful? Give feedback.
-
Why? When would you want to use this (assuming the dotnet/roslyn#11475 IL intrinsics existed)? |
Beta Was this translation helpful? Give feedback.
-
This feature suggestion makes me IL. 😆 |
Beta Was this translation helpful? Give feedback.
-
AFAIK the work already been done here and all it needs is a some - minor - effort to add into the compiler source.
Some project I'm working on require fast alternative to struct SampleType
{
public int Number { get; set; }
}
class Program
{
public static void Main()
{
var type = default(SampleType);
object o = type;
SetValue(o, nameof(SampleType.Number), 10)
}
public static void SetValue(object instance, string name, object value)
{
if (name == "Number")
{
// invalid in c#
//((SampleType)instance).Number = (int)value;
// valid in c#, the modified object is not the target object but the local one
//SampleType sampleType = (SampleType)instance;
//sampleType.Number = (int)value;
il
{
ldarg.1
unbox SampleType
ldarg.3
unbox.any [mscorlib]System.Int32
call instance void SampleType::set_Number(int32)
}
return;
}
throw new Exception("name not found");
}
} The compiler intrinsics is not confirmed yet and if it is going to be added it will be some functions so the IL code above will be something like using Microsoft.CSharp.Intrinsics;
CompilerIntrinsics.LdArg(1); // CompilerIntrinsics.LdArg(int index)
CompilerIntrinsics.Unbox(typeof(SampleType)); // CompilerIntrinsics.Unbox(type)
CompilerIntrinsics.LdArg(3); // CompilerIntrinsics.LdArg(int index)
CompilerIntrinsics.UnboxAny(typeof(SampleType)); // CompilerIntrinsics.UnboxAny(type)
CompilerIntrinsics.Call(typeof(SampleType).GetProperty(nameof(Range.Number).GetSetMethod); // CompilerIntrinsics.Call(MethodInfo metthod) which is more effective from end-user point-of-view? |
Beta Was this translation helpful? Give feedback.
-
I think you both want ldarg.0 and ldarg.2 |
Beta Was this translation helpful? Give feedback.
-
I'd still like to see either multi-language projects or language extensibility. Compiler intrinsics will also be welcome, but it solves a different set of problems. |
Beta Was this translation helpful? Give feedback.
-
@muh00mad
That project was already referenced, and no, it would not take minor work. It would take massive complicated work in order to integrate with the compiler, IDE, debugger, E&C, refactoring, etc. It's not sufficient to hack it in there.
For something that should be exceptionally rarely used? Probably the one which has any likelihood of getting implemented and would actually get the job done. |
Beta Was this translation helpful? Give feedback.
-
@muh00mad
No, it won't. There is nothing in the proposal about supporting "common" IL instructions like |
Beta Was this translation helpful? Give feedback.
-
@muh00mad I think that use case is an argument to add an With that, your code could look like this: public static void SetValue(object instance, string name, object value)
{
if (name == "Number")
{
ref SampleType sampleType = ref Unbox<SampleType>(instance);
sampleType.Number = (int)value;
return;
}
throw new Exception("name not found");
} The implementation of
|
Beta Was this translation helpful? Give feedback.
-
This feature is not championed, so there is no place for it in the schedule currently. See https://github.com/dotnet/csharplang/blob/master/README.md#design-process. |
Beta Was this translation helpful? Give feedback.
-
@06needhamt Even though the feature isn't championed, if you would like to have a go at implementing the feature. Go ahead and prototype it. |
Beta Was this translation helpful? Give feedback.
-
I want to be clear though: a PR to roslyn with an implementation for a unchampioned, undiscussed feature will be closed. Unless and until the feature is championed by a member of the LDT, the feature is not open for inclusion in the language. |
Beta Was this translation helpful? Give feedback.
-
You are, of course, always welcome to do wahtever you want in your own forks. But Fred is correct, the explicit team stance on this sort of thing is that a PR for that would be rejected for not following proper procedure. |
Beta Was this translation helpful? Give feedback.
-
@06needhamt : As long as there is missing support in C# and some things can only be accomplished by using IL I agree that there needs to be some mechanism. The question is, if you need it integrated in C# or if it's better to have some official and well supported ilproj? |
Beta Was this translation helpful? Give feedback.
-
There is an ilproj SDK that is used by dotnet/runtime. It allows you to easily compile IL into assemblies, but doesn't provide intellisense or VS project system support.
The few things that are missing (like function pointers) have championed proposals (generally speaking) and are being worked on. Other cases can be handled by things like dynamic methods. Dynamic methods or methods explicitly written in pure IL tends to work better as well since the compiler doesn't have to optimize around you inserting arbitrary IL. The same goes for inline asm in C/C++ and is one of the reasons intrinsics are preferred. |
Beta Was this translation helpful? Give feedback.
-
@tannergooding: I agree with the things that are solved with the championed proposals. I also agree to use intrinsics. The embedded asm {} in C++ was in my opinion only for microoptimizations. But what about math on generics? I can currently only do it in IL. I'm not aware that something has been championed by this. I needed to write my own assembly that holds basic math on generics, but only for these 6 methods I had to write my own assembly that I could have embedded into my own core assembly if there was a possibility to do so. There are of course arguments around here that an assembly does not matter, but we have around 200 assemblies and in the end it does matter. If there would be a possibility to add an *.il file to my project that is compiled and added that would be just fine for me. I don't need to embed code directly, only if there's performance drawback in a method call vs. embedded code. |
Beta Was this translation helpful? Give feedback.
-
Provided it is over a value type, the JIT supports generic specialization which ensures the codegen is optimal. You can see in each case where a
But it works and generates highly optimized code. |
Beta Was this translation helpful? Give feedback.
-
@tannergooding: Yes, I know this approach and it is far from being optimal. To be honest - and I don't want to sound rude - the fact that it can be done does not mean that it's good. Our code is highly cluttered with the methods described and is also far from being maintainable, since every code path needs to be implemented explicitly. This means that every change means changing all pathes. When you are doing a lot of number crunching this can be annoying like hell ;-) One can see the result of having no math on generics: Math -> MathF. Even though there might be differences in the internal behaviors, but I think Math.Abs and MathF.Abs is a good example where it would help to have support on generics. One can see that you only do this once and never touch it again, but it is the time to develop these pieces of code and to maintain them. And as said before in math and physical environments where you need to develop algorithms this could help a lot. |
Beta Was this translation helpful? Give feedback.
-
Powerful JIT can help optimize away certain "pathological" casts, but it doesn't mean the casts are no longer pathological themselves. I wholeheartedly support this idea, even though specifying it would essentially require to add another language into the specification. In the past, others have also objected that adding arbitrary CIL could make the code horribly wrong or simply invalid, but now with tools like The remaining question is how much of the syntax should be accepted. I think the most powerful option is the best one - |
Beta Was this translation helpful? Give feedback.
-
Sounds like a massive amount of effort to slightly better support the vast minority of library writers. They already have solutions, slightly less than ideal solutions, but given how often this code needs to be written it doesn't sound like it justifies adding IL (and a hybrid form of IL which would allow interop between IL and C# source). For every one of those use cases there sounds like there are numerous alternative approaches each of which involve many, many magnitudes less effort. |
Beta Was this translation helpful? Give feedback.
-
This had nothing to do with math/generics but was an overload resolution problem. You'd likewise have potential problems even if they were generic from day 1, as not all types may be supported and so you wouldn't get a compile time error for things like
Yes, it is effectively a write once situation. There are only a limited number of types (the runtime primitives) where you can use IL instructions to perform arithmetic or other logical operations. These can be trivially supported via a small generic helper class and then never need to be touched again. Any other type ends up being a call to a user-defined operator (including types like |
Beta Was this translation helpful? Give feedback.
-
@tannergooding: I'm curious about the syntax. Let's assume I want to generalize Add and I have primitive times and types with an overloaded + operator. Do I need two different kinds of Add methods:
and another (I don't know the final syntax)
and the CLR emits different pathes or is it then subsumed under one Add method? |
Beta Was this translation helpful? Give feedback.
-
That would depend entirely on how the shapes proposal was implemented, among other factors. |
Beta Was this translation helpful? Give feedback.
-
I think this should be more like class Program
{
static unsafe void Main(string[] args)
{
__ilasm
{
ldstr "Hello World"
call System.Console::WriteLine(string)
}
}
} class Program
{
static unsafe void Main(string[] args)
{
string HelloString = "Hello World";
__ilasm
{
ldstr &HelloString
call System.Console::WriteLine(string)
}
}
} |
Beta Was this translation helpful? Give feedback.
-
This is a proposal to add new keyword to allow writing inline IL code directly inside C# code for example
Beta Was this translation helpful? Give feedback.
All reactions