Commit Graph

6 Commits

Author SHA1 Message Date
agra
312d2e90ed refactor(backend): extract scalar instruction handlers into ops.zig (A7.4 slice a)
Move the Constants/Arithmetic/Bitwise/Comparisons/Logical opcode handler
bodies out of emitInst into a new Ops facade in src/backend/llvm/ops.zig.
emitInst's scalar arms now delegate via self.ops().*; the shared infra they
call (mapRef/resolveRef/matchBinOpTypes/emitCmp/emitCmpOrdered/emitStrCmp/
emitStringConstant/reflection + isFloatOrVecFloat/isSignedType) stays on
LLVMEmitter, widened to pub as needed. Pure relocation: zero snapshot churn.
2026-06-03 11:11:10 +03:00
agra
2f7c99fd11 refactor(backend): extract JNI slot cache into ffi_ctors.zig (A7.3 slice 2a)
Move getOrCreateJniSlots (the cls/methodid slot-cache builder) out of
emit_llvm.zig into the FfiCtors backend *LLVMEmitter facade. Behavior-preserving
— self.* -> self.e.* only.

- FfiCtors gains getOrCreateJniSlots (pub). The jni_slots cache + mangleJniKey
  stay on LLVMEmitter; mangleJniKey is widened to pub (the facade calls it back,
  like lazyDeclareCRuntime/emitPrivateCString), and JniSlotPair is widened to pub
  (the facade returns it; the call site consumes it). 1 call site routed via
  ffiCtors().
- emitJniConstructor intentionally NOT moved in this slice: it is emission-heavy
  (resolveRef/mapRef/coerceArg/getRefIRType/extractSlicePtr/loadJniFn/
  emitCStringGlobal — 100+ internal callers for the first two), so relocating it
  would pub-expose the emitter's core value-emission machinery. Consistent with
  A7.2 keeping emitFieldValueGet in emit_llvm.zig. Pending an explicit decision.

Gate: zig build, zig build test, bash tests/run_examples.sh -> 361/0
(JNI anchors 1402/1408/1418/1425 green, no churn).
2026-06-03 10:42:58 +03:00
agra
e8c33bfc00 refactor(backend): extract Obj-C runtime constructors into src/backend/llvm/ffi_ctors.zig (A7.3 slice 1)
Move the Obj-C module-init constructor emission out of emit_llvm.zig into a
FfiCtors backend *LLVMEmitter facade (field `e`). Behavior-preserving relocation
— self.* -> self.e.* only.

