跳到主要内容

Il2Cpp 实现对照

源码根(可编辑): build-win64/Il2CppOutputProject/IL2CPP/libil2cpp/zlua
包内镜像(手动同步,勿直接改): Packages/com.code-philosophy.zlua/ZLua~/libil2cpp-2022/zlua
Lua 可见语义: ../spec/ — 本文只描述 C++ 模块划分、初始化顺序与文件职责。


1. 模块图

Il2Cpp runtime 按职责拆成七个顶层目录,与 Mono 重写后的 Runtime/Mono/ 一一对应(见 MONO.md §2)。

zlua/
├── lvm/ 宿主生命周期、Lua 状态、ZLuaLib、InternalCall、Loader
├── mt/ 类型注册、元表绑定、成员索引(`Dispatch*` + `MetaBinding`)
├── marshal/ Push/Pop、Registry、MarshalMeta、Overload 解析
├── bridge/ Method / Property / Field / Delegate / LuaInvoke 调用体
├── generated/ 构建期 Codegen 产物(stub 表、BuiltinScripts.inc)
├── utils/ 横切:MetadataUtil、异常、栈守卫、分配器
├── ZLuaCommon.* 公共头、宏门控、与 Lua VM 的 ABI 约定
└── LuaConsts.h 元表字段名、userdata kind 常量

依赖方向(硬约束):

  • marshal/ 不得 #include mt/(Mt 通过 MetatableHooks 回调或上层装配)。
  • bridge/ 可依赖 marshal/generated/mt/ 在绑定期调用 bridge/MarshalMeta
  • generated/ 仅被 lvm/bridge/ 引用;不参与运行时逻辑分支。

2. 初始化顺序

