Self referencing computed property will cause an infinite loop and stackoverflow
When having a self referencing property with the computed attribute, delegatedecompiler will create an infinite loop and causes a stackoverflow.
See the testcase for an example project https://www.dropbox.com/s/40070ysin7h01j3/Self%20reference%20property%20overflowexception.zip?dl=0
If you change the property from if(Base == null)
to if ( Base == null || Base == default(TestClass)) It works. Maybe helps fixing the stuff.
Hi @mwillebrands, I've looked into the problem and it seems that the "fix" works when you cache Base to an variable.
Hi Alexander,
Thanks for your response. Could you maybe explain it a bit more, i don't really understand. I've tried looking through your source, but couldn't really find a way to fix it.
Thanks Maarten
@mwillebrands if you'll take a look to the difference in IL between "Debug" and "Release" versions you can get some ideas; however I'm not sure how to fix this yet.
Yeah i did, all i could think of is limit the amount of hoe many levels deep the decompiling should go. That works, however it is an hidious way to fix it ;)
But, I'm not sure how the decompiled expression tree should look like.
Well, i'm not really sure what causes the problem to arise in release. It's almost doing the same thing. Do you know what line in the IL causes it?
[DEBUG] http://hastebin.com/raqecebewi.py
[RELEASE] http://hastebin.com/iredufowur.il
They both should call get_Base and get_Test
The control flows for both seem to involve the three function calls. However, release only ever ldarg.0's, whereas debug does stloc.0 and ldloc.0 before returning. Perhaps modifying whatever generates that IL into having the same ldarg.0 -> function -> stloc.0 -> ldloc.0 -> ret flow (instead of ldarg.0 -> function -> ret) would work, given that caching Base to a variable beforehand makes it work. The immediate downside that I see there is that it might be slow, but you could test for that.
Yeah, that would work, however, i can't seem to get the same IL whatever i do. And this is pretty faulty, if a new version of the compiler changes the IL, you'll get strange errors and you don't know why...
I've changed it for now so it won't use Computed properties which reference itself, it's ugly, but it works. (Duplicated the logic in all the queries)
Could we build in that DelegateDecompiler will not generate a stackoverflow, but throws an exception if it goes like 1000 levels deep or something? I've put it in my own version, but maybe it's convenient for other people as well.
You might try implementing your workaround (caching before the call) and keeping the original workflow around, then making an test that tests both (and expects a problem on the original flow). Then when you upgrade your environment, you will know if it's different.
True, however i can't get the IL to be the same as the debug version. I think focusing on getting the IL the same isn't the way we should go.
I think focusing on getting the IL the same isn't the way we should go.
Yes.