跳到主要内容

Mono 实现说明

源码根: Packages/com.code-philosophy.zlua/Runtime/Mono/
Lua 可见语义: ../spec/ — 本文只写 Editor Mono 的目录、初始化与 Il2Cpp 差异。


1. 背景与目标

Runtime/Mono 已备份至 _archive/Mono-pre-rewrite-20260723/ 并自零重写。目标是 Editor 开发期 与 Il2Cpp Player 交互表现一致,目录与 Il2Cpp zlua/ 模块可对照阅读。

Mono 成员索引统一走 Lua 三表 closure(见 metatable/INDEXER-MONO.md)。


2. 目录对照

Runtime/Mono/ ←→ Il2Cpp zlua/
├── Lvm/ ←→ lvm/
├── Mt/ ←→ mt/
├── Marshaling/ ←→ marshal/ (禁止依赖 Mt;避让 System.Marshal)
├── Bridge/ ←→ bridge/ (含 LuaInvoke/ 子目录)
├── Emit/ ←→ generated/ (运行时 Expression 生成,非构建期 stub)
├── Utils/ ←→ utils/
└── DelegateImpl/ ← (避免与 System.Delegate 命名冲突)

命名空间: ZLua.Lvm / ZLua.Mt / ZLua.Marshaling / ZLua.Bridge / ZLua.Emit / ZLua.Utils / ZLua.DelegateImpl

入口类型名保留: LuaMonoAppDomain 仍在根命名空间 ZLua,供 Common 反射解析;Il2Cpp 侧对应 LuaAppDomain


3. 已锁定决策

#决策Mono 落点
D1删除旧 Mono,全新重写当前 Runtime/Mono/ 为 Phase 0–4
D2Lua 三表 indexer;无 C# Dispatch*Mt/TypeMemberLuaIndexer.cs
D3无法 Expression 特化 → 绑定期显式错误Emit/EmitException.cs
D4删除 [LuaInvoke] legacy(object[] / TryRewriteLegacyEditorMethodPhase 4 Weaver + Bridge/LuaInvoke/
D5无 Event 专用支持add_Xxx/remove_Xxx 为普通方法MetaBinding 不扫描 event 子表
D6Il2Cpp 复用 stub;Mono 每成员 Emit 一条桥Emit/ vs Il2Cpp generated/
D7MetaBinding 热路径无 methodId / MethodMarshalCtx upvalueEmit 闭包直接绑 MethodInfo/FieldInfo
D8目录 PascalCase;generated/Emit/见 §2

4. 初始化顺序

4.1 AppDomain 级(Lvm/LuaMonoAppDomain.cs

首次 LuaAppDomain.Initialize(moduleLoader)

步骤调用对照 Il2Cpp
1new LuaEnv()LuaEnv::Initialize 主体
1aluaL_openlibs + RegisterPrintRegisterLibs 前半
1bObjectRegistry.Initialize
1cStructRegistry.Initialize
1dMetaTableCache.Initialize
1eTypeMemberLuaIndexer.EnsureLoadedMono 独有:加载 indexer 工厂
2SetModuleLoader(moduleLoader)LuaLoader::SetModuleLoader
3LoadBuiltinGlobals()RegisterGlobals
4AssemblyRegistry.EnsureCSharpRoot()AssemblyRegistry::InitializeCSharpRoot
5ZLuaLib.RegisterGlobals(_luaEnv)ZLuaLib::RegisterGlobals
6EnsureBuiltinZLuaLib()嵌入 zlualib.lua 等价物
7DelegateBridges.Warmup()DelegateBridge::Initialize 预热

重复 Initialize:_luaEnv 已存在,仅更新 loader 并 EnsureBuiltinZLuaLib()

Shutdown: ProcessPendingRefReleasesLuaEnv.Dispose()(逆序释放 Registry / MetaTableCache,见 LuaEnv.cs)。

Il2Cpp 在 AppDomain 级额外提前执行 MethodBridge::Initialize 等 stub 表加载;Mono 对应桥由 Emit 按类型绑定 写入三表(Phase 3)。


5. 阶段进度与模块落点

Phase状态要点主要文件
0备份、骨架、LuaInvoke 占位ZLua.asmdefBridge/LuaInvoke/*
1Lvm 链、ObjectRegistry、cast/box、struct ByVal/ByObjLvm/LuaEnv.csMarshaling/*
2TypeRegistry*、SMT/IMT、三表 indexer、MetaBinding 扫描Mt/TypeRegistry*.csMt/MetaBinding.csMt/TypeMemberLuaIndexer.cs
3Emit 写入三表;ctor/__call;arity overload MVPEmit/*MemberTableEmitter.Fill
4Delegate Emit、ZLuaLib 大部、LuaInvokeBridge typed catalog、删 legacyDelegateImpl/Bridge/LuaInvoke/Marshaling/DelegateMarshal.cs
5✅ 实现 / ⏳ 验收NYI 补齐、Vector LuaInvoke、MethodClosureTag、LuaAlias、Pointer/params;manifest 待 Editor 跑通Emit/*Marshaling/PointerMarshalZLuaLib

Phase 5: register_method / make_generic_method / opaque get/set 已实装;开放泛型方法写入 throw stub + tag;Unity Vector LuaInvoke catalog 已加;[LuaAlias] 与 Il2Cpp 一致(别名替换默认键);Pointer lightuserdata + DynamicMethod;TypedReference/decimal/ByRefLike 调用期拒绝;params T[] 按数组编组。


6. 与 Il2Cpp 的关键差异

主题Il2CppMono
成员索引C Dispatch* + MetaBinding / TypeRegistryLua function __index/__newindex + 三表 upvalue
Lua→C# 桥构建期 C++ stub;MethodBridge::ResolveMethodInvoker 按签名查表绑定期 Expression.Compile()lua_pushcfunction共享 ReducedType stub
MetaBinding 上下文MethodMarshalCtx + registry ref closure特化闭包 runtime methodId upvalue
C#→LuaInternalCall + generated/LuaInvokeStub.cppIL PostProcessor 改写为 LuaInvokeBridge.{Method} + LuaInvokeSiteRegistry
Legacy LuaInvokeN/A(Player 仅 IC)已删除 TryRewriteLegacyEditorMethod / RunLuaFunc(object[]);仅 typed LuaInvokeBridge
Event无专用 MetaKind::Event无 Event 子表;add_*/remove_*methodTable
GC / 性能Il2Cpp GC + 槽位 pin槽位强引用 + weak cache;non-blittable ByVal 用 boxed companion

语义一致性验收以 ../spec/ 为准;实现路径不同 允许,但 miss/strict、overload、cast、struct 等行为须与 Il2Cpp 一致。


7. 验收标准

实现完成后须满足:

  • Editor Mono:Tests/Lua/manifest.lua 全绿
  • 与 Il2Cpp 一致:类型门面、zlua.cast、虚方法、overload、struct、delegate、数组
  • 无 Event 专用 API;add_/remove_ 仅作普通方法
  • 无 LuaInvoke legacy;无 ReducedType 共享桥
  • MetaBinding 热路径无 methodId / MarshalCtx upvalue
  • 热路径无巨量 GC / Method.Invoke 兜底

8. 关联文档