Closed sbogie-gdi closed 1 year ago
There is definitely something funky going on. I suspect related to #146 . I recall removing some if LValue.IsType
The reason why I think it is related and not necessarily an issue with caching is that the following works:
Assert.AreEqual('FooBar', Template.Eval('<% print(_[0].Name() + _[1].Name()) %>', l));
I will probe more.
Another test I've created that failed similar to what you described:
Assert.AreEqual('FooBar', Template.Eval('<% for i := 0 to 1; print( _[i].Name()); end %>', l));
The caching is definitely aggravating the situation, but the passing test case is a bit strange.
I've done a test now with the caching removed, and the array dereferencing and for of loops work.
Is this blocking you at present - just want to get a sense of urgency and if I can review a bit more till next week?
Thanks for the quick response.
I believe your first test is passing because it's generating two separate IMethodCallExpr
s which each have their own RttiMethod cache.
No, this isn't a hard blocker for us. We've already adjusted the affected template to just pass an array with the precomputed values instead.
Thanks for also 'deep diving' ;) I'll try have these addressed for next week.
Regarding: if (LMethod = nil) or (LMethod.Parent.Handle <> AObject.TypeInfo) then
This might not behave well when multi threaded. I think probably best to just remove the caching for now.
Will be in next release. Currently in the dev branch.
When iterating over a collection of objects derived from a common base type, attempting to call a virtual method which has different overridden implementations results in an 'Invalid class typecast' error. The issue is occurs because the rtti method is cached on the
IMethodCallExpr
when invoking. This is a useful optimization, but assumes it will only ever be invoked with a single type.A simple fix is to just check the type against the cached method and redo the lookup on mismatch.
Sample test case: