Write MRB_STR_BINARY through accessors, as the other flags are - #7150
Conversation
`include/mruby/string.h` names a way in and out of each string flag it
defines. `MRB_STR_SINGLE_BYTE`, `MRB_STR_VALID_ENC` and
`MRB_STR_BROKEN_ENC` have four apiece: a predicate, a set, an unset and
a copy. Nothing outside the header names those bits.
`MRB_STR_BINARY` has the predicate and the copy and neither of the other
two, so the places that turn it on and off spell the bit out:
mrb_str_ptr(result)->flags |= MRB_STR_BINARY;
s->flags &= ~MRB_STR_BINARY;
There are fourteen of them, spread over `src/string.c` and five gems.
Add `RSTR_SET_BINARY_FLAG()` and `RSTR_UNSET_BINARY_FLAG()` in the shape
the other three flags use, and write all fourteen through them. Both go
next to `RSTR_BINARY_P()`, outside the `MRB_UTF8_STRING` guard the other
three sit behind, because a build without it still tells a byte read
string from the rest: `String#b` and `String#force_encoding` write the
flag there too.
`RSTR_COPY_BINARY_FLAG()` keeps the body it has. Spelling it through the
new unset would change what it compiles to and buy nothing; this adds
the two ways in that were missing, it does not rebuild the ones already
there.
Each new macro expands to the expression its call sites spelled out, so
the generated code is unchanged. `gcc -S -O3` over the six sources that
change gives assembly identical to the assembly before it.
|
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 (7)
📝 WalkthroughWalkthroughThis change adds public macros for setting and clearing ChangesBinary String Flag API Migration
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This localized refactor routes binary string-flag writes through named accessors without changing generated code or Ruby-level behavior. The reported test suites pass with no failures or crashes, so no actionable merge-blocking risk remains beyond normal checks and review. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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/string.hgives each string flag a named way in and out. Three of the four are complete, and one is not:MRB_STR_SINGLE_BYTERSTR_SINGLE_BYTE_PRSTR_SET_SINGLE_BYTE_FLAGRSTR_UNSET_SINGLE_BYTE_FLAGRSTR_COPY_SINGLE_BYTE_FLAGMRB_STR_VALID_ENCRSTR_VALID_ENC_PRSTR_SET_VALID_ENC_FLAGRSTR_UNSET_VALID_ENC_FLAGRSTR_COPY_VALID_ENC_FLAGMRB_STR_BROKEN_ENCRSTR_BROKEN_ENC_PRSTR_SET_BROKEN_ENC_FLAGRSTR_UNSET_BROKEN_ENC_FLAGRSTR_COPY_BROKEN_ENC_FLAGMRB_STR_BINARYRSTR_BINARY_PRSTR_COPY_BINARY_FLAGBecause the two are missing, every place that turns the binary flag on or off reaches past the header and names the bit itself. Before this change:
Fourteen sites, one
srcfile and five gems. After it, the same grep finds the two macro bodies in the header and nothing else.What this adds
They sit next to
RSTR_BINARY_P()rather than inside the#ifdef MRB_UTF8_STRINGblock the other three flags' accessors are in. A build withoutMRB_UTF8_STRINGstill tells a byte read string from the rest, andString#bandString#force_encoding("BINARY")still write the flag there, so the accessors have to be real in that build, exactly asRSTR_BINARY_P()already is.RSTR_COPY_BINARY_FLAG()keeps the body it has. Expressing it through the new unset would change what it compiles to and buy nothing: this change adds the two ways in that were missing, it does not rebuild the ones already there.What this changes
gcc -S -O3with the full-core defines over the six sources that change gives assembly identical to the assembly before this change, byte for byte.lib/mruby/amalgam.rbinlinesinclude/mruby/string.hwhole, so the amalgamated header gains them too. Nothing is removed or renamed, so code outside this repository is unaffected.Testing
MRB_UTF8_STRINGon: 2286 tests, 2276 OK, 10 skip, 0 KO, 0 crash, no new warnings.mruby-encodingis absent and strings index by byte: 2070 tests, 2042 OK, 28 skip, 0 KO, 0 crash.Still left out
Two writes to other string flags still name the bit directly. Neither is a binary flag write, and each wants its own reasoning:
mrbgems/mruby-string-ext/src/string.c, instr_ascii_only_p():flags |= MRB_STR_SINGLE_BYTE, whereRSTR_SET_SINGLE_BYTE_FLAG()exists but compiles to nothing withoutMRB_UTF8_STRING, so swapping it in is a behavior question, not a spelling one.mrbgems/mruby-sprintf/src/sprintf.c, around line 624:RSTR_SET_EMBED_LEN()written out by hand, next to a branch that sets the heap length to a different value. Folding the pair intoRSTR_SET_LEN()is not a rename.Summary by CodeRabbit