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?

@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview7 milestone Jul 13, 2026
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
…tive (#130543)

## Summary

Fixes the browser-wasm **CoreCLR** library test leg
(`WasmTestOnChrome-CLR` → `System.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 `33` → `34`
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.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Jul 16, 2026
@github-actions github-actions Bot mentioned this pull request Aug 6, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.