Skip to content

feat(identity): callable identity plumbing, no language enabled (#2061) - #2342

Open
DeusData wants to merge 2 commits into
mainfrom
feat/callable-identity-plumbing
Open

DeusData wants to merge 2 commits into
mainfrom
feat/callable-identity-plumbing

Conversation

@DeusData

Copy link
Copy Markdown
Owner

Overloads that share a base QN (Java/C#/C++/Kotlin/Swift/Scala/ObjC) merge
into one graph node today, and that node collects the CALLS of every
overload. The agreed cure is one signature-qualified callable identity for
all overloading languages:

callable_qn := base_qn [<tparams>] (params) [cvref]

This change lands the plumbing with every language still at
CBM_CALLABLE_ID_NONE, so the graph is byte-identical; each language is
switched on later in its own change (with its index-format bump).

  • internal/cbm/callable_sig.{c,h}: the per-language mode side table
    (NONE|TYPED|LABELED_TYPED|LABELED|ARITY; kept out of CBMLangSpec like
    cbm_string_dispatch_suffixes, since 160 positional rows would otherwise
    all need the member under -Wmissing-field-initializers), the shared
    builder cbm_callable_sig[_mode] for the def and the call-scope QN, and
    the inverse cbm_qn_callable_base_len[_named]. Suffix contract: no '.',
    '::' or '->'; whitespace-normalized; comments/annotations/attributes
    dropped; qualified types keep their last segment; '->' spelled '=>';
    variadic '[]' (Java) / '
    '; C++ top-level cv dropped, arrays decay,
    cvref kept; <= 200 bytes, longer ones keep whole leading entries and end
    in '#)'. The builder is iterative (cursor
    walk, bounded declarator loop) and self-checks against the inverse.
  • The inverse is anchored to the node's bare name wherever the name is
    known: real QNs already end in ')' without being callables (a Java field
    whose name is its declarator X = f(), make $(VAR) targets), and only
    the anchor makes the inverse exact on them.
  • Leaf splitters strip a suffix first (no-op today): registry by-name key
    (indexed by the bare name for a suffixed callable), cbm_lsp_bare_segment,
    cbm_pipeline_qn_class_method_tail, pxc_last_component, pxc_qn_leaf,
    go_index_visit_node, collect_prod_defs, sg_qn_prefix_len.
  • New unused fields: CBMDefinition.qn_sig_off, CBMResolvedCall.callee_sig
    (relocated by result compaction), CBMRegisteredFunc.sig, CBMLSPDef.sig.
    The lsp_surface codec is unchanged (no format bump in this change).
  • get_code_snippet and trace_path gain base-QN tiers
    (cbm_store_find_nodes_by_qn_base) that find nothing until suffixes exist.
  • store: cbm_store_find_nodes_by_qn_suffix built its LIKE pattern in a
    512-byte buffer (a long suffix was truncated into a pattern that matched
    nothing) and did not escape '_'/'%' (my_func also matched myXfunc).
    The pattern is now heap-built, escaped, and matched with ESCAPE ''.

Proof: full sorted node+edge+lsp_surface dumps are byte-identical before
and after on 7 corpora (this repo, elasticsearch libs, Exposed, dotnet
System.Linq, System.Collections, coreclr/gc, a C corpus).

Refs #2061


PR1 of the #2061 overload-identity program; every language stays NONE, so the graph is unchanged (byte-identical dumps on 7 corpora). Language PRs follow, each with its own index-format bump. Also fixes a pre-existing store bug (qn-suffix LIKE truncation/escaping). Can be split into PR1a (inverse, splitters, store fix) and PR1b (signature builder + golden tables) if preferred.

Overloads that share a base QN (Java/C#/C++/Kotlin/Swift/Scala/ObjC) merge
into one graph node today, and that node collects the CALLS of every
overload. The agreed cure is one signature-qualified callable identity for
all overloading languages:

    callable_qn := base_qn [<tparams>] (params) [cvref]

This change lands the plumbing with every language still at
CBM_CALLABLE_ID_NONE, so the graph is byte-identical; each language is
switched on later in its own change (with its index-format bump).

- internal/cbm/callable_sig.{c,h}: the per-language mode side table
  (NONE|TYPED|LABELED_TYPED|LABELED|ARITY; kept out of CBMLangSpec like
  cbm_string_dispatch_suffixes, since ~160 positional rows would otherwise
  all need the member under -Wmissing-field-initializers), the shared
  builder cbm_callable_sig[_mode] for the def and the call-scope QN, and
  the inverse cbm_qn_callable_base_len[_named]. Suffix contract: no '.',
  '::' or '->'; whitespace-normalized; comments/annotations/attributes
  dropped; qualified types keep their last segment; '->' spelled '=>';
  variadic '[]' (Java) / '~'; C++ top-level cv dropped, arrays decay,
  cvref kept; <= 200 bytes, longer ones keep whole leading entries and end
  in '#<fnv1a64 of the full suffix>)'. The builder is iterative (cursor
  walk, bounded declarator loop) and self-checks against the inverse.
- The inverse is anchored to the node's bare name wherever the name is
  known: real QNs already end in ')' without being callables (a Java field
  whose name is its declarator `X = f()`, make `$(VAR)` targets), and only
  the anchor makes the inverse exact on them.
- Leaf splitters strip a suffix first (no-op today): registry by-name key
  (indexed by the bare name for a suffixed callable), cbm_lsp_bare_segment,
  cbm_pipeline_qn_class_method_tail, pxc_last_component, pxc_qn_leaf,
  go_index_visit_node, collect_prod_defs, sg_qn_prefix_len.
- New unused fields: CBMDefinition.qn_sig_off, CBMResolvedCall.callee_sig
  (relocated by result compaction), CBMRegisteredFunc.sig, CBMLSPDef.sig.
  The lsp_surface codec is unchanged (no format bump in this change).
- get_code_snippet and trace_path gain base-QN tiers
  (cbm_store_find_nodes_by_qn_base) that find nothing until suffixes exist.
- store: cbm_store_find_nodes_by_qn_suffix built its LIKE pattern in a
  512-byte buffer (a long suffix was truncated into a pattern that matched
  nothing) and did not escape '_'/'%' (`my_func` also matched `myXfunc`).
  The pattern is now heap-built, escaped, and matched with ESCAPE '\'.

Proof: full sorted node+edge+lsp_surface dumps are byte-identical before
and after on 7 corpora (this repo, elasticsearch libs, Exposed, dotnet
System.Linq, System.Collections, coreclr/gc, a C corpus).

Refs #2061

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
@DeusData
DeusData force-pushed the feat/callable-identity-plumbing branch from 3441da4 to 5538355 Compare September 30, 2026 22:34

This branch has not been deployed

No deployments
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