Skip to content

ParparVM: remove dead C# target, add Windows LLVM (clang-cl) build + CI#5137

Merged
shai-almog merged 6 commits into
masterfrom
parparvm-windows-llvm-build
Jun 1, 2026
Merged

ParparVM: remove dead C# target, add Windows LLVM (clang-cl) build + CI#5137
shai-almog merged 6 commits into
masterfrom
parparvm-windows-llvm-build

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Context

ParparVM's ByteCodeTranslator.OutputType had four backends; the C# target was dead (generateCSharpCode() returned "", appendMethodCSharp() was an empty // todo stub with zero callers — abandoned years ago per vm/README.md). Separately, there was no Windows build of the VM. The existing clean target is already an LLVM/CMake portable-C path (proven end-to-end on Linux/mac by CleanTargetIntegrationTest).

This PR removes the dead C# target and lays the groundwork to build the clean target on Windows using LLVM (clang-cl / MSVC ABI) rather than Visual Studio's cl.exe, plus a CI runner that exercises it. This is preliminary work for a future Windows desktop port (separate task) — targeting the MSVC ABI now means building the Win32 compatibility layer the runtime needs.

Note: the legacy UWP maven/.../src/main/csharp native-interface stubs are an unrelated old Win10 port and are intentionally not touched.

Changes

Remove the dead C# target

  • Delete OUTPUT_TYPE_CSHARP, its arg-parse branch, help text, the generateCSharpCode()/appendMethodCSharp() stubs, and the Parser C# write branch.
  • Unrecognized output tokens now route explicitly to handleDefaultOutput (previously they silently fell through to the iOS default — a latent bug). The default-branch test is repointed from "csharp" to "unknown".

Win32 compatibility shim (the substantive deliverable)

  • New cn1_win_compat.h/.c (entirely #ifdef _WIN32) maps the runtime's exact POSIX surface onto Win32: pthread mutex→SRWLOCK, cond→CONDITION_VARIABLE, TLS keys→Tls*, pthread_create_beginthreadex, sched→Get/SetThreadPriority, plus usleep/gettimeofday.
  • The header is windows.h-free (layout-mirrored lock structs, _Static_assert-checked against the real Win32 types in the .c) so it's safe to pull into every translated unit via cn1_globals.h.
  • POSIX includes in cn1_globals.h/.m and nativeMethods.m are guarded; handleCleanOutput always emits the shim (inert off-Windows); writeCmakeProject targets C11 (for <stdatomic.h> / _Static_assert).

Windows-aware test harness

  • clang-cl + Ninja generator, .exe suffix, and no libm link under MSVC.

Windows CI runner

  • .github/workflows/parparvm-tests-windows.yml runs the vm test suite on windows-latest with the MSVC env, clang-cl and Ninja.

Testing

Full vm suite on macOS: 826 run / 0 failures / 0 errors, including CleanTargetIntegrationTest (13/0/0) which translates Java→C, compiles with clang via CMake, and runs the binary — confirming the C# removal, C11 bump and always-copied shim don't regress the existing POSIX path.

The clang-cl-on-Windows path is first exercised by the new workflow in CI; expect to iterate there (most likely a narrow <stdatomic.h>/linker detail, fixable without touching the POSIX paths).

🤖 Generated with Claude Code

Removes the abandoned C# output target and lays the groundwork for a Windows
build of the portable "clean" C target using LLVM (clang-cl / MSVC ABI),
preliminary to a future Windows desktop port.

- Remove OUTPUT_TYPE_CSHARP and its empty generateCSharpCode()/
  appendMethodCSharp() stubs, arg parsing, help text and Parser write branch.
  Unrecognized output tokens now route explicitly to handleDefaultOutput
  instead of silently falling through to the iOS default.
- Add a self-contained Win32 POSIX shim (cn1_win_compat.h/.c, gated on
  _WIN32) mapping the runtime's pthread/usleep/gettimeofday usage onto Win32
  primitives (SRWLOCK, CONDITION_VARIABLE, Tls*, _beginthreadex,
  Get/SetThreadPriority). The header is windows.h-free so it can be pulled
  into every translated unit via cn1_globals.h; layout-mirrored lock structs
  are _Static_assert-checked against the real Win32 types. POSIX includes in
  cn1_globals.h/.m and nativeMethods.m are guarded; handleCleanOutput always
  emits the shim and writeCmakeProject targets C11.
- Make the clean-target test harness Windows-aware: clang-cl + Ninja
  generator, .exe suffix, and no libm link under MSVC.
- Add .github/workflows/parparvm-tests-windows.yml running the vm test suite
  on windows-latest with the MSVC env, clang-cl and Ninja.

Verified on macOS: full vm suite 826 run / 0 failures, including
CleanTargetIntegrationTest (13/0) which compiles and runs translated C.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Cloudflare Preview

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 31, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 31, 2026

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

Benchmark Results

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

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 704.000 ms
Base64 CN1 encode 1180.000 ms
Base64 encode ratio (CN1/native) 1.676x (67.6% slower)
Base64 native decode 337.000 ms
Base64 CN1 decode 877.000 ms
Base64 decode ratio (CN1/native) 2.602x (160.2% slower)
Base64 SIMD encode 386.000 ms
Base64 encode ratio (SIMD/native) 0.548x (45.2% faster)
Base64 encode ratio (SIMD/CN1) 0.327x (67.3% faster)
Base64 SIMD decode 363.000 ms
Base64 decode ratio (SIMD/native) 1.077x (7.7% slower)
Base64 decode ratio (SIMD/CN1) 0.414x (58.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 57.000 ms
Image createMask (SIMD on) 8.000 ms
Image createMask ratio (SIMD on/off) 0.140x (86.0% faster)
Image applyMask (SIMD off) 119.000 ms
Image applyMask (SIMD on) 55.000 ms
Image applyMask ratio (SIMD on/off) 0.462x (53.8% faster)
Image modifyAlpha (SIMD off) 116.000 ms
Image modifyAlpha (SIMD on) 58.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.500x (50.0% faster)
Image modifyAlpha removeColor (SIMD off) 137.000 ms
Image modifyAlpha removeColor (SIMD on) 70.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.511x (48.9% faster)
Image PNG encode (SIMD off) 991.000 ms
Image PNG encode (SIMD on) 743.000 ms
Image PNG encode ratio (SIMD on/off) 0.750x (25.0% faster)
Image JPEG encode 403.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 31, 2026

JavaScript port screenshot updates

Compared 73 screenshots: 64 matched, 9 updated.

  • DialogTheme_dark — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    DialogTheme_dark
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as DialogTheme_dark.png in workflow artifacts.

  • DialogTheme_light — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    DialogTheme_light
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as DialogTheme_light.png in workflow artifacts.

  • FloatingActionButtonTheme_dark — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    FloatingActionButtonTheme_dark
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as FloatingActionButtonTheme_dark.png in workflow artifacts.

  • FloatingActionButtonTheme_light — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    FloatingActionButtonTheme_light
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as FloatingActionButtonTheme_light.png in workflow artifacts.

  • ListTheme_light — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    ListTheme_light
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as ListTheme_light.png in workflow artifacts.

  • MultiButtonTheme_dark — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    MultiButtonTheme_dark
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as MultiButtonTheme_dark.png in workflow artifacts.

  • MultiButtonTheme_light — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    MultiButtonTheme_light
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as MultiButtonTheme_light.png in workflow artifacts.

  • SpanLabelTheme_light — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    SpanLabelTheme_light
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as SpanLabelTheme_light.png in workflow artifacts.

  • ToolbarTheme_dark — updated screenshot. Screenshot differs (375x667 px, bit depth 8).

    ToolbarTheme_dark
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as ToolbarTheme_dark.png in workflow artifacts.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 31, 2026

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 71000 ms
Simulator Boot (Run) 0 ms
App Install 11000 ms
App Launch 4000 ms
Test Execution 323000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 751.000 ms
Base64 CN1 encode 1983.000 ms
Base64 encode ratio (CN1/native) 2.640x (164.0% slower)
Base64 native decode 501.000 ms
Base64 CN1 decode 1343.000 ms
Base64 decode ratio (CN1/native) 2.681x (168.1% slower)
Base64 SIMD encode 792.000 ms
Base64 encode ratio (SIMD/native) 1.055x (5.5% slower)
Base64 encode ratio (SIMD/CN1) 0.399x (60.1% faster)
Base64 SIMD decode 598.000 ms
Base64 decode ratio (SIMD/native) 1.194x (19.4% slower)
Base64 decode ratio (SIMD/CN1) 0.445x (55.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 139.000 ms
Image createMask (SIMD on) 9.000 ms
Image createMask ratio (SIMD on/off) 0.065x (93.5% faster)
Image applyMask (SIMD off) 124.000 ms
Image applyMask (SIMD on) 57.000 ms
Image applyMask ratio (SIMD on/off) 0.460x (54.0% faster)
Image modifyAlpha (SIMD off) 155.000 ms
Image modifyAlpha (SIMD on) 77.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.497x (50.3% faster)
Image modifyAlpha removeColor (SIMD off) 204.000 ms
Image modifyAlpha removeColor (SIMD on) 104.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.510x (49.0% faster)
Image PNG encode (SIMD off) 1092.000 ms
Image PNG encode (SIMD on) 840.000 ms
Image PNG encode ratio (SIMD on/off) 0.769x (23.1% faster)
Image JPEG encode 488.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 31, 2026

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 65000 ms
Simulator Boot (Run) 0 ms
App Install 11000 ms
App Launch 12000 ms
Test Execution 308000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 859.000 ms
Base64 CN1 encode 2582.000 ms
Base64 encode ratio (CN1/native) 3.006x (200.6% slower)
Base64 native decode 776.000 ms
Base64 CN1 decode 1916.000 ms
Base64 decode ratio (CN1/native) 2.469x (146.9% slower)
Base64 SIMD encode 779.000 ms
Base64 encode ratio (SIMD/native) 0.907x (9.3% faster)
Base64 encode ratio (SIMD/CN1) 0.302x (69.8% faster)
Base64 SIMD decode 919.000 ms
Base64 decode ratio (SIMD/native) 1.184x (18.4% slower)
Base64 decode ratio (SIMD/CN1) 0.480x (52.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 62.000 ms
Image createMask (SIMD on) 16.000 ms
Image createMask ratio (SIMD on/off) 0.258x (74.2% faster)
Image applyMask (SIMD off) 133.000 ms
Image applyMask (SIMD on) 61.000 ms
Image applyMask ratio (SIMD on/off) 0.459x (54.1% faster)
Image modifyAlpha (SIMD off) 219.000 ms
Image modifyAlpha (SIMD on) 86.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.393x (60.7% faster)
Image modifyAlpha removeColor (SIMD off) 257.000 ms
Image modifyAlpha removeColor (SIMD on) 96.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.374x (62.6% faster)
Image PNG encode (SIMD off) 1627.000 ms
Image PNG encode (SIMD on) 1252.000 ms
Image PNG encode ratio (SIMD on/off) 0.770x (23.0% faster)
Image JPEG encode 1120.000 ms

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 31, 2026

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 715 total, 0 failed, 3 skipped

Benchmark Results

  • Execution Time: 10170 ms

  • Hotspots (Top 20 sampled methods):

    • 20.62% java.lang.String.indexOf (362 samples)
    • 19.82% com.codename1.tools.translator.Parser.isMethodUsed (348 samples)
    • 13.84% java.util.ArrayList.indexOf (243 samples)
    • 8.37% com.codename1.tools.translator.Parser.addToConstantPool (147 samples)
    • 5.92% java.lang.Object.hashCode (104 samples)
    • 2.85% java.lang.System.identityHashCode (50 samples)
    • 2.16% com.codename1.tools.translator.ByteCodeClass.updateAllDependencies (38 samples)
    • 1.82% com.codename1.tools.translator.BytecodeMethod.appendMethodSignatureSuffixFromDesc (32 samples)
    • 1.77% com.codename1.tools.translator.ByteCodeClass.calcUsedByNative (31 samples)
    • 1.59% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (28 samples)
    • 1.54% java.lang.StringBuilder.append (27 samples)
    • 0.97% com.codename1.tools.translator.Parser.cullMethods (17 samples)
    • 0.91% com.codename1.tools.translator.ByteCodeClass.markDependent (16 samples)
    • 0.74% java.io.FileOutputStream.writeBytes (13 samples)
    • 0.74% com.codename1.tools.translator.ByteCodeClass.isDefaultInterfaceMethod (13 samples)
    • 0.74% com.codename1.tools.translator.BytecodeMethod.isMethodUsedByNative (13 samples)
    • 0.74% java.lang.StringCoding.encode (13 samples)
    • 0.63% com.codename1.tools.translator.BytecodeMethod.optimize (11 samples)
    • 0.63% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (11 samples)
    • 0.57% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (10 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 and others added 5 commits May 31, 2026 21:12
The runner was executing the entire vm suite (~1h, and it includes the
JavaScript integration tests which need Node that this workflow does not
install), so it appeared stuck. Scope it to CleanTargetIntegrationTest, which
is what actually proves the clang-cl/LLVM Windows build works (translate
Java -> C -> cmake/clang-cl -> run). The rest of the suite is platform-agnostic
Java already covered on Linux by parparvm-tests.yml. Add a 45m job timeout as a
backstop.

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

With -am, surefire also runs in the upstream ByteCodeTranslator module where
-Dtest=CleanTargetIntegrationTest matches nothing, which aborts the build.
failIfNoTests does not cover the -Dtest specified-tests case in surefire 3.x;
surefire.failIfNoSpecifiedTests does.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PowerShell split the dotted -Dsurefire.failIfNoSpecifiedTests property at the
'.', so Maven saw a bogus lifecycle phase. Quoting passes them as literal
tokens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On Windows the escaped-backslash source-root path produced glob results like
C:\Users\... which CMake rejects as invalid string escapes ('\U') when
expanded into add_executable/add_library. Forward slashes are accepted by CMake
on all platforms; this is a no-op on macOS/Linux. Fixes the clean-target
configure failure under clang-cl on Windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
clang-cl flagged these POSIX functions (used by the date/timezone runtime in
nativeMethods) as undeclared under the MSVC ABI. Add static-inline wrappers over
the MSVC equivalents (_putenv_s, _mkgmtime, localtime_s). Gated on _WIN32, so a
no-op elsewhere.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog merged commit ca3b858 into master Jun 1, 2026
23 of 24 checks passed
@shai-almog shai-almog deleted the parparvm-windows-llvm-build branch June 1, 2026 01:08
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