string.c: answer an ASCII-case build from the header's fallback - #7222
Conversation
`include/mruby/internal.h` defines `mrb_str_case_convert_unicode()` as `(-1)` for a build that compiles no case tables, but its guard asked only about `MRB_UTF8_STRING`. A build defining `MRB_USE_ASCII_CASE` keeps `MRB_UTF8_STRING` and drops the tables, so it took the declared side of that guard and `src/string.c` had to supply a body for it, which did nothing but return the same `-1` the header already had. Two spellings of one answer, and the one costing a call and return per `downcase`, `upcase`, `capitalize`, `swapcase` and `casecmp?` was the one such a build took. Widen the guard to the condition the tables are compiled under, and the out-of-line stub goes away whole. All seven call sites pass plain locals and read the result as `int uc = ...; if (uc >= 0)` or `... < 0`, so a macro evaluating none of its arguments answers each of them as before. Built full-core with `MRB_USE_ASCII_CASE` (gcc 15.2.0, x86_64): | | assertions | .text | |----------------|------------|-----------| | before | 2319, KO 0 | 1,266,102 | | after | 2319, KO 0 | 1,265,862 | full-core with `MRB_UTF8_STRING` and full-core reading bytes are both unchanged: 2325 and 2217 assertions, KO 0.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan includes up to 8 reviews per rolling hour; 3 remain after this review. 📝 WalkthroughWalkthroughThe build guards for ChangesUnicode case conversion guards
Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: ⚪ Minimal · up to This localized build-configuration change aligns the fallback behavior with the configurations that omit Unicode case tables, with no actionable merge-blocking risk remaining after normal checks. Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
include/mruby/internal.halready answers-1for a build that compiles nocase tables:
The guard asks only about
MRB_UTF8_STRING, but that is not the condition thetables are compiled under.
MRB_USE_ASCII_CASEkeepsMRB_UTF8_STRINGanddrops the tables, so such a build takes the declared side of the guard, and
src/string.chas to supply a body for the promise:Two spellings of one answer, and the one costing a call and a return is the one
that build takes.
The change
Widen the guard to the condition the tables are actually compiled under, and
the
#elifarm goes away whole:That condition is the one
src/string.copens the walk with and the oneinclude/mruby/internal.halready uses a few lines below for the codepointaccessors, so the header now names the tables the same way in both places.
All seven call sites pass plain locals, so a macro evaluating none of its
arguments answers each of them as before:
src/string.cmrb_str_capitalize_bang(),mrb_str_downcase_bang(),mrb_str_upcase_bang()mrbgems/mruby-string-ext/src/string.cString#swapcase!, and both operands ofString#casecmp?Each already reads the result as
int uc = ...; if (uc >= 0)or as... < 0,which
(-1)satisfies. A build withoutMRB_UTF8_STRINGhas taken the macrofor as long as it has existed, so this is the path those five methods are
already compiled from where the tables are absent; what changes is which builds
count as absent.
The stale
#endif /* MRB_UTF8_STRING */comment, which closed a chain whosefirst arm is
MRB_UTF8_STRING && !MRB_USE_ASCII_CASE, is carried off by thesame change.
Size
.textsummed over every.o, each side built from an empty build directory:full-debug(-O0)bintestcxx_abibyte-stringascii-caseasan(-O0)ascii-caseis the only build whose guard moves, and every other one isunchanged to the byte, which is what a change that only redraws a
#ifshouldshow.
Testing
build_config/ci/gcc-clang.rbandbuild_config/asan.rb, run per build so thecounts are attributable:
full-debugbintestcxx_abibyte-stringascii-caseasanIdentical to master, build for build.
bintest(the binary tests) passes 117of 117 under
ci/gcc-clangand 79 of 79 underasan.No new tests come with this.
ascii-casealready asks all five methods for the-1answer:mrbgems/mruby-string-ext/test/string.rbskips only the Unicodeassertions of
String#swapcaseandString#casecmp?there and keeps the ASCIIones, and
test/t/string.rbassertsdowncase,upcaseandcapitalizeonstrings the walk would have refused either way.
Environment
Details
The optimization level is not the same in every build, so these are the lines
that actually compiled
src/string.c, with-MMD -c,-Iand-odropped.cxx_abicompiles withgcc -x c++, not withg++;g++only links.Summary by CodeRabbit