Environment
- Nino: 4.0.0-preview.143
- HybridCLR: 8.9.0
- Unity: 2022.3
Description
Serializing any [NinoType] class that contains a Dictionary<K,V> field throws System.ArrayTypeMismatchException when running in HybridCLR (hot-update interpreter). Works fine in the Unity editor (Mono JIT).
Minimal Reproduction
[NinoType]
public class Repro
{
public Dictionary<int, int> Data = new() { { 1, 100 } };
}
// In MonoBehaviour.Start():
var bytes = NinoSerializer.Serialize(new Repro()); // ❌ ArrayTypeMismatchException
Nested dictionaries are also affected:
[NinoType]
public class Root
{
public Dictionary<int, Child> Children = new();
}
[NinoType]
public class Child
{
public int Id;
public Dictionary<int, int> Values = new();
}
Stack Trace
System.ArrayTypeMismatchException: Attempted to access an element as a type incompatible with the array.
at NinoGen.Serializer.Serialize (Dictionary`2[TKey,TValue] value, Writer& writer)
at NinoGen.Serializer.SerializeImpl (Root value, Writer& writer)
at Nino.Core.NinoSerializer.Serialize[T] (T value, Writer& writer)
at Nino.Core.NinoSerializer.Serialize[T] (T value)
Root Cause
The generated Serialize(Dictionary<K,V>, ref Writer) method uses:
Entry<K,V>[] entries = Unsafe.As<Dictionary<K,V>, DictionaryView<K,V>>(ref value)._entries;
ref Entry<K,V> source = ref entries[0]; // ❌ throws here
Unsafe.As reinterprets the Dictionary reference as a DictionaryView to access the internal _entries field. The runtime array type is Dictionary<K,V>.Entry[] but the code accesses it as DictionaryView<K,V>.Entry[].
- Editor (Mono JIT):
Unsafe.As is a JIT intrinsic, no runtime type checking on array element access → works
- HybridCLR (interpreter): The
ldelema IL instruction performs runtime type checking, detects DictionaryView.Entry ≠ Dictionary.Entry → ArrayTypeMismatchException
Suggested Fix
The generated Dictionary serializer needs a HybridCLR-compatible code path, for example using Dictionary.GetEnumerator() instead of Unsafe.As<Dictionary, DictionaryView> when targeting interpreters.
Ref: JasonXuDeveloper/JEngine#621
Environment
Description
Serializing any
[NinoType]class that contains aDictionary<K,V>field throwsSystem.ArrayTypeMismatchExceptionwhen running in HybridCLR (hot-update interpreter). Works fine in the Unity editor (Mono JIT).Minimal Reproduction
Nested dictionaries are also affected:
Stack Trace
Root Cause
The generated
Serialize(Dictionary<K,V>, ref Writer)method uses:Unsafe.Asreinterprets theDictionaryreference as aDictionaryViewto access the internal_entriesfield. The runtime array type isDictionary<K,V>.Entry[]but the code accesses it asDictionaryView<K,V>.Entry[].Unsafe.Asis a JIT intrinsic, no runtime type checking on array element access → worksldelemaIL instruction performs runtime type checking, detectsDictionaryView.Entry≠Dictionary.Entry→ArrayTypeMismatchExceptionSuggested Fix
The generated Dictionary serializer needs a HybridCLR-compatible code path, for example using
Dictionary.GetEnumerator()instead ofUnsafe.As<Dictionary, DictionaryView>when targeting interpreters.Ref: JasonXuDeveloper/JEngine#621