commit 96469fa516e26b1e76409a026678a264cb06a928 parent 068c1134505dfa9b6fcfa4de52f918f9a973e797 Author: Ryan Sepassi <rsepassi@gmail.com> Date: Tue, 19 May 2026 15:13:50 -0700 Clean up public API: merge object headers, drop redundant accessors, use bool - Merge objmodel.h and objbuild.h into object.h (model/builder/reader in one place; downstream now includes a single header). - Replace per-field compiler accessors with cfree_compiler_context() returning const CfreeContext*; per-field calls become ctx->heap etc. - Convert int/uint8_t boolean fields to bool via stdbool.h (big_endian, debug_info, abi_variadic, warnings_are_errors, inlined, whole_archive, gc_sections, pie, allow_undefined). Diffstat:
28 files changed, 205 insertions(+), 237 deletions(-)
diff --git a/include/cfree/cg.h b/include/cfree/cg.h @@ -2,7 +2,7 @@ #define CFREE_PUBLIC_CG_H #include <cfree/core.h> -#include <cfree/objbuild.h> +#include <cfree/object.h> /* ============================================================ * Handles @@ -104,7 +104,7 @@ typedef struct CfreeCgFuncSig { const CfreeCgFuncParam* params; uint32_t nparams; CfreeCgCallConv call_conv; - int abi_variadic; + bool abi_variadic; } CfreeCgFuncSig; typedef struct CfreeCgField { diff --git a/include/cfree/compile.h b/include/cfree/compile.h @@ -2,7 +2,7 @@ #define CFREE_COMPILE_H #include <cfree/core.h> -#include <cfree/objbuild.h> +#include <cfree/object.h> /* * Source compiler embedding API. @@ -43,7 +43,7 @@ typedef struct CfreePreprocessOptions { } CfreePreprocessOptions; typedef struct CfreeDiagnosticOptions { - int warnings_are_errors; + bool warnings_are_errors; uint32_t max_errors; /* 0 means unlimited */ } CfreeDiagnosticOptions; diff --git a/include/cfree/core.h b/include/cfree/core.h @@ -12,6 +12,7 @@ */ #include <stdarg.h> +#include <stdbool.h> #include <stddef.h> #include <stdint.h> @@ -101,7 +102,7 @@ typedef struct CfreeTarget { CfreeObjFmt obj; uint8_t ptr_size; uint8_t ptr_align; - uint8_t big_endian; + bool big_endian; uint8_t pic; /* CfreePic */ uint8_t code_model; /* CfreeCodeModel */ } CfreeTarget; @@ -131,8 +132,8 @@ typedef struct CfreePathPrefixMap { } CfreePathPrefixMap; typedef struct CfreeCodeOptions { - int opt_level; /* 0 direct, 1 minimal, 2 full */ - int debug_info; /* nonzero emits source/debug records when supported */ + int opt_level; /* 0 direct, 1 minimal, 2 full */ + bool debug_info; /* emit source/debug records when supported */ uint64_t epoch; /* reproducible timestamp seed; 0 means no timestamp */ const CfreePathPrefixMap *path_map; uint32_t npath_map; @@ -224,11 +225,7 @@ CfreeStatus cfree_compiler_new(CfreeTarget, const CfreeContext *, void cfree_compiler_free(CfreeCompiler *); CfreeTarget cfree_compiler_target(CfreeCompiler *); -CfreeHeap *cfree_compiler_heap(CfreeCompiler *); -const CfreeFileIO *cfree_compiler_file_io(CfreeCompiler *); -CfreeDiagSink *cfree_compiler_diag_sink(CfreeCompiler *); -int64_t cfree_compiler_now(CfreeCompiler *); -CfreeContext cfree_compiler_context(CfreeCompiler *); +const CfreeContext *cfree_compiler_context(CfreeCompiler *); const char *cfree_compiler_file_name(CfreeCompiler *, uint32_t file_id); diff --git a/include/cfree/dwarf.h b/include/cfree/dwarf.h @@ -44,7 +44,7 @@ typedef struct CfreeDwarfSubprogram { const char *decl_file; uint32_t decl_line; const CfreeDwarfType *return_type; - uint8_t inlined; + bool inlined; } CfreeDwarfSubprogram; CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo *, uint64_t pc, diff --git a/include/cfree/jit.h b/include/cfree/jit.h @@ -3,7 +3,6 @@ #include <cfree/arch.h> #include <cfree/object.h> -#include <cfree/objbuild.h> /* * JIT image API. diff --git a/include/cfree/link.h b/include/cfree/link.h @@ -2,7 +2,7 @@ #define CFREE_LINK_H #include <cfree/core.h> -#include <cfree/objbuild.h> +#include <cfree/object.h> /* * Linker API. @@ -126,7 +126,7 @@ typedef enum CfreeLinkMode { typedef struct CfreeLinkArchiveInput { CfreeBytes bytes; uint8_t link_mode; /* CfreeLinkMode */ - uint8_t whole_archive; + bool whole_archive; uint8_t group_id; uint8_t pad; } CfreeLinkArchiveInput; @@ -149,8 +149,8 @@ typedef struct CfreeLinkInputs { typedef struct CfreeExeLinkOptions { CfreeLinkInputs inputs; - int gc_sections; - int pie; + bool gc_sections; + bool pie; const char *interp_path; } CfreeExeLinkOptions; @@ -163,13 +163,13 @@ typedef struct CfreeSharedLinkOptions { uint32_t nrunpaths; const char *const *exports; uint32_t nexports; - int allow_undefined; - int gc_sections; + bool allow_undefined; + bool gc_sections; } CfreeSharedLinkOptions; typedef struct CfreeJitLinkOptions { CfreeLinkInputs inputs; - int gc_sections; + bool gc_sections; CfreeExternResolver extern_resolver; void *extern_resolver_user; } CfreeJitLinkOptions; diff --git a/include/cfree/objbuild.h b/include/cfree/objbuild.h @@ -1,82 +0,0 @@ -#ifndef CFREE_OBJBUILD_H -#define CFREE_OBJBUILD_H - -#include <cfree/objmodel.h> - -/* - * Format-neutral relocatable object builder. - * - * This is for embedders that want to synthesize object files directly without - * going through the CG API. It is intentionally lower level than cfree/cg.h: - * callers choose sections, symbol bindings, raw bytes, and target relocation - * kinds themselves. - */ - -typedef struct CfreeObjSectionDesc { - CfreeSym name; - CfreeSecKind kind; - uint32_t flags; /* CfreeSecFlag */ - uint32_t align; /* 0 means default; otherwise power of two */ - uint32_t entsize; /* 0 means none */ -} CfreeObjSectionDesc; - -typedef struct CfreeObjSymbolDesc { - CfreeSym name; - CfreeSymBind bind; - CfreeSymKind kind; - CfreeObjSection section; /* CFREE_SECTION_NONE for undef/abs/common */ - uint64_t value; - uint64_t size; -} CfreeObjSymbolDesc; - -typedef struct CfreeObjRelocDesc { - CfreeObjSection section; - uint64_t offset; - CfreeRelocKind kind; - CfreeObjSymbol symbol; - int64_t addend; -} CfreeObjRelocDesc; - -CfreeStatus cfree_obj_builder_new(CfreeCompiler *, CfreeObjBuilder **out); -void cfree_obj_builder_free(CfreeObjBuilder *); - -CfreeStatus cfree_obj_builder_section(CfreeObjBuilder *, - const CfreeObjSectionDesc *, - CfreeObjSection *out); -CfreeStatus cfree_obj_builder_section_group(CfreeObjBuilder *, CfreeObjSection, - CfreeObjGroup); - -CfreeStatus cfree_obj_builder_pos(CfreeObjBuilder *, CfreeObjSection, - uint64_t *out); -CfreeStatus cfree_obj_builder_align(CfreeObjBuilder *, CfreeObjSection, - uint32_t align, uint64_t *new_pos_out); -CfreeStatus cfree_obj_builder_write(CfreeObjBuilder *, CfreeObjSection, - const void *data, size_t n); -CfreeStatus cfree_obj_builder_reserve(CfreeObjBuilder *, CfreeObjSection, - size_t n, void **out); -CfreeStatus cfree_obj_builder_reserve_bss(CfreeObjBuilder *, CfreeObjSection, - uint64_t size, uint32_t align); -CfreeStatus cfree_obj_builder_patch(CfreeObjBuilder *, CfreeObjSection, - uint64_t offset, const void *data, - size_t n); - -CfreeStatus cfree_obj_builder_symbol(CfreeObjBuilder *, - const CfreeObjSymbolDesc *, - CfreeObjSymbol *out); -CfreeStatus cfree_obj_builder_symbol_define(CfreeObjBuilder *, CfreeObjSymbol, - CfreeObjSection, uint64_t value, - uint64_t size); -CfreeStatus cfree_obj_builder_reloc(CfreeObjBuilder *, - const CfreeObjRelocDesc *); - -CfreeStatus cfree_obj_builder_group(CfreeObjBuilder *, CfreeSym name, - CfreeObjSymbol signature, uint32_t flags, - CfreeObjGroup *out); -CfreeStatus cfree_obj_builder_group_add_section(CfreeObjBuilder *, - CfreeObjGroup, - CfreeObjSection); - -CfreeStatus cfree_obj_builder_finalize(CfreeObjBuilder *); -CfreeStatus cfree_obj_builder_emit(CfreeObjBuilder *, CfreeWriter *); - -#endif diff --git a/include/cfree/object.h b/include/cfree/object.h @@ -1,16 +1,167 @@ #ifndef CFREE_OBJECT_H #define CFREE_OBJECT_H -#include <cfree/objmodel.h> +#include <cfree/core.h> /* - * Object-file detection and read-only inspection. + * Object files: format-neutral model, builder, and read-only inspection. * - * Object readers keep the caller's byte storage borrowed for the lifetime of - * CfreeObjFile. Strings returned by iterators are owned by the object file and + * The model types (CfreeSecKind, CfreeObjSymInfo, CfreeObjReloc, ...) are + * shared by the builder and reader, and are also referenced by other + * components: codegen (cg.h), link (link.h), JIT image inspection (jit.h), + * and disassembly (disasm.h). + * + * The builder is format-neutral and lower level than cg.h: callers pick + * sections, symbol bindings, raw bytes, and target relocation kinds. + * + * The reader keeps the caller's byte storage borrowed for the lifetime of + * the CfreeObjFile. Strings returned by iterators are owned by the file and * remain valid until cfree_obj_free. */ +/* ============================================================ + * Model + * ============================================================ */ + +#define CFREE_SECTION_NONE UINT32_MAX +#define CFREE_OBJ_SYMBOL_NONE UINT32_MAX +#define CFREE_OBJ_GROUP_NONE UINT32_MAX + +typedef uint32_t CfreeObjSection; +typedef uint32_t CfreeObjSymbol; +typedef uint32_t CfreeObjGroup; + +typedef enum CfreeSecKind { + CFREE_SEC_TEXT, + CFREE_SEC_RODATA, + CFREE_SEC_DATA, + CFREE_SEC_BSS, + CFREE_SEC_DEBUG, + CFREE_SEC_OTHER, +} CfreeSecKind; + +typedef enum CfreeSecFlag { + CFREE_SF_EXEC = 1u << 0, + CFREE_SF_WRITE = 1u << 1, + CFREE_SF_ALLOC = 1u << 2, + CFREE_SF_TLS = 1u << 3, + CFREE_SF_MERGE = 1u << 4, + CFREE_SF_STRINGS = 1u << 5, +} CfreeSecFlag; + +typedef enum CfreeObjGroupFlag { + CFREE_OBJ_GROUP_COMDAT = 1u << 0, +} CfreeObjGroupFlag; + +typedef struct CfreeRelocKind { + CfreeArchKind arch; + CfreeObjFmt obj_fmt; + uint32_t code; +} CfreeRelocKind; + +typedef struct CfreeObjSecInfo { + const char *name; + CfreeSecKind kind; + uint32_t flags; /* CfreeSecFlag */ + uint64_t size; /* bytes; BSS uses virtual size */ + uint32_t align; /* power of two; 1 means no special alignment */ + uint32_t entsize; /* section entry size, or 0 */ +} CfreeObjSecInfo; + +typedef struct CfreeObjSymInfo { + const char *name; + CfreeSymBind bind; + CfreeSymKind kind; + CfreeObjSection section; + uint64_t value; + uint64_t size; +} CfreeObjSymInfo; + +typedef struct CfreeObjReloc { + CfreeObjSection section; + uint64_t offset; + CfreeObjSymbol sym; + const char *sym_name; + int64_t addend; + CfreeRelocKind kind; + const char *kind_name; /* diagnostic spelling, when known */ +} CfreeObjReloc; + +/* ============================================================ + * Builder + * ============================================================ */ + +typedef struct CfreeObjSectionDesc { + CfreeSym name; + CfreeSecKind kind; + uint32_t flags; /* CfreeSecFlag */ + uint32_t align; /* 0 means default; otherwise power of two */ + uint32_t entsize; /* 0 means none */ +} CfreeObjSectionDesc; + +typedef struct CfreeObjSymbolDesc { + CfreeSym name; + CfreeSymBind bind; + CfreeSymKind kind; + CfreeObjSection section; /* CFREE_SECTION_NONE for undef/abs/common */ + uint64_t value; + uint64_t size; +} CfreeObjSymbolDesc; + +typedef struct CfreeObjRelocDesc { + CfreeObjSection section; + uint64_t offset; + CfreeRelocKind kind; + CfreeObjSymbol symbol; + int64_t addend; +} CfreeObjRelocDesc; + +CfreeStatus cfree_obj_builder_new(CfreeCompiler *, CfreeObjBuilder **out); +void cfree_obj_builder_free(CfreeObjBuilder *); + +CfreeStatus cfree_obj_builder_section(CfreeObjBuilder *, + const CfreeObjSectionDesc *, + CfreeObjSection *out); +CfreeStatus cfree_obj_builder_section_group(CfreeObjBuilder *, CfreeObjSection, + CfreeObjGroup); + +CfreeStatus cfree_obj_builder_pos(CfreeObjBuilder *, CfreeObjSection, + uint64_t *out); +CfreeStatus cfree_obj_builder_align(CfreeObjBuilder *, CfreeObjSection, + uint32_t align, uint64_t *new_pos_out); +CfreeStatus cfree_obj_builder_write(CfreeObjBuilder *, CfreeObjSection, + const void *data, size_t n); +CfreeStatus cfree_obj_builder_reserve(CfreeObjBuilder *, CfreeObjSection, + size_t n, void **out); +CfreeStatus cfree_obj_builder_reserve_bss(CfreeObjBuilder *, CfreeObjSection, + uint64_t size, uint32_t align); +CfreeStatus cfree_obj_builder_patch(CfreeObjBuilder *, CfreeObjSection, + uint64_t offset, const void *data, + size_t n); + +CfreeStatus cfree_obj_builder_symbol(CfreeObjBuilder *, + const CfreeObjSymbolDesc *, + CfreeObjSymbol *out); +CfreeStatus cfree_obj_builder_symbol_define(CfreeObjBuilder *, CfreeObjSymbol, + CfreeObjSection, uint64_t value, + uint64_t size); +CfreeStatus cfree_obj_builder_reloc(CfreeObjBuilder *, + const CfreeObjRelocDesc *); + +CfreeStatus cfree_obj_builder_group(CfreeObjBuilder *, CfreeSym name, + CfreeObjSymbol signature, uint32_t flags, + CfreeObjGroup *out); +CfreeStatus cfree_obj_builder_group_add_section(CfreeObjBuilder *, + CfreeObjGroup, + CfreeObjSection); + +CfreeStatus cfree_obj_builder_finalize(CfreeObjBuilder *); +CfreeStatus cfree_obj_builder_emit(CfreeObjBuilder *, CfreeWriter *); + +/* ============================================================ + * Reader / inspection + * ============================================================ */ + typedef enum CfreeBinFmt { CFREE_BIN_UNKNOWN = 0, CFREE_BIN_AR, diff --git a/include/cfree/objmodel.h b/include/cfree/objmodel.h @@ -1,75 +0,0 @@ -#ifndef CFREE_OBJMODEL_H -#define CFREE_OBJMODEL_H - -#include <cfree/core.h> - -/* - * Format-neutral object model shared by object builders, readers, linkers, - * disassemblers, and JIT image inspection. - */ - -#define CFREE_SECTION_NONE UINT32_MAX -#define CFREE_OBJ_SYMBOL_NONE UINT32_MAX -#define CFREE_OBJ_GROUP_NONE UINT32_MAX - -typedef uint32_t CfreeObjSection; -typedef uint32_t CfreeObjSymbol; -typedef uint32_t CfreeObjGroup; - -typedef enum CfreeSecKind { - CFREE_SEC_TEXT, - CFREE_SEC_RODATA, - CFREE_SEC_DATA, - CFREE_SEC_BSS, - CFREE_SEC_DEBUG, - CFREE_SEC_OTHER, -} CfreeSecKind; - -typedef enum CfreeSecFlag { - CFREE_SF_EXEC = 1u << 0, - CFREE_SF_WRITE = 1u << 1, - CFREE_SF_ALLOC = 1u << 2, - CFREE_SF_TLS = 1u << 3, - CFREE_SF_MERGE = 1u << 4, - CFREE_SF_STRINGS = 1u << 5, -} CfreeSecFlag; - -typedef enum CfreeObjGroupFlag { - CFREE_OBJ_GROUP_COMDAT = 1u << 0, -} CfreeObjGroupFlag; - -typedef struct CfreeRelocKind { - CfreeArchKind arch; - CfreeObjFmt obj_fmt; - uint32_t code; -} CfreeRelocKind; - -typedef struct CfreeObjSecInfo { - const char *name; - CfreeSecKind kind; - uint32_t flags; /* CfreeSecFlag */ - uint64_t size; /* bytes; BSS uses virtual size */ - uint32_t align; /* power of two; 1 means no special alignment */ - uint32_t entsize; /* section entry size, or 0 */ -} CfreeObjSecInfo; - -typedef struct CfreeObjSymInfo { - const char *name; - CfreeSymBind bind; - CfreeSymKind kind; - CfreeObjSection section; - uint64_t value; - uint64_t size; -} CfreeObjSymInfo; - -typedef struct CfreeObjReloc { - CfreeObjSection section; - uint64_t offset; - CfreeObjSymbol sym; - const char *sym_name; - int64_t addend; - CfreeRelocKind kind; - const char *kind_name; /* diagnostic spelling, when known */ -} CfreeObjReloc; - -#endif diff --git a/lang/c/c.h b/lang/c/c.h @@ -21,7 +21,7 @@ #include <cfree/compile.h> #include <cfree/core.h> #include <cfree/frontend.h> -#include <cfree/objbuild.h> +#include <cfree/object.h> CfreeStatus cfree_c_compile(CfreeCompiler*, const CfreeFrontendCompileOptions*, const CfreeSourceInput*, CfreeObjBuilder*); diff --git a/lang/c/c_support.h b/lang/c/c_support.h @@ -36,7 +36,7 @@ typedef struct Pool { } Pool; static inline Pool* c_pool_new(Compiler* c) { - Heap* h = cfree_compiler_heap(c); + Heap* h = cfree_compiler_context(c)->heap; Pool* p = h ? (Pool*)h->alloc(h, sizeof(*p), _Alignof(Pool)) : NULL; if (!p) return NULL; p->c = c; @@ -52,7 +52,7 @@ static inline Pool* c_pool_new(Compiler* c) { static inline void c_pool_free(Pool* p) { Heap* h; if (!p) return; - h = cfree_compiler_heap(p->c); + h = cfree_compiler_context(p->c)->heap; cfree_arena_free(p->arena); if (h) h->free(h, p, sizeof(*p)); } diff --git a/lang/c/decl/decl.c b/lang/c/decl/decl.c @@ -31,7 +31,7 @@ struct DeclTable { #define DECL_INITIAL_CAP 16u static void decls_grow(DeclTable* t, u32 want) { - Heap* h = cfree_compiler_heap(t->c); + Heap* h = cfree_compiler_context(t->c)->heap; u32 cap = t->cap; Decl* nb; if (cap >= want) return; @@ -46,7 +46,7 @@ static void decls_grow(DeclTable* t, u32 want) { } DeclTable* decl_new(Compiler* c, CfreeCg* cg) { - Heap* h = cfree_compiler_heap(c); + Heap* h = cfree_compiler_context(c)->heap; DeclTable* t = (DeclTable*)h->alloc(h, sizeof(DeclTable), _Alignof(DeclTable)); memset(t, 0, sizeof *t); @@ -61,7 +61,7 @@ DeclTable* decl_new(Compiler* c, CfreeCg* cg) { void decl_free(DeclTable* t) { Heap* h; if (!t) return; - h = cfree_compiler_heap(t->c); + h = cfree_compiler_context(t->c)->heap; if (t->slots) h->free(h, t->slots, sizeof(Decl) * t->cap); h->free(h, t, sizeof(*t)); } diff --git a/lang/c/lex/lex.c b/lang/c/lex/lex.c @@ -123,7 +123,7 @@ static SrcLoc lex_here(const Lexer* l) { Lexer* lex_open_mem(Compiler* c, const char* name, const char* src, size_t len) { - Heap* h = (Heap*)cfree_compiler_heap(c); + Heap* h = (Heap*)cfree_compiler_context(c)->heap; Lexer* l = (Lexer*)h->alloc(h, sizeof(*l), _Alignof(Lexer)); if (!l) return NULL; memset(l, 0, sizeof(*l)); diff --git a/lang/c/parse/parse.c b/lang/c/parse/parse.c @@ -113,7 +113,7 @@ static Tok fuse_string_lits(Parser* p, Tok a, Tok b) { size_t a_content_len, b_content_len; size_t out_pfx_len; size_t out_len; - Heap* h = cfree_compiler_heap(p->c); + Heap* h = cfree_compiler_context(p->c)->heap; char* buf; size_t k = 0; Tok out; diff --git a/lang/c/parse/parse_expr.c b/lang/c/parse/parse_expr.c @@ -383,7 +383,7 @@ u8* decode_string_literal(Parser* p, const Tok* t, size_t* nlen_out) { size_t len = 0; const char* s = pool_str(p->pool, t->spelling, &len); size_t i = 0; - Heap* h = cfree_compiler_heap(p->c); + Heap* h = cfree_compiler_context(p->c)->heap; u8* buf; size_t k = 0; const Type* elem_ty; @@ -1794,7 +1794,7 @@ static void parse_primary(Parser* p) { } size_t nlen = 0; const char* fn_name = pool_str(p->pool, p->cur_func_name, &nlen); - Heap* h = cfree_compiler_heap(p->c); + Heap* h = cfree_compiler_context(p->c)->heap; u8* bytes = (u8*)h->alloc(h, nlen + 1u, 1u); for (size_t i = 0; i < nlen; ++i) bytes[i] = (u8)fn_name[i]; bytes[nlen] = 0; @@ -1850,7 +1850,7 @@ static void parse_primary(Parser* p) { const Type* elem_ty = string_literal_elem_type(p, &t); u32 elem_size = c_abi_sizeof(p->abi, elem_ty); ObjSymId sym = emit_string_literal_to_rodata(p, bytes, n, elem_ty); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); advance(p); { const Type* arr_ty = diff --git a/lang/c/parse/parse_init.c b/lang/c/parse/parse_init.c @@ -255,7 +255,7 @@ static void init_string_at(Parser* p, FrameSlot slot, const Type* arr_ty, cg_store(p->cg); cg_drop(p->cg); } - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); advance(p); /* consume TOK_STR */ } @@ -770,7 +770,7 @@ static void parse_static_string_at(Parser* p, u8* buf, u32 buflen, u32 offset, if (offset + (u32)copy_bytes > buflen) perr(p, "string initializer overflows object"); memcpy(buf + offset, bytes, copy_bytes); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); advance(p); } @@ -985,7 +985,7 @@ static int try_parse_static_address_const(Parser* p, CStaticConst* out) { u8* bytes = decode_string_literal(p, &t, &n); const Type* elem_ty = string_literal_elem_type(p, &t); ObjSymId str_sym = emit_string_literal_to_rodata(p, bytes, n, elem_ty); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); advance(p); out->kind = C_STATIC_CONST_ADDR; out->target = str_sym; diff --git a/lang/c/parse/parse_stmt.c b/lang/c/parse/parse_stmt.c @@ -429,7 +429,7 @@ static const char* parse_asm_str(Parser* p, const char* what) { bytes = decode_string_literal(p, &t, &nlen); if (nlen > 0) nlen -= 1; s = pool_intern(p->pool, (const char*)bytes, nlen); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); return pool_str(p->pool, s, NULL); } diff --git a/lang/c/parse/parse_type.c b/lang/c/parse/parse_type.c @@ -212,7 +212,7 @@ static void parse_attr_args(Parser* p, Attr* a, AttrArgShape shape, u8* bytes = decode_string_literal(p, &t, &nlen); u32 ilen = (nlen > 0) ? (u32)(nlen - 1) : 0; a->v.sym = pool_intern(p->pool, (const char*)bytes, ilen); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); } a->nargs = 1; advance(p); @@ -1527,7 +1527,7 @@ const Type* complete_incomplete_array(Parser* p, const Type* ty) { size_t n = 0; u8* bytes = decode_string_literal(p, &t, &n); u32 elem_size = c_abi_sizeof(p->abi, elem); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); return type_array(p->pool, elem, elem_size ? (u32)(n / elem_size) : 0, /*incomplete=*/0); } @@ -1541,7 +1541,7 @@ const Type* complete_incomplete_array(Parser* p, const Type* ty) { size_t n = 0; u8* bytes = decode_string_literal(p, &t, &n); u32 elem_size = c_abi_sizeof(p->abi, elem); - cfree_compiler_heap(p->c)->free(cfree_compiler_heap(p->c), bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); cnt = elem_size ? (u32)(n / elem_size) : 0; } replay_rewind(p); diff --git a/lang/c/pp/pp.c b/lang/c/pp/pp.c @@ -270,7 +270,7 @@ static void compute_date_time(Pp* pp) { "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; char date[24]; char tm[16]; - int64_t t = cfree_compiler_now(pp->c); + int64_t t = cfree_compiler_context(pp->c)->now; PpYMD ymd; if (t < 0) { pp->val_date_str = pool_intern_cstr(pp->pool, "\"??? ?? ????\""); @@ -500,7 +500,7 @@ static void pp_register_target_predefined(Pp* pp) { } Pp* pp_new(Compiler* c) { - Heap* h = (Heap*)cfree_compiler_heap(c); + Heap* h = (Heap*)cfree_compiler_context(c)->heap; Pp* pp = (Pp*)h->alloc(h, sizeof(*pp), _Alignof(Pp)); if (!pp) return NULL; memset(pp, 0, sizeof(*pp)); diff --git a/lang/c/pp/pp_directive.c b/lang/c/pp/pp_directive.c @@ -584,7 +584,7 @@ static int try_open_include(Pp* pp, const char* path, const u8** data_out, u8* buf; memset(&fd, 0, sizeof(fd)); - io = cfree_compiler_file_io(pp->c); + io = cfree_compiler_context(pp->c)->file_io; if (!io || !io->read_all) { compiler_panic(pp->c, (SrcLoc){0, 0, 0}, "#include: env.file_io is not configured"); @@ -1030,7 +1030,7 @@ static void directive_message(Pp* pp, const Tok* line, u32 n, CharBuf* cb) { } static void pp_warn(Pp* pp, SrcLoc loc, const char* fmt, ...) { - CfreeDiagSink* sink = cfree_compiler_diag_sink(pp->c); + CfreeDiagSink* sink = cfree_compiler_context(pp->c)->diag; va_list ap; if (sink && sink->emit) { va_start(ap, fmt); diff --git a/lang/c/pp/pp_priv.h b/lang/c/pp/pp_priv.h @@ -163,7 +163,7 @@ struct Pp { * Allocation helpers (defined in pp.c, used everywhere) * ============================================================ */ -static inline Heap* pp_heap(Pp* pp) { return cfree_compiler_heap(pp->c); } +static inline Heap* pp_heap(Pp* pp) { return cfree_compiler_context(pp->c)->heap; } static inline void* pp_xrealloc(Pp* pp, void* p, size_t old_n, size_t new_n, size_t align) { diff --git a/lang/toy/parser_core.c b/lang/toy/parser_core.c @@ -46,7 +46,7 @@ void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg, p->cap_goto_targets = 0; p->cur_fn_ret = toy_builtin_type(p, CFREE_CG_BUILTIN_VOID); p->cur_fn_ret_toy = toy_type_from_cg(p, p->cur_fn_ret); - p->diag = cfree_compiler_diag_sink(c); + p->diag = cfree_compiler_context(c)->diag; p->has_error = 0; p->static_counter = 0; p->expr_island_mask = 0; diff --git a/lang/wasm/wasm.c b/lang/wasm/wasm.c @@ -8274,7 +8274,7 @@ static void wasm_encode(CfreeCompiler* c, const WasmModule* m, CfreeWriter* out) { static const uint8_t magic[] = {0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00}; - CfreeHeap* h = cfree_compiler_heap(c); + CfreeHeap* h = cfree_compiler_context(c)->heap; out->write(out, magic, sizeof magic); for (uint32_t i = 0; i < m->ncustoms; ++i) encode_custom(h, out, &m->customs[i]); @@ -8317,7 +8317,7 @@ CfreeStatus cfree_wasm_compile(CfreeCompiler* c, WasmModule m; if (!c || !opts || !input || !out) return CFREE_INVALID; (void)opts->language_options; /* wasm frontend has no per-language options */ - wasm_module_init(&m, cfree_compiler_heap(c)); + wasm_module_init(&m, cfree_compiler_context(c)->heap); wasm_parse_any(c, &input->bytes, &m); wasm_emit_cg(c, &opts->code, out, &m); wasm_module_free(&m); @@ -8331,7 +8331,7 @@ void cfree_wasm_register(CfreeCompiler* c) { int cfree_wasm_wat_to_wasm(CfreeCompiler* c, const CfreeBytes* input, CfreeWriter* out) { WasmModule m; - wasm_module_init(&m, cfree_compiler_heap(c)); + wasm_module_init(&m, cfree_compiler_context(c)->heap); wat_parse_module(c, input, &m); wasm_validate(&m, c); wasm_encode(c, &m, out); diff --git a/src/api/lifecycle.c b/src/api/lifecycle.c @@ -38,27 +38,8 @@ CfreeTarget cfree_compiler_target(CfreeCompiler* c) { return c->target; } -CfreeContext cfree_compiler_context(CfreeCompiler* c) { - CfreeContext z; - memset(&z, 0, sizeof z); - if (!c || !c->ctx) return z; - return *c->ctx; -} - -CfreeHeap* cfree_compiler_heap(CfreeCompiler* c) { - return (c && c->ctx) ? c->ctx->heap : NULL; -} - -const CfreeFileIO* cfree_compiler_file_io(CfreeCompiler* c) { - return (c && c->ctx) ? c->ctx->file_io : NULL; -} - -CfreeDiagSink* cfree_compiler_diag_sink(CfreeCompiler* c) { - return (c && c->ctx) ? c->ctx->diag : NULL; -} - -int64_t cfree_compiler_now(CfreeCompiler* c) { - return (c && c->ctx) ? c->ctx->now : -1; +const CfreeContext* cfree_compiler_context(CfreeCompiler* c) { + return (c && c->ctx) ? c->ctx : NULL; } const char* cfree_compiler_file_name(CfreeCompiler* c, uint32_t file_id) { diff --git a/src/api/objbuilder.c b/src/api/objbuilder.c @@ -1,6 +1,6 @@ /* Public CfreeObjBuilder API: thin adapter over the internal obj_* surface. */ -#include <cfree/objbuild.h> +#include <cfree/object.h> #include <string.h> #include "core/core.h" diff --git a/src/core/core.h b/src/core/core.h @@ -3,7 +3,7 @@ #include <cfree/compile.h> #include <cfree/core.h> -#include <cfree/objmodel.h> +#include <cfree/object.h> #include <cfree/source.h> #include <setjmp.h> #include <stdarg.h> diff --git a/src/link/link.c b/src/link/link.c @@ -224,15 +224,13 @@ LinkInputId link_add_archive_bytes(Linker* l, const char* name, const u8* data, CfreeArMember mem; LinkArchive* ar; u32 n; - CfreeContext ctx; if (!l || !data || !len) return LINK_INPUT_NONE; in_arc.name = name; in_arc.data = data; in_arc.len = len; - ctx = cfree_compiler_context(l->c); - if (cfree_ar_iter_new(&ctx, &in_arc, &it) != CFREE_OK || !it) + if (cfree_ar_iter_new(cfree_compiler_context(l->c), &in_arc, &it) != CFREE_OK || !it) compiler_panic(l->c, no_loc(), "link_add_archive_bytes: '%s' is not a valid ar archive", name ? name : "(unnamed)"); @@ -266,7 +264,7 @@ LinkInputId link_add_archive_bytes(Linker* l, const char* name, const u8* data, * for us, so every member returned here is a real object file. * Format is detected per-member so a single archive could in * principle hold mixed formats (in practice it never does). */ - if (cfree_ar_iter_new(&ctx, &in_arc, &it) != CFREE_OK || !it) + if (cfree_ar_iter_new(cfree_compiler_context(l->c), &in_arc, &it) != CFREE_OK || !it) compiler_panic(l->c, no_loc(), "link_add_archive_bytes: ar_iter_init failed on '%s' " "second pass", diff --git a/src/link/link_jit.c b/src/link/link_jit.c @@ -10,7 +10,6 @@ #include <cfree/core.h> #include <cfree/jit.h> -#include <cfree/objbuild.h> #include <cfree/object.h> #include <string.h>