| | |
| | | "versions": [ |
| | | { |
| | | "unity_version":"2019", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "il2cpp_plus": { "branch":"v2019-8.1.0"} |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v2019-8.9.0"} |
| | | }, |
| | | { |
| | | "unity_version":"2020", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "il2cpp_plus": { "branch":"v2020-8.1.0"} |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v2020-8.9.0"} |
| | | }, |
| | | { |
| | | "unity_version":"2021", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v2021-8.1.0"} |
| | | }, |
| | | { |
| | | "unity_version":"2022", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "il2cpp_plus": { "branch":"v2022-8.2.0"} |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v2022-8.11.0"} |
| | | }, |
| | | { |
| | | "unity_version":"2022-tuanjie", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "il2cpp_plus": { "branch":"v2022-tuanjie-8.3.0"} |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v2022-tuanjie-8.11.0"} |
| | | }, |
| | | { |
| | | "unity_version":"2023", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v2023-8.1.0"} |
| | | }, |
| | | { |
| | | "unity_version":"6000", |
| | | "hybridclr" : { "branch":"v8.5.1"}, |
| | | "il2cpp_plus": { "branch":"v6000-8.1.0"} |
| | | "hybridclr" : { "branch":"v8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v6000-8.11.0"} |
| | | }, |
| | | { |
| | | "unity_version":"6000.3.x", |
| | | "hybridclr" : { "branch":"v6000.3.x-8.12.0"}, |
| | | "il2cpp_plus": { "branch":"v6000.3.x-8.11.0"} |
| | | } |
| | | ] |
| | | } |
| | |
| | | if (ptr == IntPtr.Zero) |
| | | return; |
| | | |
| | | #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN |
| | | #if UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN) |
| | | uint oldProtect; |
| | | bool ret = VirtualProtect(ptr, (uint)size, Protection.PAGE_EXECUTE_READWRITE, out oldProtect); |
| | | UnityEngine.Debug.Assert(ret); |
| | |
| | | }; |
| | | |
| | | |
| | | #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN |
| | | #if UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN) |
| | | [Flags] |
| | | public enum Protection |
| | | { |
| | |
| | | return; |
| | | } |
| | | BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); |
| | | #if UNITY_6000_0_OR_NEWER |
| | | NamedBuildTarget namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup); |
| | | ScriptingImplementation curScriptingImplementation = PlayerSettings.GetScriptingBackend(namedBuildTarget); |
| | | #else |
| | | ScriptingImplementation curScriptingImplementation = PlayerSettings.GetScriptingBackend(buildTargetGroup); |
| | | #endif |
| | | ScriptingImplementation targetScriptingImplementation = ScriptingImplementation.IL2CPP; |
| | | if (curScriptingImplementation != targetScriptingImplementation) |
| | | { |
| | | Debug.LogError($"[CheckSettings] current ScriptingBackend:{curScriptingImplementation},have been switched to:{targetScriptingImplementation} automatically"); |
| | | #if UNITY_6000_0_OR_NEWER |
| | | PlayerSettings.SetScriptingBackend(namedBuildTarget, targetScriptingImplementation); |
| | | #else |
| | | PlayerSettings.SetScriptingBackend(buildTargetGroup, targetScriptingImplementation); |
| | | #endif |
| | | } |
| | | |
| | | var installer = new Installer.InstallerController(); |
| | |
| | | return $"{projectDir}/Library/Bee/artifacts/PS4PlayerBuildProgram/ManagedStripped"; |
| | | case BuildTarget.PS5: |
| | | return $"{projectDir}/Library/Bee/artifacts/PS5PlayerBuildProgram/ManagedStripped"; |
| | | case BuildTarget.GameCoreXboxOne: |
| | | case BuildTarget.GameCoreXboxSeries: |
| | | return $"{projectDir}/Library/Bee/artifacts/GameCorePlayerBuildProgram/ManagedStripped"; |
| | | #if UNITY_WEIXINMINIGAME |
| | | case BuildTarget.WeixinMiniGame: |
| | | return $"{projectDir}/Library/Bee/artifacts/WeixinMiniGame/ManagedStripped"; |
| | |
| | | using System.Threading.Tasks; |
| | | using UnityEditor; |
| | | using UnityEngine; |
| | | using static UnityEngine.Networking.UnityWebRequest; |
| | | |
| | | namespace HybridCLR.Editor.Commands |
| | | { |
| | |
| | | { |
| | | UnityEngine.Debug.Log($"[BashUtil] CopyDir {src} => {dst}"); |
| | | } |
| | | RemoveDir(dst); |
| | | if (Directory.Exists(dst)) |
| | | { |
| | | RemoveDir(dst); |
| | | } |
| | | else |
| | | { |
| | | string parentDir = Path.GetDirectoryName(Path.GetFullPath(dst)); |
| | | Directory.CreateDirectory(parentDir); |
| | | } |
| | | |
| | | UnityEditor.FileUtil.CopyFileOrDirectory(src, dst); |
| | | } |
| | |
| | | #if UNITY_6000_3_OR_NEWER && UNITY_EDITOR_OSX |
| | | #define NEW_IL2CPP_PATH |
| | | #endif |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | |
| | | using System.Text.RegularExpressions; |
| | | using System.Linq; |
| | | using HybridCLR.Editor.Settings; |
| | | using System.Runtime.InteropServices; |
| | | |
| | | namespace HybridCLR.Editor.Installer |
| | | { |
| | |
| | | { |
| | | _curVersion = ParseUnityVersion(Application.unityVersion); |
| | | _versionManifest = GetHybridCLRVersionManifest(); |
| | | _curDefaultVersion = _versionManifest.versions.FirstOrDefault(v => _curVersion.isTuanjieEngine ? v.unity_version == $"{_curVersion.major}-tuanjie" : v.unity_version == _curVersion.major.ToString()); |
| | | _curDefaultVersion = _versionManifest.versions.FirstOrDefault(v => { |
| | | return _curVersion.isTuanjieEngine? v.unity_version == $"{_curVersion.major}-tuanjie" |
| | | #if UNITY_6000_3_OR_NEWER |
| | | : v.unity_version == "6000.3.x" |
| | | #else |
| | | : v.unity_version == _curVersion.major.ToString() |
| | | #endif |
| | | ; |
| | | }); |
| | | PackageVersion = LoadPackageInfo().version; |
| | | InstalledLibil2cppVersion = ReadLocalVersion(); |
| | | } |
| | |
| | | case 2021: return "2021.3.0"; |
| | | case 2022: return "2022.3.0"; |
| | | case 2023: return "2023.2.0"; |
| | | #if UNITY_6000_3_OR_NEWER |
| | | case 6000: return "6000.3.0"; |
| | | #else |
| | | case 6000: return "6000.0.0"; |
| | | #endif |
| | | default: return $"2020.3.0"; |
| | | } |
| | | } |
| | |
| | | |
| | | public string Il2cppPlusLocalVersion => _curDefaultVersion?.il2cpp_plus?.branch; |
| | | |
| | | |
| | | private string GetIl2CppPathByContentPath(string contentPath) |
| | | public string ApplicationIl2cppPath |
| | | { |
| | | return $"{contentPath}/il2cpp"; |
| | | get |
| | | { |
| | | Debug.Log($"application path:{EditorApplication.applicationPath} {EditorApplication.applicationContentsPath}"); |
| | | #if NEW_IL2CPP_PATH |
| | | #if UNITY_IOS |
| | | string platformDirName = "iOSSupport"; |
| | | #elif UNITY_TVOS |
| | | string platformDirName = "AppleTVSupport"; |
| | | #elif UNITY_VISIONOS |
| | | string platformDirName = "VisionOSPlayer"; |
| | | #else |
| | | string platformDirName = "iOSSupport"; |
| | | #endif |
| | | return $"{EditorApplication.applicationContentsPath}/../../PlaybackEngines/{platformDirName}/il2cpp"; |
| | | #else |
| | | return $"{EditorApplication.applicationContentsPath}/il2cpp"; |
| | | #endif |
| | | } |
| | | } |
| | | |
| | | public string ApplicationIl2cppPath => GetIl2CppPathByContentPath(EditorApplication.applicationContentsPath); |
| | | |
| | | public string LocalVersionFile => $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/generated/libil2cpp-version.txt"; |
| | | |
| | |
| | | // create LocalIl2Cpp |
| | | string localUnityDataDir = SettingsUtil.LocalUnityDataDir; |
| | | BashUtil.RecreateDir(localUnityDataDir); |
| | | |
| | | #if !NEW_IL2CPP_PATH |
| | | // copy MonoBleedingEdge |
| | | BashUtil.CopyDir($"{Directory.GetParent(editorIl2cppPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true); |
| | | |
| | | #endif |
| | | // copy il2cpp |
| | | BashUtil.CopyDir(editorIl2cppPath, SettingsUtil.LocalIl2CppDir, true); |
| | | #if NEW_IL2CPP_PATH |
| | | string buildDir = $"{SettingsUtil.LocalIl2CppDir}/build"; |
| | | if (RuntimeInformation.ProcessArchitecture == Architecture.Arm || RuntimeInformation.ProcessArchitecture == Architecture.Arm64) |
| | | { |
| | | BashUtil.CopyDir($"{buildDir}/deploy_arm64", $"{buildDir}/deploy", false); |
| | | } |
| | | else |
| | | { |
| | | BashUtil.CopyDir($"{buildDir}/deploy_x86_64", $"{buildDir}/deploy", false); |
| | | } |
| | | #endif |
| | | |
| | | // replace libil2cpp |
| | | string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp"; |
| | |
| | | { |
| | | return CallingConvention.Winapi; |
| | | } |
| | | if (monoPInvokeCallbackAttr.ConstructorArguments.Count == 0) |
| | | { |
| | | Debug.LogError($"MonoPInvokeCallbackAttribute on method {method.FullName} has no constructor arguments. Using CallingConvention.Winapi as default."); |
| | | return CallingConvention.Winapi; |
| | | } |
| | | object delegateTypeSig = monoPInvokeCallbackAttr.ConstructorArguments[0].Value; |
| | | |
| | | TypeDef delegateTypeDef; |
| | |
| | | throw new NotSupportedException($"Unsupported delegate type: {delegateTypeSig}"); |
| | | } |
| | | var attr = delegateTypeDef.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute"); |
| | | if (attr == null) |
| | | if (attr == null || attr.ConstructorArguments.Count == 0) |
| | | { |
| | | return CallingConvention.Winapi; |
| | | } |
| | |
| | | - [官方文档](https://www.hybridclr.cn/docs/intro) |
| | | - [快速上手](https://www.hybridclr.cn/docs/beginner/quickstart) |
| | | - [商业项目案例](https://www.hybridclr.cn/docs/other/businesscase) |
| | | - [LeanCLR](https://github.com/focus-creative-games/leanclr) |
| | | |
| | | ## 特性 |
| | | |
| | |
| | | - 商业合作邮箱: business#code-philosophy.com |
| | | - [商业化支持](https://www.hybridclr.cn/docs/business/intro) |
| | | |
| | | ## 相关项目 LeanCLR |
| | | |
| | | hybridclr仅是一个解释器模块,如果你需要一个完整小巧的适合发布到移动和小游戏平台的开源CLR实现,[LeanCLR](https://github.com/focus-creative-games/leanclr) 是当前最合适的方案。 |
| | | |
| | | LeanCLR 是一个面向全平台的精益 CLR(Common Language Runtime)实现。LeanCLR 在高度符合 ECMA-335 规范的前提下,提供更紧凑、易嵌入、低内存占用的运行时,实现对移动端、H5 与小游戏等资源受限平台的友好支持。LeanCLR原生支持 AOT + Interpreter 混合执行模式,内置 IL 与 IR 双解释器。 |
| | | |
| | | LeanCLR既可以独立嵌入到任何app和游戏项目,发布到任何平台,也可以**替代il2cpp作为Unity(团结引擎)发布到webgl和小游戏平台的运行时**。大幅缩减包体和内存开销。 |
| | | |
| | | ## 关于作者 |
| | | |
| | | **walon** :**Code Philosophy(代码哲学)** 创始人 |
| | |
| | | - [Official Documentation](https://www.hybridclr.cn/en/docs/intro) |
| | | - [Quick Start](https://www.hybridclr.cn/en/docs/beginner/quickstart) |
| | | - [Business Project Cases](https://www.hybridclr.cn/en/docs/other/businesscase) |
| | | - [LeanCLR](https://github.com/focus-creative-games/leanclr) |
| | | |
| | | ## Features |
| | | |
| | |
| | | - Business cooperation email: business#code-philosophy.com |
| | | - [Commercial Support](https://www.hybridclr.cn/en/docs/business/intro) |
| | | |
| | | ## LeanCLR Project |
| | | |
| | | HybridCLR is just an interpreter module. If you need a complete, compact, open-source CLR implementation suitable for mobile and mini-game platforms, [LeanCLR](https://github.com/focus-creative-games/leanclr) is currently the best solution. |
| | | |
| | | LeanCLR can be embedded independently into any app or game project and published to any platform. It can also **replace il2cpp as the runtime for Unity (Unity Engine) when publishing to webgl and mini-game platforms**, greatly reducing package size and memory usage. |
| | | |
| | | ## About the Author |
| | | |
| | | **walon**: Founder of **Code Philosophy (代码哲学)** |
| | |
| | | # ReleaseLog |
| | | |
| | | ## 8.12.0 |
| | | |
| | | Release Date: 2026-06-01. |
| | | |
| | | ### Runtime |
| | | |
| | | - fix: also setup packingSize to TypeDefinition.bitfield at bit position il2cpp::vm::kSpecifiedPackingSize so that Type.StructLayoutAttribute.Pack return the correct packingSize |
| | | - fix: get wrong packing and classSize for the struct when interpreter type contains a AOT generic struct |
| | | |
| | | ### Editor |
| | | |
| | | - fix: correct conditional compilation macro of MonoHook for Windows standalone targeting |
| | | |
| | | ## 8.11.0 |
| | | |
| | | Release Date: 2026-02-28. |
| | | |
| | | ### Runtime |
| | | |
| | | - [fix] fix methodPointer of Full Generic Sharing Method may not be initialized in some cases, which leads to methodPointerCallByInterp not initialized correctly. |
| | | - [fix] handle intrinsic System.Array.UnsafeMov specially. It will raise unbox exception if runs this generic method at interpreter mod. |
| | | - [fix] adjust data type at stack top after JitHelper::UnsafeCast and JitHelper::UnsafeEnumCastLong. |
| | | - [fix] **6000.3.x**: fix bug of comparing MVAR in IsSameOverrideType |
| | | |
| | | ## 8.10.0 |
| | | |
| | | Release Date: 2026-02-24. |
| | | |
| | | ### Runtime |
| | | |
| | | - fix: fix bug of computing interface vtable implement when re-implements interface in child class. |
| | | - fix: for arrays whose element type is a value type, `ldelema` no longer performs type-matching checks. |
| | | Although this does not strictly follow the ECMA-335 specification, it is consistent with the behavior of Mono and CoreCLR. |
| | | - fix: fix bug that didn't handle RuntimeOptionId::MaxInlineableMethodBodySize in RuntimeConfig::GetRuntimeOption and RuntimeConfig::SetRuntimeOption. |
| | | - fix: assign FindImageByAssembly result to image in PreJitClass |
| | | - fix: use strict bounds in CheckMulOverflow for int32 and uint32 |
| | | - fix: fix arguments overflow when method argument count > 256 in InvokeDelegateBeginInvoke. |
| | | |
| | | ### Editor |
| | | |
| | | - [new]: support BuildTarget GameCoreXboxOne and GameCoreXboxSeries. |
| | | |
| | | ## 8.9.0 |
| | | |
| | | Release Date: 2026-01-12. |
| | | |
| | | ### Runtime |
| | | |
| | | - [fix] **Unity 6.3.x**: fix bug that didn't handle interpreter type in GlobalMetadata::GetNestedTypes |
| | | - [fix] **Unity 6.3.x**: fix crash on GlobalMetadata::GetMethodHandleFromMethodInfo because it maybe passed null as methodInfo in setup vtable. |
| | | - [fix] **TUANJIE**: fix IL2CPP_ASSERT fail in Class::GetVirtualMethod when klass is generic class and not initialized, at this time klass->vtable_count == 0 |
| | | - [fix] **TUANJIE**: fix the bug that didn't initialize method->klass->rgctx_data after GenericMetadata::InflateRGCTXMethod |
| | | - [change] **TUANJIE**: [merge] merge il2cpp changes from tuanjie 1.6.7 to 1.6.8 |
| | | |
| | | ## 8.8.0 |
| | | |
| | | Release Date: 2025-12-14. |
| | | |
| | | ### Runtime |
| | | |
| | | - [new] support 6000.3.x |
| | | - [new] add instructions for ldfld and stfld while field offset >= 2^16 |
| | | - [fix] fix offset overflow issue for ldflda, ldfld, stfld while offset >= 2^16 |
| | | - [fix] fix bug of comparing array rank |
| | | |
| | | ### Editor |
| | | |
| | | - [new] support 6000.3.x |
| | | - [fix] fix deprecated warning of `PlayerSettings.GetScriptingBackend(BuildTargetGroup)` in Unity 6000 |
| | | |
| | | ## 8.7.0 |
| | | |
| | | Release Date: 2025-11-03. |
| | | |
| | | ### Runtime |
| | | |
| | | - [fix] fix a crash issue in IH_object_ctor caused by `ctx.GetCurbb()->insts` may be empty in obfuscated code |
| | | - [merge] **Unity 6000***: merge il2cpp changes from 6000.0.44 to 6000.0.60 |
| | | - [merge] **TuanJie**: merge il2cpp changes from tuanjie 1.6.5 to 1.6.7 |
| | | |
| | | ### Editor |
| | | |
| | | - [fix] fix raising NullReferenceException in generating MethodBridge for MonoPInvokeCallbackAttribute while constructor arguments is empty. |
| | | |
| | | ## 8.6.0 |
| | | |
| | | Release Date: 2025-09-27. |
| | | |
| | | ### Runtime |
| | | |
| | | - [fix] fix the crash in InterpreterDelegateInvoke when compiled in Release mode on Xcode 26.x. This bug is caused by an optimization issue in the newer Clang version. |
| | | - [fix] [tuanjie] fix a bug on tuanjie that calling Init of Il2CppClass `Nullable<EnumType`> may not init Il2CppClass of EnumType, which causes crash when box `Nullable<EnumType>` |
| | | - [fix] [tuanjie] fix bug that computation of method index in Class::GetGenericInstanceMethodFromDefintion. tuanjie 1.6.4 only fixes it when IL2CPP_ENABLE_LAZY_INIT. |
| | | - [merge] merge il2cpp of tuanjie changes from 1.6.0-1.6.4 |
| | | |
| | | ### Editor |
| | | |
| | | - [fix] fix the bug that BashUtil.CopyDir calls UnityEditor.FileUtil.CopyFileOrDirectory failed when parent directory of dst does not exist. |
| | | |
| | | ## 8.5.1 |
| | | |
| | | Release Date: 2025-08-25. |
| | |
| | | { |
| | | "name": "com.code-philosophy.hybridclr", |
| | | "version": "8.5.1", |
| | | "version": "8.12.0", |
| | | "displayName": "HybridCLR", |
| | | "description": "HybridCLR is a fully featured, zero-cost, high-performance, low-memory solution for Unity's all-platform native c# hotupdate.", |
| | | "category": "Scripting", |