I'm developing for the iPhone using C# and Mono's Full AOT technology. According to their Limitations page (link text), unlike traditional Mono/.NET, code on the iPhone is statically compiled ahead of time instead of being compiled on demand by a JIT compiler.
When running on the hardware, the following exception occurs:
ExecutionEngineException: Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Image, UnityEngine.Color> (System.Reflection.MonoProperty/Getter`2<Image, UnityEngine.Color>,object)' while running with --aot-only.
System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) [0x00000]
Ani+AniValue.Get ()
Ani.CreateAnimations (System.Object obj, System.Collections.Hashtable properties, Single duration, System.Collections.Hashtable options, AniType type)
Ani.Method (AniType type, System.Object obj, Single duration, System.Collections.Hashtable _properties, System.Collections.Hashtable _options)
Ani.From (System.Object obj, Single duration, System.Collections.Hashtable _properties)
xObject+<>c__CompilerGenerated5.MoveNext ()
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
xObject:StartAnimation(Animate, GameObject, Object, Object)
SceneSplash:CreateBackground()
SceneSplash:OnSetup()
SceneSplash:OnSceneActivate(Callback)
GameController:ActivateScene()
GameController:DeactivateScene()
GameController:SceneLoaded(Scene, GameObject, SceneBase)
SceneBase:Start()
According to the Limitations document, System.Reflection.Emit is not supported, but they state that as side from Reflection.Emit, "the entire Reflection API, including Type.GetType("someClass"), listing methods, listing properties, fetching attributes and values works just fine."
I've included the code that is causing the exception ...
void CreateAnimations(System.Object obj, Hashtable properties, float duration,
Hashtable options, AniType type)
{
foreach (DictionaryEntry item in properties)
{
name = (string)item.Key; // Extract name and value
System.Object value = item.Value;
AniValue foo = new AniValue(obj, name); // Create value object
/* To exception occurs inside Get() */
System.Object current = foo.Get(); // Get current value
...
The above method grabs a property name from a hashtable, and uses it (along with obj) to create an instance of AniValue. Just afterward, foo.Get() is called to retrieve the value of the property. The exception occurs on propertyInfo.GetValue(obj, null).
using System.Reflection
public class AniValue
{
static BindingFlags bFlags = BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static;
System.Object obj; // Object a field or property is animated on
string name; // Name of the field or property
System.Type objType; // Type object
FieldInfo fieldInfo; // FieldInfo object
PropertyInfo propertyInfo; // PropertyInfo object
public AniValue(System.Object o, string n)
{
obj = o;
name = n;
objType = obj.GetType();
fieldInfo = objType.GetField(n, AniValue.bFlags);
propertyInfo = objType.GetProperty(n, AniValue.bFlags);
if (fieldInfo == null && propertyInfo == null)
{
throw new System.MissingMethodException("Property or field '" + n
+ "' not found on " + obj);
}
}
// Get field or property
public System.Object Get()
{
if (propertyInfo != null)
{
/* The next line causes the Exception */
return propertyInfo.GetValue(obj, null);
}
else
{
return fieldInfo.GetValue(obj);
}
}
...
Although I have limited experience with C#, JIT, AOT, and Reflection, should GetValue() trigger JIT? UnityEngine.Color is a struct, and the Image class is as subclass of xObject, which is a subclass of UnityEngine.MonoBehaviour. Color is a property of Image, and that is what the code could be getting the value of when the exception occurs.
Interestingly, you can compile the code using .NET 1.1, and everything executes fine. Only when you compile using .NET 2.1 does the exception occur.
I don't know if there is a solution or work around to this, but I would be interested in any insight as to the cause.