Skip to content

[wasm] Fix CoreCLR P/Invoke EntryCount for libSystem.Globalization.Native#130543

Merged
lewing merged 1 commit into
mainfrom
lewing-fix-coreclr-wasm-globalization-pinvoke-c
Jul 11, 2026
Merged

[wasm] Fix CoreCLR P/Invoke EntryCount for libSystem.Globalization.Native#130543
lewing merged 1 commit into
mainfrom
lewing-fix-coreclr-wasm-globalization-pinvoke-c

Conversation

@lewing

@lewing lewing commented Jul 11, 2026

Copy link
Copy Markdown
Member

Summary

Fixes the browser-wasm CoreCLR library test leg (WasmTestOnChrome-CLRSystem.Globalization.Extensions.Tests), failing on main since 2026-07-09 with:

System.DllNotFoundException : Unable to load shared library 'libSystem.Globalization.Native' ...
dynamic linking not enabled
   at Interop.Globalization.ToUnicode(...)
   at System.Globalization.IdnMapping.IcuTryGetUnicodeCore(...)

Tracked by #130479 (blocking-clean-ci).

Root cause

#130140 added GlobalizationNative_InitOrdinalLowerCasingPage to the generated callhelpers-pinvoke.cpp P/Invoke tables (browser + wasi) — correctly inserting the sorted entry and its extern "C" declaration — but did not update the hard-coded EntryCount in s_PInvokeTables (left at 33, now 34 entries).

minipal_resolve_dllimport (src/native/minipal/entrypoints.h) linearly scans entries[0 .. count-1]. With count = 33 over the 34-entry table, the last entry — GlobalizationNative_ToUnicode — became unreachable, so its P/Invoke resolved to NULL and fell back to dlopen (unsupported for CoreCLR-wasm) → DllNotFoundException. This is why only IdnMapping.GetUnicode/ToUnicode tests failed while GetAscii (ToAscii, index 32, still in range) kept passing.

The generator emits this count from the table length, so 34 is exactly what a regeneration produces; #130140 hand-edited the generated file without re-running it.

Fix

Bump the libSystem.Globalization.Native EntryCount from 3334 in both:

  • src/coreclr/vm/wasm/browser/callhelpers-pinvoke.cpp
  • src/coreclr/vm/wasm/wasi/callhelpers-pinvoke.cpp

All other module counts already match their tables (verified in both files).

Regression window (bisected on main, definition 129)

Build SHA LibraryTestsCoreCLR
1500867 (Jul 9 08:00) 0f907bfa (no #130140) ✅ pass
1502091 (Jul 9 20:00) 6c584914 (has #130140) ❌ fail — same signature

Emscripten 5.0.6/LLVM23 (Jun 25) and -O3 (#130111, Jul 2) were ruled out — the leg stayed green with both for two weeks.

Verification

  • Native reproduction against the real minipal/entrypoints.h: ToUnicode resolves NULL at count 33 and FOUND at count 34; ToAscii resolves at 33 (matches the observed pass/fail split).
  • The browser-wasm CoreCLR WasmTestOnChrome-CLR CI leg exercises this end-to-end.

cc @tarekgh @pavelsavara @lewing

Note

Root-cause investigation and this fix were produced with GitHub Copilot.

…tive

#130140 added GlobalizationNative_InitOrdinalLowerCasingPage to the generated
callhelpers-pinvoke.cpp tables (browser and wasi) but did not update the
hard-coded EntryCount in s_PInvokeTables (33 -> 34).

minipal_resolve_dllimport linearly scans entries[0 .. count-1], so with a count
of 33 over the now-34-entry table the last entry, GlobalizationNative_ToUnicode,
became unreachable. Every IdnMapping.GetUnicode P/Invoke therefore resolved to
NULL and fell back to dlopen ("dynamic linking not enabled"), throwing
DllNotFoundException and breaking the browser-wasm CoreCLR library test leg
(System.Globalization.Extensions.Tests) starting 2026-07-09.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 11, 2026 03:43
@lewing lewing temporarily deployed to copilot-pat-pool July 11, 2026 03:43 — with GitHub Actions Inactive
@lewing lewing temporarily deployed to copilot-pat-pool July 11, 2026 03:44 — with GitHub Actions Inactive
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

@lewing lewing had a problem deploying to copilot-pat-pool July 11, 2026 03:44 — with GitHub Actions Failure
@lewing lewing temporarily deployed to copilot-pat-pool July 11, 2026 03:45 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the CoreCLR WASM P/Invoke override tables to correctly report the number of exported entrypoints for libSystem.Globalization.Native, ensuring the resolver can reach the final entry in the table.

Changes:

  • Bump EntryCount for libSystem.Globalization.Native from 33 to 34 in the browser WASM CoreCLR callhelpers P/Invoke table.
  • Bump EntryCount for libSystem.Globalization.Native from 33 to 34 in the WASI CoreCLR callhelpers P/Invoke table.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/coreclr/vm/wasm/browser/callhelpers-pinvoke.cpp Updates s_PInvokeTables entry count for libSystem.Globalization.Native to match the 34-entry s_libSystem_Globalization_Native table.
src/coreclr/vm/wasm/wasi/callhelpers-pinvoke.cpp Updates s_PInvokeTables entry count for libSystem.Globalization.Native to match the 34-entry s_libSystem_Globalization_Native table.

@lewing lewing temporarily deployed to copilot-pat-pool July 11, 2026 03:46 — with GitHub Actions Inactive
@lewing lewing temporarily deployed to copilot-pat-pool July 11, 2026 03:46 — with GitHub Actions Inactive
@lewing lewing enabled auto-merge (squash) July 11, 2026 03:57
@lewing

lewing commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

/ba-g fast merging ci breakage

@lewing lewing merged commit 7db4382 into main Jul 11, 2026
28 of 54 checks passed
@lewing lewing deleted the lewing-fix-coreclr-wasm-globalization-pinvoke-c branch July 11, 2026 03:58
@pavelsavara

Copy link
Copy Markdown
Member

Thanks!


static PInvokeTable s_PInvokeTables[] = {
{"libSystem.Globalization.Native", s_libSystem_Globalization_Native, 33},
{"libSystem.Globalization.Native", s_libSystem_Globalization_Native, 34},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we use a sizeof(s_libSystem_Globalization_Native) / sizeof(Entry) instead of manually keeping track of the count?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants