public Value(Type type, JValue value) { IsNone = value == null; @bool = default; @byte = default; @sbyte = default; @short = default; @ushort = default; @int = default; @uint = default; @long = default; @ulong = default; @char = default; @double = default; @float = default; @string = IL2CPP.ManagedStringToIl2Cpp(""); if (type == typeof(string)) { tag = ValueType.String; if (value == null) { return; } // FIXME: // The purpose of intern is to prevent GC from freeing our string to avoid UAF. // But intern will run into some performance problems sometimes. // Maybe making a reference circle is another solution. @string = Il2CppHelper.il2cpp_string_intern( IL2CPP.ManagedStringToIl2Cpp(value.Value <string>())); } else if (type == typeof(bool)) { tag = ValueType.Boolean; if (value == null) { return; } @bool = value.Value <bool>(); } else if (type == typeof(byte)) { tag = ValueType.Byte; if (value == null) { return; } @byte = value.Value <byte>(); } else if (type == typeof(sbyte)) { tag = ValueType.SByte; if (value == null) { return; } @sbyte = value.Value <sbyte>(); } else if (type == typeof(short)) { tag = ValueType.Int16; if (value == null) { return; } @short = value.Value <short>(); } else if (type == typeof(ushort)) { tag = ValueType.UInt16; if (value == null) { return; } @ushort = value.Value <ushort>(); } else if (type == typeof(int)) { tag = ValueType.Int32; if (value == null) { return; } @int = value.Value <int>(); } else if (type == typeof(uint)) { tag = ValueType.UInt32; if (value == null) { return; } @uint = value.Value <uint>(); } else if (type == typeof(long)) { tag = ValueType.Int64; if (value == null) { return; } @long = value.Value <long>(); } else if (type == typeof(ulong)) { tag = ValueType.UInt64; if (value == null) { return; } @ulong = value.Value <ulong>(); } else if (type == typeof(char)) { tag = ValueType.Char; if (value == null) { return; } @char = value.Value <char>(); } else if (type == typeof(double)) { tag = ValueType.Double; if (value == null) { return; } @double = value.Value <double>(); } else if (type == typeof(float)) { tag = ValueType.Single; if (value == null) { return; } @float = value.Value <float>(); } else { throw new NotSupportedException($"Type {type} is not supported"); } }