FastExpressionCompiler
FastExpressionCompiler copied to clipboard
Is it possible to implement ref local variables?
I know its not supported by the Microsoft expression tree api, but I wonder if this is possible to generate directly in IL. I am building game systems with a language based on expression trees and desperately need to avoid allocating things every frame. `ref`` locals have helped a lot with that, I'd like to integrate these into the language I'm writing but obviously it's not currently possible with standard expression trees. Since I'm using your library anyway, I wondered if an option to opt-in to using ref locals would be possible.
What do you mean here by ref locals.
Could provide an example/pseudocode?
Regarding memory usage, are you using LightExpressions?
Sure, here is the C# I'd like to emulate
Vector3[] array = new Vector3[100]; // struct btw
for(int i = 0; i < array.Length; i++) {
ref Vector3 v = ref array[i];
// do stuff with v and have the array[i] value updated (because its a reference)
v.x += 12;
v.Normalize();
}
I'm not currently, I'm not that worried about memory usage at expression compile time (which happens once on startup), but I care a lot about this stuff while the game is running
Sure, here is the C# I'd like to emulate
Thanks.. So you want to be able to turn this code into expression and compile it?
yes exactly, right now the ref keyword cannot be used with ParameterExpression and I think thats just because the expression tree API got frozen before c# 7 when ref locals were introduced to the language. I would imagine this is possible to implement in IL, just nobody has done it yet. We can't change the Microsoft compiler to support this, but since you generate IL yourself I figured it might be a. possible and b. pretty useful for a lot of people using your library
Yes it should be possible, just get the address instead. But do you need to put all that code into expression or for instance only the body of the loop and convert the ref var to ref parameter?
Vector3[] array = new Vector3[100]; // struct btw
for(int i = 0; i < array.Length; i++) {
DoStuff(ref array[i]);
}
static void DoStuff(ref Vector3 v)
{
// do stuff with v and have the array[i] value updated (because its a reference)
v.x += 12;
v.Normalize();
}
Then make lambda expression representing the DoStuff with the Parameter(typeof(Vector3).MakeByRef(), "v").
Does this work?
It would need to behave identically to the C# compiler's behavior. The example above is contrived. I'm building a language for people to write game code in that compiles to C# at production time and to IL (via expression trees) during runtime so I can support hot reloading. the syntax is 90% identical to C# to the point where you can basically copy + paste C# code into my script language it will run. Ref locals are the one thing I can't work around in my compiler via lowering and so I'd like to find a way to implement it for real.
Yes it should be possible, just get the address instead. But do you need to put all that code into expression or for instance only the body of the loop and convert the ref var to ref parameter?
Vector3[] array = new Vector3[100]; // struct btw for(int i = 0; i < array.Length; i++) { DoStuff(ref array[i]); } static void DoStuff(ref Vector3 v) { // do stuff with v and have the array[i] value updated (because its a reference) v.x += 12; v.Normalize(); }Then make lambda expression representing the
DoStuffwith theParameter(typeof(Vector3).MakeByRef(), "v").Does this work?
No, this won't work, since I'm making a scripting language, I don't know the input ahead of time and can't make that transformation work in all cases.
@weichx Just updated my prev answer with code.
Ok. I need to experiment with by-ref locals and ref assignments then. I'll keep you posted.
@weichx Just updated my prev answer with code.
Ok. I need to experiment with by-ref locals and ref assignments then. I'll keep you posted.
Awesome, thanks a lot!
@weichx Back to looking into it.