Skip to content

include: reserve the unused shorthand to ucode's own build - #430

Closed
blogic wants to merge 1 commit into
jow-:masterfrom
blogic:unused-macro-guard
Closed

blogic wants to merge 1 commit into
jow-:masterfrom
blogic:unused-macro-guard

Conversation

@blogic

@blogic blogic commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

abb80c6 ("include: add unused macro"). breaks anything that also uses "unused" such as openssl. this patch adds a safeguard causing the macro to only be visible to ucode internally and not leaking into other code it is linked against.

util.h defines `unused` as `__attribute__((unused))` for every file that
includes it, and the name is an ordinary identifier inside GNU attribute
syntax. A module that includes ucode's headers ahead of OpenSSL's
therefore sees `ossl_unused`, itself `__attribute__((unused))`, rewritten
into `__attribute__((__attribute__((unused))))` and stops compiling at
the first DEFINE_STACK_OF in x509v3.h; any other header that spells the
attribute out breaks the same way.

Define the shorthand only when UCODE_INTERNAL is set, which the CMake
build now does for ucode's own translation units, and give localfunc the
reserved __unused__ / __noinline__ spelling so the public header reads
the same with or without the macro.

Fixes: abb80c6 ("include: add `unused` macro")
Signed-off-by: John Crispin <john@phrozen.org>
@jow-

jow- commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Hm, workable approach. Still trying to decide whether I want to introduce private headers instead.

@blogic

blogic commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

yes, that would also be a workable option, once you decide let me know and I can spin a patch and update the PR

jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart but no other
    public header; .c files include the internal header only. Redundant
    includes are dropped from every .c file (verified by compile-testing
    each removal); conditional (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h, program.h, lib.h, module.h, util.h, platform.h
  util.h     deprecated shim (kept for compatibility)

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h, util-macros.h

Key points:
  * The bare 'unused'/'localfunc' macros are isolated in
    internal/util-macros.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h   source creation + line lookup + refcounting
  program.h  program creation + serialization + refcounting
  lib.h      stdlib / native-module authoring API
  module.h   module entry-point contract
  util.h     failsafe allocators, vectors, lists, ALIGN/ARRAY_SIZE
  platform.h system signal table

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h

Key points:
  * The bare 'unused'/'localfunc' macros and __hidden are isolated in
    internal/util.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h   source creation + line lookup + refcounting
  program.h  program creation + serialization + refcounting
  lib.h      stdlib / native-module authoring API
  module.h   module entry-point contract
  util.h     failsafe allocators, vectors, lists, ALIGN/ARRAY_SIZE
  platform.h system signal table

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h

Key points:
  * The bare 'unused'/'localfunc' macros and __hidden are isolated in
    internal/util.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 10, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h   source creation + line lookup + refcounting
  program.h  program creation + serialization + refcounting
  lib.h      stdlib / native-module authoring API
  module.h   module entry-point contract
  util.h     failsafe allocators, vectors, lists, ALIGN/ARRAY_SIZE
  platform.h system signal table

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h

Key points:
  * The bare 'unused'/'localfunc' macros and __hidden are isolated in
    internal/util.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 11, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h   source creation + line lookup + refcounting
  program.h  program creation + serialization + entry function
  lib.h      stdlib / native-module authoring API
  module.h   module entry-point contract
  util.h     failsafe allocators, vectors, lists, ALIGN/ARRAY_SIZE
  platform.h system signal table

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h

Key points:
  * The bare 'unused'/'localfunc' macros and __hidden are isolated in
    internal/util.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * uc_program_entry() is declared in the public ucode/program.h header
    rather than the internal one: the entry function accessor is
    exported from libucode.so and needed by embedding hosts (e.g. the
    ucode CLI) to wrap a program's top-level function in a closure.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 11, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h   source creation + line lookup + refcounting
  program.h  program creation + serialization + refcounting
  lib.h      stdlib / native-module authoring API
  module.h   module entry-point contract
  util.h     failsafe allocators, vectors, lists, ALIGN/ARRAY_SIZE
  platform.h system signal table

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h

Key points:
  * The bare 'unused'/'localfunc' macros and __hidden are isolated in
    internal/util.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
jow- added a commit that referenced this pull request Sep 15, 2026
Split the ucode headers into an installed public API and a private
include/ucode/internal/ tree that is never installed, so downstream
codebases no longer pick up implementation details -- in particular the
bare 'unused' macro that clashed with downstream definitions.

Public (installed) headers:
  ucode.h    umbrella
  types.h    value types + public value ABI + struct uc_vm
  vm.h       VM API (ISA moved out)
  compiler.h uc_compile() + parse configuration
  source.h   source creation + line lookup + refcounting
  program.h  program creation + serialization + refcounting
  lib.h      stdlib / native-module authoring API
  module.h   module entry-point contract
  util.h     failsafe allocators, vectors, lists, ALIGN/ARRAY_SIZE
  platform.h system signal table

Private (include/ucode/internal/, not installed):
  types.h, vm.h, compiler.h, source.h, program.h, chunk.h, vallist.h,
  lexer.h, platform.h, util.h

Key points:
  * The bare 'unused'/'localfunc' macros and __hidden are isolated in
    internal/util.h; the installed util.h no longer defines them.
  * struct uc_vm stays public: downstream (rpcd, uhttpd, uwsd) embeds
    uc_vm_t by value and calls uc_vm_init()/uc_vm_free(), so it cannot
    be opaque. uc_source_t/uc_program_t/uc_function_t are opaque
    forward decls; their full layouts (plus chunk, thread-context,
    object-iterator) live in internal/types.h.
  * The bytecode ISA (__insns, uc_vm_insn_t, I_* opcodes) moves to
    internal/vm.h; compiler state to internal/compiler.h.
  * compile.h is merged into compiler.h (the former is removed); the
    public compilation API lives in a single header.
  * lexer.h moves to internal/ (no downstream users).
  * platform.h is split: the public half keeps UC_SYSTEM_SIGNAL_COUNT
    and uc_system_signal_names[]; byte-order helpers, execvpe(), pipe2(),
    sigtimedwait() and the environ shim move to internal/platform.h.
  * UCODE_BYTECODE_VERSION moves to program.h (it describes the
    serialized bytecode, not the VM).
  * uc_source_get/put and uc_program_get/put become real functions (the
    types are now opaque); the __hidden source/program internals move to
    internal/source.h and internal/program.h.
  * chunk.h and vallist.h move to internal/ (unused downstream).
  * lib.h uc_fn_this reads vm->callframes directly (struct uc_vm is
    public).
  * UC_GC_ENABLED / UC_GC_DEFAULT_INTERVAL introduced; bare GC_* kept as
    deprecated aliases.
  * Internal headers include their own public counterpart (where one
    exists) plus other internal headers; the lexer additionally includes
    the public compiler.h for uc_parse_config_t. .c files include the
    internal header only. Redundant includes are dropped from every .c
    file (verified by compile-testing each removal); conditional
    (#ifdef) includes are preserved.

Fixes: #429
Supersedes: #430
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
@jow-

jow- commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Superseded by #436

@jow- jow- closed this Sep 15, 2026
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