Skip to content

feat(libSceLibcInternal): implement the messages<char> open, get, close and do_get members - #15753

Closed
B-Howell wants to merge 1 commit into
boykopovar:mainfrom
B-Howell:feat/r3-messages-char
Closed

B-Howell wants to merge 1 commit into
boykopovar:mainfrom
B-Howell:feat/r3-messages-char

Conversation

@B-Howell

@B-Howell B-Howell commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

What

Implements four libSceLibcInternal exports of std::messages<char> that threw NotImplemented through the Pending4_003-006 stubs in Export.cpp:

NID Name
U2t+WvMQj8A _ZNKSt8messagesIcE4openERKSsRKSt6locale (open)
XxsPrrWJ52I _ZNKSt8messagesIcE3getEiiiRKSs (get)
EeBQ7253LkE _ZNKSt8messagesIcE5closeEi (close)
vbgCuYKySLI _ZNKSt8messagesIcE6do_getEiiiRKSs (do_get)

The stubs are replaced by functions with the mangled names in the new Messages.cpp; the NID of each _nid_postfix name is the one the stub exported (checked with the SHA-1 NID computation).

  • open, get and close call do_open, do_get and do_close through the facet's vtable and return their results, as ISO C++ [locale.messages.members] specifies ("Returns: do_open(name, loc)", "Returns: do_get(cat, set, msgid, dfault)", "Effects: Calls do_close(cat)"). A null facet or a facet without a vtable throws std::invalid_argument.
  • GuestLocale::MessagesVtable (libc/include/GuestLocale.hpp) places do_open at 0x20, do_get at 0x28 and do_close at 0x30 after the four facet slots, with static_asserts. Seven virtual slots plus offset-to-top and typeinfo give the nine-slot, 72-byte _ZTVSt8messagesIcE that feat(libc): export the messages facet vtable as data #10158 measured on a console libc.prx.
  • do_get returns a copy of the default message for every catalog, set and message id, as Dinkumware's xlocmes does. microsoft/STL stl/inc/xlocmes L87-L90 at e1ed302683e5e822f663fbb0f44cee7e9ddc6af0:
        virtual string_type __CLR_OR_THIS_CALL do_get(catalog, int, int,
            const string_type& _Dflt) const { // get message from set in catalog (return default)
            return _Dflt;
        }
    No catalog can be open, since do_open returns -1 (the same file, L82-L84, and feat(libSceLibcInternal): answer the codecvt and messages queries as firmware 13.42 does #15582 for firmware 13.42), so [locale.messages.virtuals] only leaves the default. The result is built the way collate::do_transform builds one (inline capacity 15, heap capacity length | 15, GuestLocale::AllocateStringStorage, the 0x28-byte GuestLocale::String). The allocator word at offset 0 is left alone and embedded null characters are copied. A null default or result throws std::invalid_argument.
  • libc gets two helpers, GuestLocale::StringData and GuestLocale::AssignString, declared in GuestLocale.hpp and defined at the end of LocaleSupport.cpp, so libSceLibcInternal adds no libc export (the feat(libSceLibcInternal): implement the numpunct<char> members #14373 pattern). They take the inline capacity from sizeof(String::buffer), so they still build once feat(libSceLibcInternal): implement basic_string erase, append, assign, _Xran and _Xlen #15692 moves the file-local capacity constants into the header.
  • The four entries under "Additional PS5 3.20 import declarations" in docs/dev/debt/libSceLibcInternal.md are removed. One Functional entry records that do_get follows Dinkumware and that the console body was not disassembled.

Progress (tools/progress.py collect_libraries(), origin/main b11c7bf84f vs this branch): done 9921 -> 9925 (+4), todo 27225 -> 27221 (-4), no new todo. libSceLibcInternal done 92 -> 96 and todo 1045 -> 1041; the four names above move from todo to done.

Tested

No title or homebrew run. New guest test guest_libc_internal_messages (core/libs/tests/GuestLibcInternalMessages.cpp):

  • open, get and close on a facet whose test vtable records its calls: each forwards its own arguments and returns the virtual's result, and none calls another virtual.
  • get through the real do_get returns the default.
  • do_get copies defaults of 0, 5, 3 (with an embedded null), 15, 16, 40 and 4095 characters. It checks size, capacity (15, 15, 15, 15, 31, 47, 4095), the terminator, inline or allocated storage, one allocation for each long copy, and that the source and the allocator word are unchanged.
  • Null facet, missing vtable, null default and null result throw std::invalid_argument, and a rejected call never reaches a virtual.

The test regex is ^(guest_libc_internal_messages|guest_collate|guest_locale|conventions_.*|debt_split|public_headers)$: 46 tests, of which conventions_* and debt_split are self-tests of the conventions and debt-split checkers.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

🤖 Generated with Claude Code

…se and do_get members

open, get and close call do_open, do_get and do_close through the facet's
vtable, as [locale.messages.members] specifies. do_get returns a copy of
the default message, as Dinkumware's xlocmes does, since do_open never
opens a catalog. GuestLocale gains the messages vtable layout and the
StringData and AssignString helpers that build the copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JJenkx

JJenkx commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Windows check of head a4689b14e6, which already contains main b11c7bf84f.

Setup: Windows 11 Enterprise 22621, WinLibs GCC 15.2 UCRT, Release. The hosted Windows check does not run this test on pull requests.

  • guest_libc_internal_messages passes in 3 of 3 runs.

AI-assisted: yes.

@github-actions github-actions Bot added the open PR limit Closed over the open PR limit: 1 without merged PRs, 20 with at least 1, none from 20 label Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

Thank you for your contribution! Authors with no pull requests merged into main can have 1 open pull request at a time, authors with at least 1 merged can have 20, and from 20 merged there is no limit. This PR has been automatically closed and labeled "open PR limit" because that limit was reached. This is not a judgment of the quality of your changes: reopen it once one of your open pull requests is merged or closed.

@github-actions github-actions Bot closed this Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

Progress report (b11c7bf → a4689b1)

📈 System libraries: 26.72% (+0.01%, +4 implemented, -4 removed functions)

✅ 4 implemented
Library Name
libSceLibcInternal _ZNKSt8messagesIcE3getEiiiRKSs_nid_postfix
libSceLibcInternal _ZNKSt8messagesIcE4openERKSsRKSt6locale_nid_postfix
libSceLibcInternal _ZNKSt8messagesIcE5closeEi_nid_postfix
libSceLibcInternal _ZNKSt8messagesIcE6do_getEiiiRKSs_nid_postfix
🗑️ 4 removed
Library Name
libSceLibcInternal sceLibcInternalPending4_003_nid_no_patch
libSceLibcInternal sceLibcInternalPending4_004_nid_no_patch
libSceLibcInternal sceLibcInternalPending4_005_nid_no_patch
libSceLibcInternal sceLibcInternalPending4_006_nid_no_patch

Changed libraries (implemented exports)

Library Before After Change
libSceLibcInternal 92/1137 (8.09%) 96/1137 (8.44%) +0.35%

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

Labels

open PR limit Closed over the open PR limit: 1 without merged PRs, 20 with at least 1, none from 20

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants