Skip to content

Count the compiler warnings in a ParparVM native build, by owner - #5750

Open
shai-almog wants to merge 24 commits into
masterfrom
native-warning-census
Open

Count the compiler warnings in a ParparVM native build, by owner#5750
shai-almog wants to merge 24 commits into
masterfrom
native-warning-census

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Rationale is in the commit message and in code comments; this body is a pointer only.

What it does. Records where every file in a generated project came from (cn1-source-manifest.txt), then attributes each compiler warning in a build log to generated / runtime / port / vendored / sdk / toolchain. Ownership is not recoverable from the path -- the translator copies port natives into the same flat directory as its own output.

Not gating yet. No baseline is committed. The census is report-only on scripts-ios.yml's build-ios leg (the only iOS leg that compiles cold), gated on CN1_WARNING_CENSUS, which nothing a customer runs sets. pr.yml gains only a parser self-test that needs no compiler.

Local measurement (clean target, JavaAPI-only app, -Wall -Wextra): 3,802 warning lines from a cold build -- 3,035 in generated code across 8 kinds, 185 in the runtime. Top rows are -Wunused-parameter (1694) and -Wunused-variable (1002), both single-emitter fixes. The runtime carries several worth triaging as bugs rather than noise, including -Wpointer-to-int-cast (cast to a smaller integer type).

Next step is freezing the baselines from this PR's CI run.

🤖 Generated with Claude Code

A ParparVM build compiles four different kinds of C into one binary -- the
translator's output, the ParparVM runtime, the hand-written port natives, and
vendored third-party sources -- and their warnings arrive in one log with
nothing to tell them apart. At that volume a real defect is invisible: an Apple
API that is deprecated now and deleted in two releases, or a pointer/integer
confusion in generated code, reads the same as the noise around it. Nothing in
this tree has ever counted them, and the Android port has already shown what
that costs (API 37 deleted FingerprintManager with every check green).

Ownership cannot be recovered from the path. ByteCodeTranslator.execute() copies
every non-class file into the same flat srcRoot as the generated code, so
CN1Vision.m and com_codename1_ui_Form.m are indistinguishable siblings, and
bytecode-translator-files.txt is a plain find over that directory. So the
translator records provenance at each copy site into cn1-source-manifest.txt.

It goes in the project root rather than srcRoot deliberately: getFileType() has
no case for .txt, so anything left in srcRoot falls through to ***RESOURCES***
and is copied inside the shipped .app.

check-native-warnings.py reads that manifest plus a build log and attributes
every diagnostic to generated / runtime / port / vendored / sdk / toolchain,
holding the result against a per-leg baseline in the manner of
check-cast-semantics.sh. No baseline is committed yet -- one has to be frozen
from a real CI leg, not from a local run.

Three guards, because a gate that reads nothing reports success:

- The build must have compiled everything the manifest lists. An incremental
  build recompiles nothing, reports no warnings, and is indistinguishable from a
  clean codebase; so is the documented ARCHS failure where xcodebuild "silently
  compiles NOTHING while still copying resources".
- --probe injects one synthetic warning and asserts the whole chain reacts, on
  the real log with the real manifest, so a gate that has gone blind fails the
  day it breaks rather than the day someone notices it never fired.
- --self-test checks the parser against a hand-authored fixture and the
  baselines against their own format. Both run in pr.yml and need no compiler.

The census runs on scripts-ios.yml's build-ios leg because that is the one that
can: it sets no CN1_IOS_DERIVED_DATA, so it wipes derived data and compiles
cold, and its path filters are a superset of the other iOS legs'. It is gated on
CN1_WARNING_CENSUS, which our workflows set and nothing a customer runs does,
and it is report-only for now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T11:41:58.623265Z 1c237bc New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0be6104ec

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-native-warnings.py Outdated
# Xcode names the source it is about to compile; ninja and make announce the
# object. Either way this is how we learn what the build ACTUALLY compiled, as
# opposed to what it could have compiled.
COMPILE_XCODE_RE = re.compile(r'^\s*CompileC\s+(?:"[^"]*"|\S+)\s+(?P<src>"[^"]+"|\S+)\s+normal\b')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Parse Metal compile steps before checking completeness

On the checked build-ios workflow, CN1MetalShaders.metal is copied from Ports/iOSPort/nativeSources and included in the Xcode sources, but Xcode announces it with a CompileMetalFile operation rather than CompileC. Since this regex is the only Xcode compilation grammar while .metal is included in SOURCE_EXTS, check_completeness() always reports that shader as uncompiled and exits 2; run-ios-ui-tests.sh then swallows that status, so this leg produces no warning census or JSON artifact despite a successful cold build.

Useful? React with 👍 / 👎.

Comment on lines +1164 to +1167
// Only the one-file-per-class case has a file name worth recording. Under
// concatenation the classes are bucketed into concatenated_<n> and the
// provenance of an individual class is genuinely gone by the time the
// compiler sees it; the manifest says so by simply not naming these.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record concatenated output files in the manifest

When concatenateFiles=true—used by iOS superfast builds and unconditionally by MacOSNativeBuilder—the compiler sees concatenated_<n>.m, but this branch deliberately records none of those generated files. Any warning emitted from a concatenated unit consequently has no manifest entry or external-path marker, so classify() treats it as unattributed and aborts the census instead of placing it in the generated group; record each nonempty concatenated output when realClose() creates it.

Useful? React with 👍 / 👎.

The completeness guard asked the wrong question. It required every source in the
manifest to appear as compiled, but the manifest names every file in the
generated project and a target legitimately builds a subset: a .metal goes
through CompileMetalFile rather than CompileC, and a source can be excluded from
a target outright. Demanding all of them would have failed the first real census
for a reason that is not a defect.

The thing actually worth catching is different: a build that compiled LESS than
the one the baseline was frozen from. That is what an incremental build looks
like, it reports no warnings, and it is indistinguishable from a clean codebase.
So the ratchet is on coverage, recorded in coverage-<leg>.txt beside the
baseline. It is exact, needs no threshold, and needs nobody to enumerate which
files a given target happens to include. A build that compiles nothing at all is
still fatal on its own.

Sources the manifest lists that this target never builds are now reported rather
than fatal, which is the honest reading of them.

Also recognises the real task-line shape, checked against Xcode 26.3 output
rather than assumed: the task name is followed by output, source, "normal", the
arch, and a trailing "(in target ... from project ...)". Both that line and the
CompileMetalFile form are in the fixture now, so neither can regress silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

Generated automatically by the PR CI workflow.

shai-almog and others added 3 commits September 9, 2026 11:47
METALView.h and METALView.m exist in both Ports/MacPort and
Ports/iOSPort/nativeSources, so resolving a warning's file by name alone was
ambiguous and would have refused the macOS leg outright the first time either
one warned.

The leg already answers it: a macOS build compiled the MacPort copy. Listing
each leg's port trees most-specific-first states that rather than guessing at
it, and a name claimed by a more specific tree is not reconsidered.

A name that appears twice inside a SINGLE port tree still refuses to resolve.
There the leg tells us nothing, and picking one would put a file nobody edited
into the baseline.

Also indexes each port tree once instead of walking it per diagnostic, which was
O(diagnostics x files) against a census that carries thousands.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"/Library/Developer/" also matches a developer's own
~/Library/Developer/Xcode/DerivedData, so a Swift package checkout under
SourcePackages was being labelled an Apple SDK header. The vendored markers are
the more specific ones and belong first.

Neither group gates, so no verdict changes -- but the census exists to be read,
and one that misattributes what it reports is not worth reading.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The summary table had a row per distinct warning kind, and the iOS leg carries
far more of them than the clean target does. GitHub drops a step summary whole
once it exceeds 1MB, so an unbounded table risks costing the entire report
rather than its tail -- the failure mode being a census that ran, found
everything, and showed nothing.

Capped per group, with the hidden rows counted rather than silently dropped, and
a line saying the tail is in the JSON dump. The census itself is unchanged; this
only bounds what a human is asked to scroll.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 584caa96d2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

* somebody else's vendored code. Written out beside the generated project at the
* end of each output handler; see {@link SourceManifest}.
*/
static final SourceManifest sourceManifest = new SourceManifest();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset provenance before each translation

When ByteCodeTranslator.main() is invoked more than once in the same JVM—as the integration tests and embedded callers can do—this static manifest retains every entry from the previous application because neither main() nor Parser.cleanup() clears it. The next project therefore receives a manifest containing sources that do not exist in its output, and retained origins can also classify a same-named file using provenance from the earlier build; create or clear the manifest at the start of each translation.

Useful? React with 👍 / 👎.

// globs srcRoot for sources, and the Apple path lists it into the Xcode project,
// where an unrecognised extension lands in the resources phase and ships inside
// the bundle. See SourceManifest.
sourceManifest.write(root);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record clean-target resource sources before writing the manifest

For the windows and linux clean targets, embedWindowsResources()/embedLinuxResources() always generate cn1_resources_table.c and may also generate cn1_resources_data.S, but neither file is added to sourceManifest before it is written here. A compiler warning in either generated unit consequently has no manifest entry, so classify() treats it as unattributed and aborts the warning census instead of assigning it to generated code.

Useful? React with 👍 / 👎.

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 166 screenshots: 166 matched.
Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 62ms / native 4ms = 15.5x speedup
SIMD float-mul (64K x300) java 63ms / native 5ms = 12.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 207.000 ms
Base64 CN1 decode 138.000 ms
Base64 SIMD encode 102.000 ms
Base64 encode ratio (SIMD/CN1) 0.493x (50.7% faster)
Base64 SIMD decode 107.000 ms
Base64 decode ratio (SIMD/CN1) 0.775x (22.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 37.000 ms
Image createMask (SIMD on) 4.000 ms
Image createMask ratio (SIMD on/off) 0.108x (89.2% faster)
Image applyMask (SIMD off) 37.000 ms
Image applyMask (SIMD on) 60.000 ms
Image applyMask ratio (SIMD on/off) 1.622x (62.2% slower)
Image modifyAlpha (SIMD off) 32.000 ms
Image modifyAlpha (SIMD on) 47.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.469x (46.9% slower)
Image modifyAlpha removeColor (SIMD off) 41.000 ms
Image modifyAlpha removeColor (SIMD on) 57.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.390x (39.0% slower)

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 166 screenshots: 166 matched.
Native Windows port (x64 / Intel-AMD): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, SSE2 SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 50ms / native 4ms = 12.5x speedup
SIMD float-mul (64K x300) java 52ms / native 3ms = 17.3x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 150.000 ms
Base64 CN1 decode 106.000 ms
Base64 SIMD encode 78.000 ms
Base64 encode ratio (SIMD/CN1) 0.520x (48.0% faster)
Base64 SIMD decode 77.000 ms
Base64 decode ratio (SIMD/CN1) 0.726x (27.4% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 9.000 ms
Image createMask (SIMD on) 26.000 ms
Image createMask ratio (SIMD on/off) 2.889x (188.9% slower)
Image applyMask (SIMD off) 44.000 ms
Image applyMask (SIMD on) 58.000 ms
Image applyMask ratio (SIMD on/off) 1.318x (31.8% slower)
Image modifyAlpha (SIMD off) 50.000 ms
Image modifyAlpha (SIMD on) 27.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.540x (46.0% faster)
Image modifyAlpha removeColor (SIMD off) 52.000 ms
Image modifyAlpha removeColor (SIMD on) 67.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.288x (28.8% slower)

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 166 screenshots: 166 matched.
Native Windows port (arm64 / Apple Silicon - Arm): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, NEON SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 56ms / native 3ms = 18.6x speedup
SIMD float-mul (64K x300) java 57ms / native 4ms = 14.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 245.000 ms
Base64 CN1 decode 127.000 ms
Base64 SIMD encode 65.000 ms
Base64 encode ratio (SIMD/CN1) 0.265x (73.5% faster)
Base64 SIMD decode 63.000 ms
Base64 decode ratio (SIMD/CN1) 0.496x (50.4% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 6.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.333x (66.7% faster)
Image applyMask (SIMD off) 40.000 ms
Image applyMask (SIMD on) 18.000 ms
Image applyMask ratio (SIMD on/off) 0.450x (55.0% faster)
Image modifyAlpha (SIMD off) 16.000 ms
Image modifyAlpha (SIMD on) 32.000 ms
Image modifyAlpha ratio (SIMD on/off) 2.000x (100.0% slower)
Image modifyAlpha removeColor (SIMD off) 20.000 ms
Image modifyAlpha removeColor (SIMD on) 8.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.400x (60.0% faster)

SpotBugs DM_CONVERT_CASE, and it is the tree's documented rule rather than a
style nit: String.toLowerCase() is locale sensitive, and Codename One has no
java.util.Locale to ask for the root one, so the fold a device performs depends
on who is holding it. A protocol token another program parses back is exactly
the case that must never be produced by folding.

The four current constants happen to contain no dotted I, so nothing was broken
today -- but the next one added could, and it would fail only for users whose
device is set to Turkish or Azerbaijani, with nothing throwing.

Writing the token out also means the manifest's wire format is stated in the
enum rather than being an accident of the Java identifier, so renaming a
constant can no longer silently change the file that check-native-warnings.py
parses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74fe911480

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +44 to +46
GNU_RE = re.compile(
r'^(?P<path>[^\s][^:]*(?::[^:\s][^:]*)*?):(?P<line>\d+):(?P<col>\d+):\s+'
r'(?P<sev>warning|error|note):\s+(?P<msg>.*)$')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept diagnostics without a column number

When a compiler emits a diagnostic in the valid path:line: warning: ... form without a column, this pattern does not match because it requires :line:col:, while BARE_RE only accepts warnings beginning at column zero. Such warnings are silently omitted from the JSON and baseline comparison, allowing the census to report clean despite warnings in the build log; make the column portion optional and cover this form in the parser fixture.

Useful? React with 👍 / 👎.

Comment on lines +687 to +691
ByteCodeTranslator.sourceManifest.recordGenerated("cn1_class_method_index.h");
fos = new FileOutputStream(new File(outputDirectory, "cn1_class_method_index.m"));
fos.write(bldM.toString().getBytes(StandardCharsets.UTF_8));
fos.close();
ByteCodeTranslator.sourceManifest.recordGenerated("cn1_class_method_index.m");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record the on-device debug sidecar in the manifest

When cn1.onDeviceDebug=true, writeSymbolSidecar() emits and the generated project compiles cn1_debug_symbols.c, but unlike the generated files recorded here, that sidecar is never passed to sourceManifest.recordGenerated(). A warning in it therefore has neither a manifest entry nor an external-path marker, so classify() marks it unattributed and aborts the census instead of assigning it to generated code; record the sidecar when it is emitted.

Useful? React with 👍 / 👎.

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 166 screenshots: 166 matched.
Native Linux port (x64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub x64 runner. Baseline: scripts/linux/screenshots.

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 166 screenshots: 166 matched.
Native Linux port (arm64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub arm64 runner. Baseline: scripts/linux/screenshots-arm.

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 181 screenshots: 181 matched.
✅ JavaScript-port screenshot tests passed.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 567 total, 0 failed, 57 skipped

Benchmark Results

  • Execution Time: 24137 ms

  • Hotspots (Top 20 sampled methods):

    • 13.84% com.codename1.tools.translator.Parser.addToConstantPool (280 samples)
    • 8.90% java.util.ArrayList.indexOf (180 samples)
    • 4.25% com.codename1.tools.translator.ByteCodeClass.hasDeclaredMethod (86 samples)
    • 3.61% java.lang.StringBuilder.append (73 samples)
    • 3.36% com.codename1.tools.translator.BytecodeMethod.optimize (68 samples)
    • 3.06% com.codename1.tools.translator.Parser.cn1EnsureSubclassIndex (62 samples)
    • 2.52% org.objectweb.asm.tree.analysis.Analyzer.analyze (51 samples)
    • 2.27% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (46 samples)
    • 2.13% org.objectweb.asm.tree.analysis.Analyzer.findSubroutine (43 samples)
    • 2.08% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (42 samples)
    • 1.98% java.lang.System.identityHashCode (40 samples)
    • 1.93% java.util.IdentityHashMap$KeySet.toArray (39 samples)
    • 1.73% com.codename1.tools.translator.ByteCodeClass.fillVirtualMethodTable (35 samples)
    • 1.68% com.codename1.tools.translator.BytecodeMethod.equals (34 samples)
    • 1.68% java.util.HashMap.hash (34 samples)
    • 1.58% com.codename1.tools.translator.Parser.classIndex (32 samples)
    • 1.33% java.lang.Object.hashCode (27 samples)
    • 1.14% org.objectweb.asm.ClassReader.readCode (23 samples)
    • 1.09% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (22 samples)
    • 1.09% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (22 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 160 screenshots: 160 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 179 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 95ms / native 4ms = 23.7x speedup
SIMD float-mul (64K x300) java 69ms / native 7ms = 9.8x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 186.000 ms
Base64 CN1 decode 103.000 ms
Image encode benchmark iterations 100
Image createMask (SIMD off) 14.000 ms
Image createMask (SIMD on) 7.000 ms
Image createMask ratio (SIMD on/off) 0.500x (50.0% faster)
Image applyMask (SIMD off) 86.000 ms
Image applyMask (SIMD on) 75.000 ms
Image applyMask ratio (SIMD on/off) 0.872x (12.8% faster)
Image modifyAlpha (SIMD off) 75.000 ms
Image modifyAlpha (SIMD on) 61.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.813x (18.7% faster)
Image modifyAlpha removeColor (SIMD off) 67.000 ms
Image modifyAlpha removeColor (SIMD on) 63.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.940x (6.0% faster)

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 149 screenshots: 149 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 1615 seconds

Build and Run Timing

Metric Duration
Simulator Boot 88000 ms
Simulator Boot (Run) 0 ms
App Install 20000 ms
App Launch 37000 ms
Test Execution 421000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 106ms / native 5ms = 21.2x speedup
SIMD float-mul (64K x300) java 180ms / native 2ms = 90.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 369.000 ms
Base64 CN1 decode 186.000 ms
Base64 native encode 454.000 ms
Base64 encode ratio (CN1/native) 0.813x (18.7% faster)
Base64 native decode 524.000 ms
Base64 decode ratio (CN1/native) 0.355x (64.5% faster)
Base64 SIMD encode 82.000 ms
Base64 encode ratio (SIMD/CN1) 0.222x (77.8% faster)
Base64 SIMD decode 51.000 ms
Base64 decode ratio (SIMD/CN1) 0.274x (72.6% faster)
Base64 encode ratio (SIMD/native) 0.181x (81.9% faster)
Base64 decode ratio (SIMD/native) 0.097x (90.3% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 33.000 ms
Image createMask (SIMD on) 5.000 ms
Image createMask ratio (SIMD on/off) 0.152x (84.8% faster)
Image applyMask (SIMD off) 183.000 ms
Image applyMask (SIMD on) 889.000 ms
Image applyMask ratio (SIMD on/off) 4.858x (385.8% slower)
Image modifyAlpha (SIMD off) 327.000 ms
Image modifyAlpha (SIMD on) 313.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.957x (4.3% faster)
Image modifyAlpha removeColor (SIMD off) 225.000 ms
Image modifyAlpha removeColor (SIMD on) 244.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.084x (8.4% slower)

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 143 screenshots: 143 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 1687 seconds

Build and Run Timing

Metric Duration
Simulator Boot 81000 ms
Simulator Boot (Run) 1000 ms
App Install 37000 ms
App Launch 82000 ms
Test Execution 641000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 168ms / native 4ms = 42.0x speedup
SIMD float-mul (64K x300) java 274ms / native 14ms = 19.5x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 342.000 ms
Base64 CN1 decode 232.000 ms
Base64 native encode 1996.000 ms
Base64 encode ratio (CN1/native) 0.171x (82.9% faster)
Base64 native decode 789.000 ms
Base64 decode ratio (CN1/native) 0.294x (70.6% faster)
Base64 SIMD encode 118.000 ms
Base64 encode ratio (SIMD/CN1) 0.345x (65.5% faster)
Base64 SIMD decode 167.000 ms
Base64 decode ratio (SIMD/CN1) 0.720x (28.0% faster)
Base64 encode ratio (SIMD/native) 0.059x (94.1% faster)
Base64 decode ratio (SIMD/native) 0.212x (78.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 27.000 ms
Image createMask (SIMD on) 5.000 ms
Image createMask ratio (SIMD on/off) 0.185x (81.5% faster)
Image applyMask (SIMD off) 232.000 ms
Image applyMask (SIMD on) 458.000 ms
Image applyMask ratio (SIMD on/off) 1.974x (97.4% slower)
Image modifyAlpha (SIMD off) 179.000 ms
Image modifyAlpha (SIMD on) 285.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.592x (59.2% slower)
Image modifyAlpha removeColor (SIMD off) 1685.000 ms
Image modifyAlpha removeColor (SIMD on) 35.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.021x (97.9% faster)

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 144 screenshots: 144 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

The first real census of an iOS build: 92,129 warning lines in a 1.17M-line log,
none of which anything had ever counted. 60,952 of them are ours and gating,
across 157 distinct kinds. Coverage confirms it came from a cold build -- 3,147
sources compiled, none of the manifest's 3,133 skipped.

What the split by owner buys is visible immediately. Generated code is four
emitters, two of which account for essentially all of it: 50,967
-Wunused-variable and 9,094 -Wincompatible-pointer-types-discards-qualifiers.
The 814 warnings in the hand-written port were the ones worth finding, and they
were unreadable underneath that: 470 deprecations (OpenGLES, and
MPMoviePlayerController asking for AVPlayerViewController), 67
-Wshorten-64-to-32, 21 -Wint-conversion, 10 ARC bridge casts in non-ARC code, 6
-Wunsupported-availability-guard -- availability checks that do not guard -- and
4 -Wundeclared-selector, which is the class the macOS template already makes an
error because it crashes on the device.

Three log-transport defects had to be fixed first, all found in the real log
rather than imagined. xcodebuild's output reaches the log through a pipe and a
long diagnostic can arrive broken at an arbitrary byte:

- split in the PATH, leaving a file name like "odename1_ui_Display.m" that
  belongs to nothing;
- split in the MESSAGE, which is worse because the first half still parses and
  yields a message shape of "unuse" -- a baseline row that could never match
  again;
- and occasionally bytes are LOST rather than split, so the path is gone
  outright. Those are counted and reported as lost, never attributed and never
  baselined: a row keyed on no file cannot recur, so baselining one would
  guarantee a stale entry later.

Both joins are self-validating rather than guessed -- a path join must produce
something that parses, a message join must complete a trailing flag that was
absent. All three shapes are now in the parser fixture.

A fileless diagnostic carrying a [-Wflag] is one of the lost ones, not a
build-system warning; clang flags belong to file-scoped diagnostics, and that is
what separates it from a genuine "Skipping duplicate build file".

Two provenance rules the census asked for: an embedded watch or tv app is a
second, independent ParparVM translation writing to a sibling -src directory, so
its output is generated code by the same argument as the main app's; and an
.xcframework is unzipped into the build's own products directory before its
headers are compiled, so those arrive under a local-looking path and are not
ours.

The leg now gates rather than reporting, and runs --probe afterwards so a gate
that has gone blind fails the same day.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40e9fd9c40

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-native-warnings.py Outdated
Comment thread scripts/run-ios-ui-tests.sh Outdated
@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 148 screenshots: 148 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 360 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 75ms / native 3ms = 25.0x speedup
SIMD float-mul (64K x300) java 73ms / native 4ms = 18.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 198.000 ms
Base64 CN1 decode 126.000 ms
Base64 native encode 945.000 ms
Base64 encode ratio (CN1/native) 0.210x (79.0% faster)
Base64 native decode 472.000 ms
Base64 decode ratio (CN1/native) 0.267x (73.3% faster)
Base64 SIMD encode 65.000 ms
Base64 encode ratio (SIMD/CN1) 0.328x (67.2% faster)
Base64 SIMD decode 64.000 ms
Base64 decode ratio (SIMD/CN1) 0.508x (49.2% faster)
Base64 encode ratio (SIMD/native) 0.069x (93.1% faster)
Base64 decode ratio (SIMD/native) 0.136x (86.4% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 16.000 ms
Image createMask (SIMD on) 8.000 ms
Image createMask ratio (SIMD on/off) 0.500x (50.0% faster)
Image applyMask (SIMD off) 71.000 ms
Image applyMask (SIMD on) 52.000 ms
Image applyMask ratio (SIMD on/off) 0.732x (26.8% faster)
Image modifyAlpha (SIMD off) 56.000 ms
Image modifyAlpha (SIMD on) 90.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.607x (60.7% slower)
Image modifyAlpha removeColor (SIMD off) 80.000 ms
Image modifyAlpha removeColor (SIMD on) 71.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.888x (11.3% faster)

@shai-almog

shai-almog commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 217 screenshots: 217 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

The gate's first live run failed on generated|*|<no-flag>|unused variable ?,
which is the flake this was warned about rather than a new warning: a diagnostic
split immediately before a space, leaving the continuation as
" [-Wunused-variable]". Excluding every indented line as "probably a source
snippet" excluded that too, so the diagnostic kept a truncated message and lost
its flag. Only clang's actual snippet and caret shapes are excluded now; the
join still has to complete a trailing flag, so nothing else can be glued on.

Two runs of the same leg then produced identical baselines -- 157 keys, same
set, from logs of 60,952 and 61,124 gating diagnostics. That is the property the
ratchet needs and it is now measured rather than assumed.

Getting there exposed two holes, both of the "gate reads nothing and reports
success" kind this whole exercise exists to prevent:

An unknown leg name resolved to no port trees, so every hand-written native
failed to resolve, fell through to vendored, and left the gating set. The census
still printed and still passed, having quietly stopped checking the code most
worth checking -- 144 of 157 entries. It is a hard error now; a leg with no port
sources says so with an empty list, as clean-target does.

And the coverage ratchet compared against the sources the baselined build
compiled, which couples the gate to something that legitimately moves: the two
runs compiled 3,147 and 3,156 sources. Each compiled 100% of its OWN manifest,
which is the invariant that actually holds, needs no stored state, and catches
an incremental build just as well.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eae4f3443f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/pr.yml
Comment thread scripts/check-native-warnings.py Outdated
…hing reads

51,108 of the iOS leg's 61,124 gating warnings were -Wunused-variable in
generated code, and none of them came from where the plan guessed. The census
data named the actual sources, which is the whole reason it was built before any
of this was attempted:

  SP                                 21,577
  currentCodenameOneCallStackOffset   8,727
  methodBlockOffset                   8,727
  currentOffset                       6,495
  locals                              3,046
  objInstance                         2,438

The first five are declared unconditionally by the six frame macros, because a
macro cannot know whether the method body it precedes will touch the operand
stack, enter a try block, or have locals at all. Emitting a different macro per
combination would multiply the frame variants without making any generated code
better, so the declarations say so instead: CN1_UNUSED is the C idiom for
exactly this, and it suppresses only these variables, leaving a genuinely unused
variable anywhere else reported.

It is keyed on the compiler feature rather than the vendor. clang-cl defines
_MSC_VER as well as __clang__, so testing for MSVC first -- the shape the
neighbouring CN1_NORETURN uses -- would have silently dropped the attribute on
the Windows port and left that leg as noisy as before.

objInstance is different and is a real emitter fix: __GC_MARK_ casts objToMark
for every class, but a class declaring no object fields of its own marks nothing
and only chains to its base, so the cast is a variable no statement in the
function reads. Thousands of classes hold nothing but primitives. Every use of
it sits inside the field loop -- both the base-class call and the
java.lang.Object branch use objToMark -- so the guard is the loop's own
condition.

Measured on a clean-target build: 3,802 warnings to 2,800, with generated
-Wunused-variable going from 1,002 to zero. Verified in the generated C both
ways: java_lang_String still casts and marks its field, java_lang_Integer emits
neither.

The baseline is unchanged on purpose. Roughly 98 -Wunused-variable instances
survive in generated code from other emitters, so the row still reproduces --
which is what keying the ratchet on presence rather than count is for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… for

9,125 warnings on the iOS leg, all one message: passing
'struct elementStruct *volatile *' to a parameter of type
'struct elementStruct **' discards qualifiers. The compiler was right, and this
is the defect the census was built to surface rather than noise to be quietened.

POP_INT() and friends expanded to (*pop(&SP)).data.i, and pop() takes
struct elementStruct**. A method that emits setjmp declares SP volatile so
longjmp cannot clobber it -- that is the entire reason the _VSP frame variants
exist -- and &SP is then struct elementStruct *volatile *. So on exactly the
frames where the qualifier matters, every pop handed the runtime a pointer that
discarded it, and a write through that pointer is not the volatile access the
declaration asked for.

(*--SP) is the same decrement-then-dereference without taking SP's address, so
the qualifier stays where the frame put it. popMany had to move SP by an amount
it computes from the slot types, so it could not just drop the pointer: it
becomes cn1PopMany, value in and value out, and POP_MANY assigns the result
back. Where SP is volatile that assignment is an ordinary volatile store, which
is what was wanted all along.

Nothing else called either one. The two remaining pop/popMany spellings in
cn1_globals.h sit inside a commented-out block and are dead.

Verified: the full ParparVM suite, 557 tests, no failures, with
CleanTargetIntegrationTest running its whole 35 -- these compile and RUN
translated programs, which is the check that matters for a change to the hottest
path in the VM. On a clean-target build the category went from 75 to zero and
total warnings 2,800 -> 2,725; the generated C carries no pop(&SP) anywhere.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d4e39fd1e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/native-warnings/baseline-ios-sim-debug.txt Outdated
Five CLANG_WARN_* settings are off in the iOS Xcode project, presumably to
quieten the translated C. The census runs with all five forced on, so what each
one actually costs is now measured rather than assumed, across a full
application build -- generated code, the ParparVM runtime, the iOS port natives
and the pods:

  CLANG_WARN_EMPTY_BODY                 0
  CLANG_WARN__DUPLICATE_METHOD_MATCH    0
  CLANG_WARN_ENUM_CONVERSION           10   (all in the port)
  CLANG_WARN_INT_CONVERSION            30   (28 port, 2 runtime)
  GCC_WARN_UNUSED_VARIABLE             ~180 after the emitter fixes

The first two find nothing anywhere. They have been suppressing no diagnostic at
all, so turning them on costs this build nothing and gives an application author
the same two checks over their own native code. Both are already YES on the
app-extension targets the builder writes, so the main target was the odd one
out.

The other three do still fire, and stay off until what they find is fixed rather
than being turned on to add warnings to every customer build. -Wint-conversion
is the one worth reading first: in current clang it defaults to an error, so
= NO has been actively suppressing a pointer/integer confusion class in code
that ships.

Left alone in the macOS project, which carries the same five. Its census has not
been taken, the port natives there are different files, and zero on iOS is not
evidence about MacPort.

Verified on a regenerated project: both land as YES, every literal
IPhoneBuilder anchors its regex rewrites on is intact, and
injectDevelopmentTeam still matches both SDKROOT blocks whole -- the added
comment carries no nested "};" that would truncate one, and no "template" that
replaceInFile would rewrite into the app name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca943a9733

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-native-warnings.py
The Linux screenshot suite does not deadlock. The event dispatch thread dies and
the process keeps running:

  [EDT] Exception: java.lang.ArrayIndexOutOfBoundsException - -1567458274
      at com_codename1_ui_Display.callSeriallyOnIdle:1174
      ...
  java.lang.NullPointerException
      at com_codename1_ui_util_EventDispatcher.fireActionEvent:305
      at com_codename1_ui_Display.mainEDTLoop:1611     <- inside the catch block
      at com_codename1_ui_RunnableWrapper.run:139
      at com_codename1_impl_CodenameOneThread.run:179
      at java_lang_Thread.runImpl:216                   <- top frame of the EDT

An exception reaches mainEDTLoop's catch. The catch reports it through the
application's error handler. The handler throws. That second throwable
propagates out of the catch, out of the dispatch loop and off the end of the
thread -- the trace reaches Thread.runImpl, so the thread is gone. Every other
thread lives, so the process stays up; nothing paints or handles input again.
The suite then sits idle until a 40-minute cap kills it with 13 of 100
screenshots never taken.

Four of the calls in that block run code Display does not own: a registered
CrashReport, the port's handleEDTException, the application's error handler, and
Dialog.show -- which paints, so it fails for any reason painting fails. Any one
of them ending the dispatch thread is the same permanent freeze, and this is
reachable from ordinary application code rather than being specific to CI.

There were TWO such blocks, not one: the dispatch loop's, and the phase that
runs before the first Form is shown. Both now go through reportEdtException,
which cannot let a second throwable escape. Both throwables are logged, the
original first so it is not buried by the failure to report it.

Unifying them means the pre-Form phase now also calls
CodenameOneThread.handleException, which it did not before. That is deliberate:
the method only acts when Log.isCrashBound(), so a crash-bound application was
silently losing exceptions from that phase.

EdtExceptionReportingTest covers one collaborator per test rather than one
representative case, because the hazard is per call site and wrapping three of
four would look fixed. Verified non-vacuous: with the guard removed all four
fail, each naming its own collaborator -- including the default path, where an
application that registers nothing still dies, there on
ExceptionInInitializerError out of Dialog.show.

What this does NOT fix is whatever produced the original garbage exception. That
is pre-existing (identical stack on PR #5741), x86_64+glibc only (arm64 and musl
pass in the same run from the same zig cc), and the exception TYPE varies
between occurrences at a fixed site, which is the signature of reading garbage
rather than a logic error; the stack is semantically impossible too, since
callSeriallyOnIdle is not called from paintDirty. With this change the EDT
survives it, so the next occurrence logs and the suite continues instead of
stalling -- which is what will make that corruption diagnosable.

Core suite: 6,617 tests, no failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7923a81853

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/native-warnings/baseline-ios-sim-debug.txt
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@shai-almog

shai-almog commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 151 screenshots: 151 matched.

Native Android coverage

  • 📊 Line coverage: 9.24% (9184/99417 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.99% (47193/524920), branch 3.55% (1767/49739), complexity 3.52% (1868/53026), method 5.43% (1514/27888), class 10.89% (407/3736)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 9.24% (9184/99417 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.99% (47193/524920), branch 3.55% (1767/49739), complexity 3.52% (1868/53026), method 5.43% (1514/27888), class 10.89% (407/3736)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 207ms / native 303ms = 0.6x speedup
SIMD float-mul (64K x300) java 157ms / native 81ms = 1.9x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 137.000 ms
Base64 CN1 decode 113.000 ms
Base64 native encode 546.000 ms
Base64 encode ratio (CN1/native) 0.251x (74.9% faster)
Base64 native decode 438.000 ms
Base64 decode ratio (CN1/native) 0.258x (74.2% faster)
Image encode benchmark status skipped (SIMD unsupported)

Four occurrences of the Linux suite stall produced a hang-stacks.txt containing
seven sample headers and zero stacks. That is why the stall still has no root
cause: gdb is absent from the runner image, the install is best-effort with its
output discarded, and the IOException from ProcessBuilder.start() was caught by
a bare "catch (Exception ignore)". The file existed, was uploaded, and read as
though nothing had gone wrong.

A diagnostic that can quietly produce nothing is not a diagnostic. Both halves
now report:

- The capture compares the file length before and after gdb and, when nothing
  was written, says so together with gdb's exit code and whether gdb runs at
  all. Those two failure modes need different fixes -- a missing binary is a
  runner-image problem, a present binary that captured nothing is a ptrace or
  attach problem -- and they are indistinguishable in an empty file.
- The workflow no longer discards the install output, and states whether gdb
  ended up on PATH.

Still best-effort in both places, deliberately: a runner without gdb must not
turn a hang into a second, more confusing failure. It must just stop pretending
it looked.

gdbOnPath() verified against ground truth rather than assumed -- it answers
false on a machine with no gdb.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b4b816e7c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-native-warnings.py
shai-almog and others added 3 commits September 10, 2026 20:27
The 0x100000028 crash was diagnosed as far as it was only because this handler
prints faultAddr itself. Nothing downstream could have recovered it: the suite is
built -O3 with LTO, so gdb's post-mortem answers "No locals" and "No arguments"
for every frame of the core and reports every global as "unknown type". The one
piece of evidence that named the defect class came from here, and everything the
next step needs is missing from here too.

Two additions, both async-signal-safe and neither reading the faulting address,
which is unmapped by definition:

- The integer registers. They cost nothing and touch no memory, and they are the
  only place the faulting POINTER survives -- the address says a read went wrong,
  the register file says what the value WAS and which other register held the
  object it should have come from.
- The top 32 words of the faulting frame, clamped to the real stack top so it
  reads only mapped memory and cannot fault a second time.

The stack words are what separate the two remaining explanations for this crash.
An address whose low 32 bits are zero and bit 32 is set (0x100000000 here, plus a
0x28 field offset) is either a 64-bit value read as an object pointer or a 32-bit
write into a 64-bit object slot, and those are indistinguishable from the address
alone. An adjacent word holding the other half of the same 64-bit value says the
first; an intact pointer beside a clobbered one says the second.

The buffer sizing and read bounds are tested rather than eyeballed -- a signal
handler that overruns a stack buffer is worse than the fault it is reporting. The
worst case uses 23 bytes of the 64-byte buffer, and the frame dump clamps to 5
reads when only 5 words remain below the stack top.

Compiles only on the Linux legs, so CI is the first compile of the arch-specific
halves; the portable logic was exercised locally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gdb's post-mortem of the SIGSEGV answered "No locals" and "No arguments" for
every frame and "unknown type" for every global. That was read as LTO stripping
the information. It is not: the generated project compiles with -g1, which emits
line tables and function names and NOTHING about variables or types.

Measured rather than assumed, at -O3 on a struct-and-locals probe:

    -g1 : variable/parameter DIEs = 0 , type DIEs = 0
    -g3 : variable/parameter DIEs = 4 , type DIEs = 3

So the core was always fine and the DWARF simply did not describe the data. No
amount of post-mortem gdb could have recovered it, which is why four occurrences
produced a backtrace and never an explanation.

-g1 remains the default -- it is right for a shipping binary, where the companion
exists to turn an address back into a Java method, and the level is now a cache
variable so an unset build is byte-identical to before. The Linux suite sets
CN1_LINUX_FULL_DEBUG and gets -g3 into the <exe>.debug companion; the binary
itself is still --strip-all'd, so only the companion grows.

The core is also kept now. crash-stacks.txt is only ever the backtrace gdb could
produce in place; printing the object a faulting pointer came from, the slot
beside it, or the register that held it needs the core in hand. It is uploaded
with the stripped ELF it refers to and the .debug companion that decodes it,
compressed (zstd where available), and collected only when a core exists -- which
is only when the suite actually crashed. A README beside it gives the two
commands to open it.

This is what the outstanding question needs: 0x100000028 is either a 64-bit value
read as an object pointer or a 32-bit write into a 64-bit slot, and telling those
apart means reading the neighbouring slot, which means decoding the core.

Verified end to end on a scratch project: default configure compiles -g1, and
-DCN1_DEBUG_INFO_LEVEL=3 compiles -g3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The gate failed, and it failed correctly: one baselined warning kind no longer
reproduces, so the ratchet demanded the row be deleted rather than left to
describe a build nobody produces any more.

  generated|*|-Wincompatible-pointer-types-discards-qualifiers|passing ? to parameter of type ? discards qualifiers

That is the 9,125-instance category the operand-stack POP change removed. It is
gone from the iOS build entirely.

The S4 emitter work, measured on CI's own build rather than the local clean
target:

  warnings in the log      92,129  ->  2,201
  gating diagnostics       61,124  ->    989
  generated (distinct)      12/60,107 -> 3/144

-Wunused-variable in generated code is 98, which is what was predicted when the
baseline was deliberately left alone: the row survives because a residual from
other emitters still reproduces, and keying the ratchet on presence rather than
count is what kept that from being churn.

The port's 814 warnings are now the largest gating group. That was the point --
470 deprecations, 67 -Wshorten-64-to-32, 21 -Wint-conversion and 6
-Wunsupported-availability-guard were always there and were unreadable under
60,000 lines of generated-code noise.

Verified against this run's own log and manifest before pushing: the gate passes
with 156 entries and the injected-warning probe still fires.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1e5bf9cc9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CodenameOne/src/com/codename1/ui/Display.java Outdated
18 of the iOS port's 21 -Wint-conversion findings are one line repeated: a GLuint
initialised with NULL. A GL object name is an unsigned integer handle, not a
pointer, and 0 is its documented "no object" value; NULL is a pointer constant,
and initialising an integer with it is exactly what the warning reports.

Nothing was broken -- the two are the same bits on every target this builds for
-- but the compiler is correctly refusing to assume that, and the setting that
reports it (CLANG_WARN_INT_CONVERSION) is one of the five the iOS project turns
OFF. In current clang -Wint-conversion defaults to an ERROR, so what that
setting has been suppressing is a class that includes genuine pointer/integer
confusion; these 18 were the noise standing between it and being turned back on.

Left for their own change: the handful of JAVA_LONG <-> void* sites in
IOSNative.m and CodenameOne_GLViewController.m. Those are the deliberate "keep a
native peer in a Java long" idiom and want an explicit cast each, decided site by
site rather than swept.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acb6732339

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/native-warnings/baseline-ios-sim-debug.txt Outdated
shai-almog and others added 2 commits September 11, 2026 08:22
Second time the stale-entry rule has fired, and again correctly:

  port|Ports/iOSPort/nativeSources/CN1ES2compat.m|-Wint-conversion|incompatible pointer to integer conversion initializing ? (aka ?) with an expression of type ?

Initialising those 18 GL object names with 0 rather than NULL removed the kind
from that file entirely, so the row described a warning the build no longer
emits. -Wint-conversion across our code is 30 -> 12.

Verified against the run's own log and manifest: the gate passes with 155
entries and the injected-warning probe still fires.

Worth noting what this rule is buying. A baseline that only ever grows is an
allow-list; requiring that a fixed warning be deleted is what keeps it a record
of real remaining debt. Both times it has fired, the correct action was one line
removed and nothing else -- which is the cost it is meant to have.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The last nine -Wint-conversion sites in our code, each read rather than swept --
they are not one pattern, and treating them as one would have papered over the
two that were plain mistakes.

Four are a pointer constant used where an integer zero was meant, the same class
as the GL object names:

  defaultDatePickerDate = nil   x3   (a JAVA_LONG; the same file already
                                      writes `= 0` for it two lines away)
  __block JAVA_LONG outTexture = NULL

Four are the deliberate "keep a native peer in a JAVA_LONG" idiom, which is
sound on every 64-bit target this builds for and was simply never stated. The
read side already casts back -- `(void*)s->java_lang_String_nsString`,
`(Renderer*)(uintptr_t)renderer` -- so only the write side was silent:

  editStringAtImpl(..., n5, ...)        n5 is a long, the parameter is void*
  return (BRIDGE_CAST void*)resultGl    from a JAVA_LONG function
  networkError(..., peer, str)          peer is a void*, the parameter is long
  nnn->java_lang_String_nsString = str  an NSString* into a JAVA_LONG field

One was both a missing cast and a dead local: the block binds
`Renderer *r = (Renderer*)(uintptr_t)renderer` and never uses it, then passes
the uncast `renderer` to Renderer_produceAlphas. Using `r` fixes the conversion
and the unused variable together.

Deliberately untouched: `currentDatePickerDate = nil` in the same function, eight
times. That one really is an NSDate*.

This is what CLANG_WARN_INT_CONVERSION = NO has been hiding. In current clang
-Wint-conversion defaults to an ERROR, so the setting suppresses a class that
includes genuine pointer/integer confusion; nothing here turned out to be a live
bug, but that could only be established by reading all of them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e96c4253fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-native-warnings.py
Comment thread scripts/check-native-warnings.py
shai-almog and others added 4 commits September 11, 2026 12:21
build-test (8) failed with exit 124: `timeout 300 apt-get update` spent its whole
budget and was killed. The step runs under `-e`, so the job ended before Maven,
every module's SpotBugs report was therefore missing, and the quality gate failed
-- correctly, since a missing report means the analysis never ran -- for want of
an analysis rather than a finding.

scripts/ci/apt-get-install.sh exists for exactly this and three steps were not
using it. It bounds AND retries the index refresh, and it skips the apt round
trip entirely when every requested package is already present. libdbus-1-3 is
baked into the pr-ci-container image, so the common case becomes no network at
all -- this failure could not have happened through the helper.

All three converted rather than the one that failed today: sqlcipher and
gcc/gcc-mingw-w64-x86-64 carry the identical pattern and the identical exposure,
and their comments already said "bounded for the same reason as the libdbus
install above". Bounding was the previous answer to this and it is not enough on
its own -- a bounded hang is still a dead job, just a punctual one.

The helper uses sudo, which the container image installs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A code review raised eighteen findings on this PR. These are the ones that were
real, each verified against a real CI log rather than reasoned about:

PROVENANCE IS PER TRANSLATION. The manifest is reached through a static and was
never cleared, so a second translation in the same JVM -- which the integration
tests do repeatedly -- inherited every file the previous application recorded.
Reset now happens in Parser.cleanup(), where the rest of a translation's state
is already reset.

FILES THAT WERE GENERATED AND UNRECORDED. The clean target's cn1_resources.rc /
cn1_resources_table.c / cn1_resources_data.S, the on-device-debug sidecar
cn1_debug_symbols.c, and every concatenated_<n> unit. A warning in any of them
matched no manifest entry and no path rule, so the census would refuse the whole
build rather than guess. Concatenation is not a corner: macOS translates that way
unconditionally and iOS does under ios.superfastBuild.

DIAGNOSTICS THE GRAMMAR DROPPED SILENTLY -- the worst failure a census can have,
because the gate then reports clean. A column is optional ("path:line: warning:"),
a diagnostic can name a file and no line at all (Xcode's per-project warnings),
and a fileless diagnostic WITH a tool prefix is a real driver warning rather than
a path the transport lost -- the prefix is what separates the two. That last
grammar found one genuine warning this build had been emitting unseen, an asset
catalog missing its accent colour; it is baselined rather than hidden.

KEYS THAT COULD NOT SURVIVE THEIR OWN CONTENTS. A message containing "|" -- gcc's
"suggest parentheses around arithmetic in operand of |" -- produced a six-field
row that the reader truncated and the format check then rejected. And quoted
identifiers only collapsed for the ASCII apostrophe, so gcc's and Apple's Unicode
quotes left every distinct name as its own row.

ORDERING, which was wrong in both directions. Vendored and SDK paths now precede
the manifest, because it is keyed on a bare file name and a pod shipping
Renderer.h would otherwise be reported as the iOS port's. But the companion-target
marker must come AFTER it: a watch build copies the port natives, the runtime and
the bundled SQLite into watch-src, so watch-src/IOSNative.m is still the port.
Testing the directory first reclassified 435 diagnostics in a real build as
generated code, which would have hidden port warnings behind an emitter key. The
committed order reclassifies exactly zero.

Every new shape is in the parser fixture, so none of them can regress silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review finding, and a real weakness in the fix it was reviewing. Protecting the
dispatch thread with ONE enclosing try kept the thread alive but let the first
throwing reporter silence every later one: a CrashReporter that fails would take
impl.handleEDTException and the application's own error handler down with it, so
the application would never hear about an exception its port had already
recovered from. Reporting to four places should not be all-or-nothing.

Each step is now isolated from the others as well as from the loop, and a port
whose handleEDTException throws is no longer read as having HANDLED the
exception -- that would have swallowed it entirely rather than merely failing to
report it once.

Written out rather than routed through a helper taking a Runnable: this class
compiles at Java 5, so that means an anonymous inner class per step, and three of
them carry no outer state -- which SpotBugs reports as
SIC_INNER_SHOULD_BE_STATIC_ANON, and that gate allows no findings. The first
attempt produced exactly three.

Two more findings with it:

The probe's census is no longer published to the step summary. Redirecting stdout
never stopped it: the tool appends to GITHUB_STEP_SUMMARY directly, so every
successful run published a second census containing the synthetic warning the
probe injects -- 142 lines of it -- which reads as a real finding to anyone
looking at the summary. The variable is cleared for that invocation.

pr.yml re-includes the warning gate's own files. The parser self-test runs from
this workflow and nowhere else -- the legs that run the gate itself need a
compiler -- and `!scripts/**` meant a change to the parser, its fixture or a
baseline could merge without the one check that would have caught it ever
running. The same block already re-includes retry.sh and the apt helpers for
exactly this reason.

EdtExceptionReportingTest covers the new invariant in both directions and is
probe-verified: reverting to a single enclosing try fails it. Core suite 6,619
tests, no failures; SpotBugs 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The last two review findings on the census.

Swift was excluded from the completeness set while the generated iOS project puts
.swift files in Compile Sources and the sample carries one
(SwiftKotlinNativeImpl.swift, recorded as port). A build that compiled every
Objective-C unit and no Swift would have passed the check.

Including it needed a grammar, because Swift is announced unlike anything else:
the architecture comes second, and the line then carries either a
"Compiling\ A.swift,\ B.swift" summary followed by the paths, or the paths alone.
Taking a fixed position would have caught the first file of a batch and missed
the rest -- so every .swift path on the line is harvested. Verified on the real
log: coverage goes from "all 3142" to "all 3143" and still reports complete, and
the fixture asserts both files off one SwiftCompile line.

The other finding -- that completeness is measured against the PHONE manifest
only, so a companion watch or tv target could compile nothing and still pass --
is recorded as a known limitation rather than half-fixed. Diagnostics from a
companion are still attributed correctly; what is not verified is that it
compiled everything it has. Closing it means staging the companion's own manifest
from build-ios-app.sh and the builders, which is not a change to this tool.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66f7776d31

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// recorded. The warning census would then attribute a diagnostic to a source
// belonging to a different app, or report files that are not in the project
// at all.
ByteCodeTranslator.sourceManifest.reset();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reset the manifest before translation instead of during cleanup

Fresh evidence in this revision is that the reset was added to Parser.cleanup(), but Parser.writeOutput() unconditionally calls that method from its finally block after recording every generated source and after ByteCodeTranslator has recorded the copied port/runtime sources. The Apple handler then records only xmlvm.h before writing the manifest, so the iOS census receives a manifest missing virtually every compiled source: completeness can misleadingly cover zero expected units, and the first ordinary source warning becomes unattributed and fails the workflow. The new recordsSourceProvenanceOutsideTheSourceDirectory test also explicitly requires the generated, runtime, and port entries that this reset erases; reset once at the start of each top-level translation instead.

Useful? React with 👍 / 👎.

The manifest reset landed in Parser.cleanup(), which runs from the `finally` of
Parser.writeOutput() -- BEFORE the output handler writes the manifest. So it
discarded the translation's own records rather than the previous one's, and the
manifest went out naming no generated files at all. CI caught it:
clean-target (arm64) failed on recordsSourceProvenanceOutsideTheSourceDirectory,
the test written for exactly this, naming HelloWorld.c and
cn1_class_method_index.c as unrecorded.

It belongs at the START of a translation, and that is also the property actually
wanted: what must not leak is the PREVIOUS application's files. Moved to
ByteCodeTranslator.main, which is how every caller enters, including the tests.

I should have caught this locally. The test existed and I did not re-run it after
adding the reset -- the translator built, the core suite passed, and neither
touches this.

The guard needed rewriting too, and this is the more useful half. I first added a
cross-translation assertion to the integration test: translate twice, assert the
second manifest does not name the first project's file. It passed with the reset
REMOVED, because runTranslatorImpl hands every call a
`new URLClassLoader(urls, null)` -- each translation gets its own copy of the
statics, so the leak is unobservable from that harness. A test that cannot fail is
worse than no test, so it is gone, with a note saying why.

SourceManifestTest covers the contract where it can actually fail, and is
probe-verified: making reset() a no-op fails it with "expected: <0> but was: <3>".
It also pins renameGenerated, which the clean target relies on when it rewrites
cn1_class_method_index.m to .c.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c237bc342

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

port|Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m|-Wenum-conversion|implicit conversion from enumeration type ? (aka ?) to different enumeration type ? (aka ?)|1 instance(s) when the baseline was written; not yet triaged
port|Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m|-Wenum-conversion|implicit conversion from enumeration type ? to different enumeration type ? (aka ?)|4 instance(s) when the baseline was written; not yet triaged
port|Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m|-Wincompatible-pointer-types|incompatible pointer types initializing ? (aka ?) with an expression of type ? (aka ?)|2 instance(s) when the baseline was written; not yet triaged
port|Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m|-Wint-conversion|incompatible pointer to integer conversion assigning to ? (aka ?) from ?|3 instance(s) when the baseline was written; not yet triaged

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the fixed date-picker conversion baseline

On the next cold ios-sim-debug census, this key will be stale: the three defaultDatePickerDate = nil assignments that produced these three pointer-to-integer diagnostics were all changed to 0 in CodenameOne_GLViewController.m. Because stale entries are failures, the warning gate will reject the build even though the warnings were intentionally fixed; remove or regenerate this baseline row.

Useful? React with 👍 / 👎.

Comment on lines +135 to +137
port|Ports/iOSPort/nativeSources/IOSNative.m|-Wint-conversion|incompatible pointer to integer conversion initializing ? (aka ?) with an expression of type ?|1 instance(s) when the baseline was written; not yet triaged
port|Ports/iOSPort/nativeSources/IOSNative.m|-Wint-conversion|incompatible pointer to integer conversion passing ? to parameter of type ? (aka ?)|2 instance(s) when the baseline was written; not yet triaged
port|Ports/iOSPort/nativeSources/IOSNative.m|-Wint-conversion|incompatible pointer to integer conversion returning ? from a function with result type ? (aka ?)|1 instance(s) when the baseline was written; not yet triaged

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the IOSNative conversions fixed by explicit casts

These baseline keys no longer reproduce after the accompanying IOSNative.m changes: the JAVA_LONG initialized from NULL, the pointer passed to the Java callback, and the pointer returned from the blur function now use 0 or explicit uintptr_t/JAVA_LONG conversions. The next cold census will therefore classify these entries as stale and fail the iOS warning-gate stage; regenerate the baseline or delete the eliminated rows.

Useful? React with 👍 / 👎.

port|Ports/iOSPort/nativeSources/UIWebViewEventDelegate.m|-Wunused-variable|unused variable ?|1 instance(s) when the baseline was written; not yet triaged
port|Ports/iOSPort/nativeSources/WebSocketImpl.m|-Wunsupported-availability-guard|@available does not guard availability here; use if (@available) instead|6 instance(s) when the baseline was written; not yet triaged
runtime|cn1_globals.m|-Wformat|format specifies type ? but the argument has type ?|2 instance(s) when the baseline was written; not yet triaged
runtime|cn1_globals.m|-Wint-conversion|incompatible pointer to integer conversion assigning to ? (aka ?) from ?|2 instance(s) when the baseline was written; not yet triaged

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the fixed NSString assignment baseline

The sole implicit NSString *-to-JAVA_LONG assignment in fromNSString() now casts through uintptr_t, eliminating the diagnostic represented by this key in each staged target. On the next cold ios-sim-debug census this row will be reported as stale, causing the gate to fail despite the warning having been fixed; remove or regenerate the entry.

Useful? React with 👍 / 👎.

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