2.1 AppDomain 级(lvm/LuaAppDomain.cpp

Player 进程进入 Il2Cpp 后,托管侧调用 LuaAppDomain::Initialize(),顺序固定:

步骤调用职责
1LuaMetadataAlloc::Initialize()绑定期元数据堆(MethodMarshalCtxMarshalMetaInfo 等)
2MetadataUtil::Initialize()程序集 / 类型 / 方法解析缓存
3PropertyBridge::Initialize()加载 generated/PropertyBridgeStub.h 中的 getter/setter 函数表
4MethodBridge::Initialize()加载 generated/MethodBridgeStub.h 中的 lua2CsInvoker
5DelegateBridge::Initialize()加载 generated/DelegateBridgeStub.h
6LuaInternalCalls::RegisterCoreInternalCalls()核心 InternalCall(非 LuaInvoke)
7luainvoke::RegisterGeneratedInternalCalls()[LuaInvoke] 生成的 IC 注册(LuaInvokeStub.cpp
8LuaLoader::RegisterRoots()StreamingAssets / 模块搜索根
9LuaEnv::Initialize()创建 lua_State 并完成 Lua 侧 bootstrap(见下节)

可选:LuaAppDomain::InitializeFromManaged(Il2CppDelegate*) 在步骤 8 之后注入托管 moduleLoader delegate。

2.2 Lua 状态级(lvm/LuaEnv.cpp

LuaEnv::Initialize()单一全局 lua_State* 上执行:

步骤调用职责
1luaL_newstate()分配 VM
2RegisterGlobals()__ZLUA_IL2CPP_PLAYER__=true;嵌入 globals.luagenerated/BuiltinScripts.inc);缓存 __zluaErrorHandler ref
3RegisterLibs()luaL_openlibs;重定向 print → Unity Debug.LogZLuaLib::RegisterGlobals + 嵌入 zlualib.lua
4ObjectRegistry::Initialize(L)ByObj 弱缓存表 + 槽位强引用表
5StructRegistry::Initialize(L)non-blittable ByVal GC root 登记
6MetaTableCache::Initialize(L)类型元表 registry 缓存
7LuaLoader::InstallHooks()package.searchers / 自定义 loader
8AssemblyRegistry::InitializeCSharpRoot(L)csharp 根表,延迟类型绑定入口

ShutdownLuaEnv::Shutdown)与上述 逆序 释放:ProcessPendingRefReleasesMetaTableCacheStructRegistryObjectRegistryLuaGlobalRefs::Clear → 释放 error handler ref → lua_closeLuaLoader::Clear


3. 文件 → 职责表

3.1 lvm/

文件职责
LuaAppDomain.cpp/.hIl2Cpp 入口:Initialize / InitializeFromManaged / Shutdown 转发
LuaEnv.cpp/.h全局 lua_State、globals/libs 注册、error handler、dostring、pending ref 队列
ZLuaLib.cppC API 实现:zlua.import_typezlua.castzlua.box 等(语义见 ../spec/05-LIB.md
LuaInternalCalls.cpp/.h非 LuaInvoke 的 InternalCall 注册
LuaGlobalRefs.cpp/.hregistry 强引用集中管理
LuaLoader.cpp/.h模块搜索、StreamingAssets loader、托管 delegate loader

3.2 mt/

文件职责
AssemblyRegistry.cpp/.hcsharp 根、import_type 触发的程序集扫描
TypeRegistry.cpp/.h类型门面分派入口(reference / valuetype / array / enum)
TypeRegistryCommon.cpp/.h共用:类型表字段、IMT/SMT 填充、Dispatch* 挂载
TypeRegistryReference.cpp/.hclass / interface / delegate 绑定
TypeRegistryValueType.cpp/.hstruct / Nullable 绑定
TypeRegistryArray.cpp/.h数组类型、__len
MetaBinding.cpp/.hBind 期扫描 public 成员 → NameMetaMap;构造 method closure ref;overload group
MetaTableCache.cpp/.hIl2CppClass* 缓存 IMT/SMT registry ref
InstanceTarget.cpp/.huserdata → this 指针 / ByVal payload 地址解析

3.3 marshal/

文件职责
TypedMarshal.cpp/.hIl2CppType* 分派的 Push/Pop 门面
MarshalMeta.cpp/.h为 field/property/method 参数创建 MarshalMetaInfo 与 writer 函数指针
MarshalDefs.hMarshalMetaInfoMethodMarshalCtxMethodGroupsConversionKind 等核心结构
ObjectRegistry.cpp/.hByObj userdata:(obj, viewKlass) 弱缓存 + 槽位强引用
StructRegistry.cpp/.hnon-blittable ByVal:GC root 跟踪
ObjectMarshal.cpp/.h引用类型 push/pop
StructMarshal.cpp/.h值类型 ByVal/ByObj
PrimitiveMarshal.cpp/.h基元读写
StringMarshal.cpp/.hstring
ArrayMarshal.cpp/.h数组
DelegateMarshal.cpp/.hdelegate / Lua function
OpaqueValueMarshal.cpp/.hopaque / lightuserdata 路径
IntrinsicTypes.cpp/.hVector2/3/4 等内建 struct 特化
MethodOverloadResolver.cpp/.h运行时 overload 选择(规范 ../spec/04-METHOD-OVERLOAD.md

详见 marshal/README.md

3.4 bridge/

文件职责
MethodBridge.cpp/.h解析 stub 表 → FnLua2CsInvoker;默认 alloca + writer 慢路径
PropertyBridge.cpp/.hproperty getter/setter stub 调度
FieldBridge.cpp/.h字段 offset 读写(与 FieldMarshalCtx 配合)
DelegateBridge.cpp/.hC# delegate ↔ Lua function
LuaInvokeHelper.cpp/.hC#→Lua:[LuaInvoke] 站点解析与调用
BridgeDefs.hbridge 侧共享 typedef

3.5 generated/(构建产出,勿手改)

产物生成器职责
MethodBridgeStub.hMethodBridgeCodegen每个 AOT 方法一条 Bridge_* + lua2CsInvoker 条目
PropertyBridgeStub.hPropertyBridgdeCodegenproperty accessor stub
DelegateBridgeStub.hDelegateBridgeCodgendelegate invoke stub
LuaInvokeStub.h/.cppLuaInvokeCodegen[LuaInvoke] InternalCall 表
MarshalBindings.*MarshalAsCodegen[LuaMarshalAs] 扩展 writer
BuiltinScripts.incBuiltinScriptsCodegen嵌入 globals.lua / zlualib.lua

详见 codegen/STUBS-IL2CPP.md

3.6 utils/

文件职责
MetadataUtil.cpp/.hIl2Cpp 反射:类型查找、方法 sealed 判定、value size
LuaException.cpp/.hC++ → 托管异常 / Lua error
LuaUtil.cpp/.hregistry ref、字符串、栈辅助
LuaStackGuard.hRAII 栈平衡
LuaMetadataAlloc.cpp/.h绑定期分配器
Collection.hAppendOnlyStringHashMap 等绑定期容器

4. 与 Mono 的对照要点

维度Il2CppMono
成员索引Dispatch* + MetaBinding / TypeRegistryINDEXER-IL2CPP.mdLua 三表 indexer(INDEXER-MONO.md
Lua→C# 桥Codegen stub 复用(按 ReducedType 签名)Emit/ 每成员 Expression.Compile
C#→Luagenerated LuaInvokeStub + InternalCallWeaver → LuaInvokeBridge typed catalog
Event已移除专用元数据;add_*/remove_* 为普通方法同左

5. 关联文档