Skip to content

Claude/upgrade ape c library mm z gd - #614

Merged
staalmannen merged 5 commits into
mainfrom
claude/upgrade-ape-c-library-mmZGd
Oct 8, 2026
Merged

staalmannen merged 5 commits into
mainfrom
claude/upgrade-ape-c-library-mmZGd

Conversation

@staalmannen

Copy link
Copy Markdown
Owner

No description provided.

claude added 5 commits October 8, 2026 03:57
The link line now ends `.../amd64/lib/ape/libedg.a' and `_ZnwyPv' has
left the undefined list, so the LIB= placement was the whole of that
one and libedg.a is doing its single job: placement new.

And with -C every `redefinition:' is gone.  What is underneath is
`undefined:' on `_ZN3edg...I...E' names -- template instantiations,
every one, with no vtable, no typeinfo, no guard variable and no
plain C function anywhere in the list.  That is the prediction this
tree wrote down before the run, confirmed from the linker rather than
from a host sweep.

So both halves of the link model are now measured at the link itself:
the duplicates are discarded by -C, and the missing instantiations are
what remains.  No mkfile change reaches them -- the fix is a
re-translation with EDG's own `--instantiate=used'.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
The committed C is a second translation, same commit and same recipe
plus two flags, and it closes the gap 6l reported.

WHY THEY WERE MISSING, from EDG's own source: DEFAULT_INSTANTIATION_MODE
resolves to tim_none here because the build never defines
INSTANTIATE_TEMPLATES_EVERYWHERE_USED, and host_envir.h's own comment
says the mode controls what is instantiated "without a specific request
from the prelinker"; DEFAULT_AUTOMATIC_INSTANTIATION_MODE is TRUE.  So
cpfe was told to instantiate nothing and wait for an edg_prelink phase
this build never runs -- a configuration assuming a two-phase build,
not a limitation of the C back end.  That also retires the recorded
worry that --one_instantiation_per_object would be the thing to
introduce a prelink dependency: the default already had one.

MEASURED ON ONE FILE FIRST, because a regeneration that changed nothing
would have cost a round to discover.  src/interpret.c went from 39
undefined templates to 6, with edg::count_ones<unsigned int> -- the
exact symbol 6l named -- going from U to T, and all six survivors
defined in other translation units.

THEN THE WHOLE SET, by the same sweep that reported 679:

                    before    after
  external            679       123
  _Z-prefixed         558         2
  template insts      556         0

133 of 133 compile with gcc, 0 failures.  The two surviving _Z are the
same non-template pair as before.  And `setjmp' rather than `_setjmp'
now appears, so kencc_targ.h's TARG_SETJMP_FUNC line is confirmed and
that gap closed in the same run.

lib_src/ keeps its recorded recipe exactly and is regenerated only so
TARG_SETJMP_FUNC reaches eh_util.c and newnothrow.c: it had no missing
instantiations, --building_runtime is a different mode, and -tused
there would be an unmeasured change to the runtime.  util/ gets the
flags, being the same kind of program.  util/cfe_daemon_client.c still
does not translate and is still the only one -- predicted by name
before the run.

AND THE FIRST ATTEMPT MEASURED NOTHING: the driver ran its workers
under `xargs ... bash -c', and bash cannot export an array.  `export
INC CPPDEF' was a no-op, every --sys_include vanished in the subshell,
and all 134 files died at bits/libc-header-start.h -- glibc's headers.
The single-file test had passed minutes earlier in the shell that
defined the arrays.  An instrument whose environment is not the build's
environment is measuring a different program.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
`chicken compiler-test.scm' answers

  chicken 13344: suicide: sys: trap: fault read addr=0xfffffffffffefa6

and the cause is two lines of chicken.h.

chicken.h:81 sets C_SIXTY_FOUR from __LP64__/_LP64/__MINGW64__/_WIN64.
kencc on amd64 is LLP64, and that list names LP64 and the two Windows
LLP64 spellings -- kencc predefines only __STDC__, _POSIX_SOURCE and
the two __APEXP_* markers -- so C_SIXTY_FOUR was never defined.
C_LLP, which both mkfiles already passed, is read for the word size
only INSIDE `#ifdef C_SIXTY_FOUR' (chicken.h:515), so it was inert and
the #else arm ran: C_word was `int', 32 bits, on a machine with 64-bit
pointers, in the type CHICKEN stores pointers in.