- src/backend/llvm/ffi_ctors.zig (FfiCtors): emitObjcSelectorInit (cached SEL
  init), emitObjcClassInit (objc_getClass class-object cache), and
  emitObjcDefinedClassInit (class-pair registration: ivars, method IMP table,
  +alloc/-dealloc IMPs, #implements protocol conformances). Emit-time caches
  (ir_mod.objc_*_cache) + global_map + cached LLVM handles read via self.e.*.
- 3 call sites in LLVMEmitter.emit routed via a new ffiCtors() accessor.
- Shared infra stays in emit_llvm.zig, widened to pub (the facade calls back):
  lazyDeclareCRuntime (11 callers), emitPrivateCString (11 callers),
  injectCtorIntoMain (the moved defined-class ctor's callee). No @llvm.global_ctors
  shape / IMP-table / ivar / protocol-conformance change.

Pins: 1309 (class-method lowering), 1319 (property getter/setter IMPs), 1314
(alloc/dealloc IMPs), 1332 (sret + addMethod) all green.

Gate: zig build, zig build test, bash tests/run_examples.sh -> 361/0 (no churn).
2026-06-03 10:35:15 +03:00
agra
46b874074b refactor(backend): extract reflection metadata + trace frames into src/backend/llvm/reflection.zig (A7.2 reflection)
Move the type/field/tag reflection name-array builders and the error-trace Frame
builders out of emit_llvm.zig into a Reflection backend *LLVMEmitter facade
(field `e`). Behavior-preserving relocation — self.* -> self.e.* only.

- src/backend/llvm/reflection.zig (Reflection): getOrBuildTypeNameArray /
  getOrBuildFieldNameArray / getOrBuildTagNameArray (pub) + emitTraceFrame (pub)
  + buildStringConst (private trace helper). The memoized state
  (type_name_array(_len) / field_name_arrays / tag_name_array / frame_str_cache)
  stays on LLVMEmitter; the facade reads/writes via self.e.*.
- Routed the 5 call sites through a new reflection() accessor (type_name /
  field_name / error_tag_name builtins, emitFailableMainRet's tag-name lookup,
  and the .trace_frame push).
- Kept in emit_llvm.zig per the A6.1 "emission-heavy stays" precedent:
  getFrameStructType (composite-type getter, widened to pub — emitTraceFrame calls
  it back), emitFieldValueGet (field-value reflection EMISSION, not an array
  builder), emitFailableMainRet. getStringStructType/getAnyStructType already pub.
- No reflection-array layout, trace-Frame field order, or linkage change.

Gate: zig build, zig build test, bash tests/run_examples.sh -> 361/0 (reflection
anchors 0030/0118/0517/0520 + trace anchors 1024/1025/1026 all ok, no churn).
2026-06-03 09:29:27 +03:00
agra
f92a743c85 refactor(backend): extract DWARF debug info into src/backend/llvm/debug.zig (A7.2 debug)
Move the DWARF debug-info emission out of emit_llvm.zig into a DebugInfo backend
*LLVMEmitter facade (field `e`). Behavior-preserving relocation — self.* ->
self.e.* only.

- src/backend/llvm/debug.zig (DebugInfo): debugEnabled + diFileFor (private) +
  initDebugInfo / beginFunctionDebug / endFunctionDebug / setInstDebugLocation /
  finalizeDebugInfo (pub). The mutable DI state (di_builder/di_cu/di_files/
  di_scope/current_func_file) + the shared source map (import_sources/main_file)
  stay on LLVMEmitter; the facade reads/writes them via self.e.*.
- Routed the 5 pass-order call sites in LLVMEmitter.emit (init/finalize/
  begin/end/setInstDebugLocation) through a new debugInfo() accessor.
- setDebugContext stays on LLVMEmitter (shared-state setter; callers in main.zig/
  core.zig/test). sourceForFile stays on LLVMEmitter and is widened to pub — it is
  shared with reflection's trace-frame emission (emitTraceFrame), not debug-only.
- No DI logic / module-flag / DWARF-version / scope-line change.

Gate: zig build, zig build test, bash tests/run_examples.sh -> 361/0 (no churn).
2026-06-03 09:22:40 +03:00
agra
71f1cb2fb0 refactor(backend): extract LLVM type/ABI lowering into src/backend/llvm/ (A7.1 step 2)
Move the LLVM type-mapping and C-ABI coercion helpers out of emit_llvm.zig into
the first src/backend/llvm/ modules. Behavior-preserving relocation — the only
rewrites are module plumbing and self.* -> self.e.* facade access.

- src/backend/llvm/types.zig (TypeLowering): toLLVMType + toLLVMTypeInfo.
- src/backend/llvm/abi.zig (AbiLowering): abiCoerceParamType / abiCoerceParamTypeEx
  / needsByval / materializeByvalArg.
- Both are backend *LLVMEmitter facades (field `e`) — the backend analogue of the
  IR-side *Lowering facades, NOT a *Lowering facade. They reach the cached LLVM
  handles, IR type table, module data layout, builder, and the memoizing
  composite-type getters via self.e.*.
- LLVMEmitter stays the facade: toLLVMType (~97 callers) + abiCoerceParamType /
  abiCoerceParamTypeEx / needsByval / materializeByvalArg kept as thin wrappers
  delegating through new typeLowering()/abiLowering() accessors. Zero caller
  churn. toLLVMTypeInfo deleted (sole caller moved).
- Widened getStringStructType / getAnyStructType / getClosureStructType to pub
  (the moved toLLVMTypeInfo calls them back; their memoization stays on
  LLVMEmitter). verifySizes stays in emit_llvm.zig (size-assertion pass, not type/
  ABI lowering). No ABI/type logic, branch order, diagnostic text, or snapshot
  changed. Circular import (emit_llvm <-> backend/llvm) resolves via the pointer
  facade.

Gate: zig build, zig build test, bash tests/run_examples.sh -> 361/0
(1202 .ir + the 2 ABI unit tests unchanged, no churn).
2026-06-03 09:10:27 +03:00