Skip to content

Add metatable, raw table access, and userdata support#5

Merged
hellerve merged 2 commits into
masterfrom
claude/metatable-userdata-raw
Jun 14, 2026
Merged

Add metatable, raw table access, and userdata support#5
hellerve merged 2 commits into
masterfrom
claude/metatable-userdata-raw

Conversation

@carpentry-agent

@carpentry-agent carpentry-agent Bot commented Jun 14, 2026

Copy link
Copy Markdown

Summary

Adds three groups of low-level Lua C API bindings to the Lua module, plus a Luax helper:

  • Raw table accessraw-get, raw-set, raw-geti, raw-seti, raw-len for direct table manipulation bypassing metamethods
  • Metatable operationsget-metatable, set-metatable, new-metatable, set-named-metatable for attaching and querying metatables (registry-based and ad-hoc)
  • Userdatanew-userdata for GC-managed memory blocks, check-userdata and test-userdata for typed access, plus TYPE_USERDATA and TYPE_LIGHTUSERDATA constants
  • Luaxmaybe-get-userdata for type-checked userdata reads returning Maybe

These 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.carp and test/metatable.carp in 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.

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.

@carpentry-reviewer carpentry-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_IntegerInt is safe on 64-bit
raw-seti lua_rawseti (Fn [&Lua Int Int] ())
raw-len lua_rawlen deftemplate with (int) cast ✓ — size_tint 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:

  1. The new tests are not run by CI. Until carp -x test/metatable.carp (and ideally carp -x test/cfunction.carp from 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.
  2. Dead code: Remove the unused test-point-add function and its prepare-cfunction from 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.

@hellerve hellerve marked this pull request as ready for review June 14, 2026 22:13
@hellerve hellerve force-pushed the claude/metatable-userdata-raw branch from bcf8fb8 to 7e899ff Compare June 14, 2026 22:17
@hellerve hellerve merged commit b3e7b4a into master Jun 14, 2026
2 checks passed

Copy link
Copy Markdown
Member

Addressed the review:

  • CI now runs the new suitesci.yml executes test/cfunction.carp and test/metatable.carp alongside lua.carp/midlevel.carp. Both jobs are green on ubuntu-latest and macos-latest, so the bindings and the 20 metatable/userdata tests now compile and run in CI (previously lint/format-only).
  • Removed dead code — dropped the unused test-point-add cfunction and its prepare-cfunction call from test/metatable.carp.

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

@hellerve hellerve deleted the claude/metatable-userdata-raw branch June 14, 2026 22:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants