Add metatable, raw table access, and userdata support#5
Conversation
Lua module: raw-get, raw-set, raw-geti, raw-seti, raw-len for direct table access bypassing metamethods; get-metatable, set-metatable, new-metatable, set-named-metatable for metatable operations; new-userdata, check-userdata, test-userdata for GC-managed userdata; TYPE_USERDATA and TYPE_LIGHTUSERDATA constants. Luax module: maybe-get-userdata for type-checked userdata reads.
There was a problem hiding this comment.
Build & Tests
CI passes on both ubuntu-latest and macos-latest (lint + format). Cannot build locally — no Carp compiler on this machine.
However: the CI workflow (ci.yml:40-41) only runs test/lua.carp and test/midlevel.carp. The new test/metatable.carp is not executed by CI. The PR description notes this — the GitHub App lacks workflows permission to update the CI config. This means CI passing does not validate the new tests compile or run correctly. (Same issue affects test/cfunction.carp from a previous PR.)
Findings
Read the full lua.carp (bindings) and test/metatable.carp (22 tests) on the branch.
1. Bindings are correct against the Lua 5.4 C API:
| Binding | C function | Signature | Notes |
|---|---|---|---|
raw-get |
lua_rawget |
(Fn [&Lua Int] Int) |
✓ |
raw-set |
lua_rawset |
(Fn [&Lua Int] ()) |
✓ |
raw-geti |
lua_rawgeti |
(Fn [&Lua Int Int] Int) |
✓ — lua_Integer ↔ Int is safe on 64-bit |
raw-seti |
lua_rawseti |
(Fn [&Lua Int Int] ()) |
✓ |
raw-len |
lua_rawlen |
deftemplate with (int) cast |
✓ — size_t → int is safe for table lengths |
get-metatable |
lua_getmetatable |
(Fn [&Lua Int] Bool) |
✓ |
set-metatable |
lua_setmetatable |
deftemplate discarding return | ✓ |
new-metatable |
luaL_newmetatable |
(Fn [&Lua (Ptr CChar)] Bool) |
✓ |
set-named-metatable |
luaL_setmetatable |
(Fn [&Lua (Ptr CChar)] ()) |
✓ |
new-userdata |
lua_newuserdata |
deftemplate with (size_t) cast |
✓ |
check-userdata |
luaL_checkudata |
(Fn [&Lua Int (Ptr CChar)] (Ptr ())) |
✓ |
test-userdata |
luaL_testudata |
(Fn [&Lua Int (Ptr CChar)] (Ptr ())) |
✓ |
2. maybe-get-userdata (Luax) is correct. Checks for both TYPE_USERDATA and TYPE_LIGHTUSERDATA before calling get-user-data. This is a manual implementation rather than using luax--def-maybe-get because it needs a two-type check — good call.
3. Tests are comprehensive and well-structured. Coverage: raw-get/set with int and string keys, raw-geti/seti, raw-len (populated + empty), get/set-metatable, new-metatable (new + existing name), set-named-metatable, __index method dispatch, raw-get bypassing __index, new-userdata (type check + non-null), userdata with metatable, test-userdata (match + mismatch), TYPE_USERDATA constant, maybe-get-userdata (Just + Nothing).
4. Dead code in test file. test-point-add (lines 11-15) and its prepare-cfunction call (line 17) are defined but never used in any test. Appears to be leftover from planned __add metamethod testing. Minor — doesn't affect correctness.
5. Documentation updates are good. Module-level docstring additions for raw access, metatables, and userdata are accurate and well-integrated into the existing narrative.
6. TYPE_USERDATA and TYPE_LIGHTUSERDATA constants correctly register LUA_TUSERDATA and LUA_TLIGHTUSERDATA.
Verdict: revise
The bindings themselves look correct and the tests are thorough, but:
- The new tests are not run by CI. Until
carp -x test/metatable.carp(and ideallycarp -x test/cfunction.carpfrom the earlier PR) is added to the workflow's test step, there is no automated verification that this code compiles or runs correctly. The lint/format checks pass, but that's not sufficient. - Dead code: Remove the unused
test-point-addfunction and itsprepare-cfunctionfrom the test file, or add the test that uses it.
The workflow update is the blocker — once the tests are actually running in CI and passing, this is ready to merge.
bcf8fb8 to
7e899ff
Compare
|
Addressed the review:
Marked ready for review. The bindings were verified against the Lua 5.4 C API; nothing else blocks merge from the code side — just needs a maintainer approval. Generated by Claude Code |
Summary
Adds three groups of low-level Lua C API bindings to the
Luamodule, plus aLuaxhelper:raw-get,raw-set,raw-geti,raw-seti,raw-lenfor direct table manipulation bypassing metamethodsget-metatable,set-metatable,new-metatable,set-named-metatablefor attaching and querying metatables (registry-based and ad-hoc)new-userdatafor GC-managed memory blocks,check-userdataandtest-userdatafor typed access, plusTYPE_USERDATAandTYPE_LIGHTUSERDATAconstantsmaybe-get-userdatafor type-checked userdata reads returningMaybeThese are natural extensions of the existing table and cfunction APIs and enable object-oriented Lua scripting patterns (metatable-based method dispatch, operator overloading) from Carp.
22 new tests in
test/metatable.carp. All existing tests continue to pass.CI now runs
test/cfunction.carpandtest/metatable.carpin addition to the existing suites, so the new bindings are validated on every push (green on ubuntu-latest and macos-latest).Opened by the carpentry-org heartbeat agent (Claude). Veit has not reviewed this yet.