Metatable layout
This document specifies the structure of the type table, static metatable (SMT), and instance metatable (IMT) that ZLua exposes on the Lua side. All key names match LuaConsts.h. Lua scripts depend on these layouts indirectly through member access, typeof, construction, and related APIs, but must not depend on native implementation details (such as Dispatch closures or three-table upvalue layout — see impl/metatable/).
Member index (`__index` / `__newindex`)
This document specifies how Lua accesses C# static members (type table T + static metatable SMT) and instance members (userdata + instance metatable IMT) through __index / __newindex. The spec describes Lua-visible semantics; Mono implements this with Lua closures and three-table upvalues, while Il2Cpp uses a native indexer. Both (and any future VM fast paths) must behave identically.
Member binding (bind-time rules)
This document specifies how the EnsureBinding phase scans, classifies, and writes C# type members into the static/instance three tables (methodTable, fieldGetterTable, fieldSetterTable). After binding completes, runtime index behavior is fully defined by 02-INDEX.md; this document does not cover how native code generates bridge closures (see impl/metatable/, impl/codegen/).
Special-type metatable behavior
This document summarizes metatable-layout and member-index special cases for enum, Nullable\, struct, arrays, and delegates. Push/Pop of values, ByVal/ByObj payload layout, and other Marshal details are in the ../marshal/ volumes; this document only describes Lua-script-visible table structure, metamethods, and index entry points.
Metatable Spec (`spec/metatable/`)
This directory defines the Lua-visible layout of ZLua type tables, static metatables (SMT), and instance metatables (IMT), plus __index / __newindex member-dispatch semantics. Content is normative: Mono and Il2Cpp runtimes must behave the same; concrete implementations (Mono three-table Lua indexer, Il2Cpp native Dispatch*, etc.) live under impl/metatable/.