Skip to content

Fix tcc.load(): home_path variable, pcall handle, metatype idempotency - #3

Open
alitrack wants to merge 1 commit into
nucular:masterfrom
alitrack:fix-tcc-load-bugs
Open

Fix tcc.load(): home_path variable, pcall handle, metatype idempotency#3
alitrack wants to merge 1 commit into
nucular:masterfrom
alitrack:fix-tcc-load-bugs

Conversation

@alitrack

@alitrack alitrack commented Aug 7, 2026

Copy link
Copy Markdown

Summary

tcc.load() had three bugs that made it fail with a custom home_path and crash on repeated calls:

  1. tcc.home_path = tccdir (undefined variable) — the provided home_path was silently discarded, so tcc.clib fell back to ffi.load("tcc") and the home-path branch never worked.
  2. clib = pcall(ffi.load(...))pcall returns (ok, result); the boolean ok was stored in tcc.clib instead of the library handle. Any subsequent tcc.clib.tcc_new() then failed with cannot convert 'bool' to 'struct TCCState *'.
  3. Unconditional ffi.metatype("TCCState", tcc.State) — LuaJIT metatypes become protected once set; the second tcc.load() call raised cannot change a protected metatable. Guarded with pcall so tcc.load() is now idempotent.

Also fixed in tcc.new():

  • the body referenced tcc.tccdir (undefined) and the parameter addpaths (typo — the signature is add_paths), so the home-path setup branch never ran even when home_path was set correctly.

Verification

Tested under LuaJIT 2.1 (inside a DuckDB extension host) with a real libtcc.so build:

load1=ok; load2=ok; load3=ok; new=ok; outtype=ok; compile=ok; relocate=ok; getsym=ok; exec=ok
  • 3x tcc.load() with the same home_path — no crash (was: crash on 2nd call)
  • tcc.new()set_output_type(MEMORY)compile_string()relocate()get_symbol() → call — all OK

Three bugs in tcc.load() made it unusable with a home_path and made
repeated calls crash:

1. tcc.home_path was assigned the undefined variable `tccdir` instead of
   the `home_path` parameter, silently discarding the provided path.
2. clib = pcall(ffi.load(...)) stored the *boolean* success flag into
   tcc.clib instead of the library handle, so tcc.clib.tcc_new() failed
   with 'cannot convert bool to struct TCCState *'.
3. ffi.metatype("TCCState", ...) was called unconditionally on every
   load; the second call raises 'cannot change a protected metatable'.
   Guarded with pcall so tcc.load() is idempotent.

Also fixed tcc.new(): the body referenced `tcc.tccdir` (undefined) and
the parameter `addpaths` (typo, missing underscore), so the home path
setup branch never ran.
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.

1 participant