The state was one upstream cannot produce, which is why this is not an
upstream bug: upstream sets C_LLP only for __MINGW64__/_WIN64 and both
are also in the C_SIXTY_FOUR list, so its LLP64 targets always get
both.  Passing C_LLP alone gave a MIXED build -- C_long was `long long'
and C_strtow was strtoll, both read outside the C_SIXTY_FOUR block,
while C_word stayed 32-bit.

AND -DC_SIXTY_FOUR ALONE DOES NOT COMPILE, which the gcc check caught
before it shipped.  C_header is C_uword is `unsigned C_word', and
under C_LLP C_word is C_s64 -- the keyword-ish `__int64' only on
MinGW, where `unsigned __int64' is valid.  Everywhere else C_s64 is
the typedef int64_t and `unsigned int64_t' is not C: eight errors
inside chicken.h, the first on C_SCHEME_BLOCK at :755, none naming the
cause.  So C_uword is C_u64 under C_SIXTY_FOUR+C_LLP, which needs no
new macro and is the same `unsigned __int64' on MinGW.  C_uchar,
C_uhword and C_ulong beside it were checked and are unaffected: all
three are `unsigned <keyword>'.

Also checked and NOT patched: chicken.h:813-815 define C_WORD_MIN,
C_WORD_MAX and C_UWORD_MAX as the LONG limits inside the C_SIXTY_FOUR
block with no C_LLP arm, so under kencc they would be 32-bit limits
for a 64-bit word.  They are defined and never used -- zero uses
anywhere in the tree -- so it is latent, and upstream carries the same
latent bug on MinGW64.

sys/lib/tests/chickenword-probe.c is the instrument, and the HOST runs
both sides so this needed no VM round: `-U__LP64__ -U_LP64'
reproduces kencc's configuration exactly.  Fixed: C_word 8, 0
failures.  Shipped: C_SIXTY_FOUR NOT defined, C_word 4, pointer 8, 1
failure, exit 1.  Its section 0 is the marker, because a wrong width
and a stale object look identical from outside.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
TWO THINGS, both asked for and both measured.

pkg-config.  `Package tk was not found in the pkg-config search path'
is not about tcl or tk: `sys/src/ape/cmd/pkgconf/mkfile' built pkgconf
with -DPKG_DEFAULT_PATH="/bin", a directory holding no .pc file at
all, and nothing in the tree installs one.  So pkgconf is built, is in
_CORE_APPS, and `rc/bin/ape/pkg-config' forwards to it, and the whole
path has never resolved anything -- a capability present and not
declared, for the sixth time.  PERSONALITY_PATH beside it already
named the right parent, /sys/lib/ape/pkgconfig, which is now where
PKG_DEFAULT_PATH points and where tcl.pc and tk.pc live.

Those two .pc files have EMPTY Cflags and Libs, which is the design
rather than an omission and each file says why: /sys/include/ape is
already on pcc's default include path, so a -I would be noise and
anything else would shadow the real tcl.h the way gettext's lock.h
shadowed APE's; and kencc records archives from `#pragma lib', which
tcl.h and tk.h already carry, while 6l resolves -l against
/$objtype/lib rather than /$objtype/lib/ape (6l/obj.c:405) so a -l
would name a file that does not exist.  They exist to answer "present,
and at what version", which is what --exists and a configure script
actually need.

DATA_PATH is not a bacon problem and needs no engineering: upstream's
Makefile.in:51 passes -DDATA_PATH='"$(DATADIR)"', the installed data
directory, used once in bacongui-tk.bac.

sys/lib/tests/bacon-test.bac is the first BASIC test, and it exists
because BaCon SHIPS NONE -- bacon.bac plus the five GUIs is the entire
.bac corpus upstream carries, so there was nothing to adopt.  It is
aimed rather than general: a feature tour would mostly measure BaCon,
which upstream tests by shipping it, so every section targets
something this tree has been bitten by -- NUMBER is a C `long' and
kencc's is 32-bit with 64-bit pointers (tar's union block, Gay's
bignum word, CHICKEN's C_word); FLOATING against long-double-is-double
and the scalbn typo; strings where BaCon allocates; and a FUNCTION
return, which the missing-prototype invariant truncates in silence.

Validated on the host first, as this directory requires, and that
caught two bugs IN THE TEST before it ever reached 9front: a LOCAL
redeclaring a FUNCTION parameter, and `huge = 1000000 * 1000000',
which overflows in `int' on gcc too because BaCon folds bare literals
as int constants.  0 failures and no warnings on gcc now.

Two findings recorded in the file for whoever automates this: bacon
PROMPTS on a compile error and on leftover temporaries, so `</dev/null'
is required or a failing conversion hangs instead of reporting -- in a
mk recipe, a build that never returns.  And the exit status is NOT the
failure count: BaCon's END takes no value and its EXIT leaves a
SUB rather than the process, so the "N failures" line is the result.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
@staalmannen
staalmannen merged commit 0185378 into main Oct 8, 2026
1 check passed
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