internal.h: move writing a string's encoding and coderange inside - #7179
Conversation
Nine places asked the same question of a string and spelled it out each time: whether its coderange stands at 7BIT, or its bytes are read as bytes. Both answers mean the same thing to the caller, which is that a character index into the string is already a byte index. `mrb_str_char_to_byte` returns the index it was handed, `mrb_str_byte_to_char` likewise, `mrb_str_check_byte_pos` has no boundary to check, and `mrb_str_rindex_m` hands the whole search to `mrb_str_byterindex_m`. `RSTR_SINGLE_BYTE_P` gives that question a name. It is derived from what the string carries rather than carried alongside it, so it is not the `MRB_STR_SINGLE_BYTE` flag coming back: nothing stores it and nothing has to keep it up to date. The expansion is what the call sites spelled, so nothing changes in what is generated.
Reading either field is a fact about the string, and mruby/string.h goes on handing both back to anyone who includes it. Writing one is a claim, and a claim the bytes do not support is caught nowhere: an encoding index has the bytes read as something they are not, and a string wrongly saying it reads whole and sound goes straight through the check a regexp makes of its subject before handing it to the engine. So the writes move to where they can be answered for. This is the line CRuby draws in the same place, with `rb_enc_str_coderange()` in ruby/encoding.h and `ENC_CODERANGE_CLEAR` in internal/encoding/coderange.h. Nothing in the tree has to follow: all ten files that write either field already include mruby/internal.h, and all ten include mruby/string.h before it. No guard is needed around the block, since what a macro spells has to be defined where it is used and not where it is written. The answers themselves stay in mruby/string.h. Naming one is reading, and what reads MRB_STR_CODERANGE_7BIT off a string has to be able to say 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 (4)
📝 WalkthroughWalkthroughThe change adds shared string metadata macros, introduces ChangesString metadata and byte-oriented handling
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to This localized header change moves string metadata writers without identified behavior or build risk; no actionable merge-blocking risk remains after normal checks and review. 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 |
Stacked on #7178, which is the first commit here. The second commit is this PR's own change, and the diff to read is
git diff 33723b692..HEAD. Merging #7178 first leaves this one a single commit.include/mruby/string.hhands out both of a string's answers about its bytes and both ways of writing them:Reading one is asking the string what its bytes were found to be, and asking costs it nothing. Writing one is making a claim about them, and a claim the bytes do not support is caught nowhere: a wrong encoding index has the bytes read as something they are not, and a string wrongly saying it reads whole and sound walks straight through the check a regexp makes of its subject before handing it to the engine.
This PR moves the writes to
include/mruby/internal.h, which is where what has to be answered for already lives.The line CRuby draws in the same place
rb_enc_str_coderange()is ininclude/ruby/encoding.h;ENC_CODERANGE_CLEARandENC_CODERANGE_SETare ininternal/encoding/coderange.h. Read published, written inside.What stays behind
The answers themselves. Naming one is reading, and what reads
MRB_STR_CODERANGE_7BIToff a string has to be able to say it:along with the
_SHIFT/_BITS/_MASKtriples the readers expand to, andRSTR_CODERANGE,RSTR_ENCODING,RSTR_BINARY_P,RSTR_SINGLE_BYTE_P.Nothing in the tree has to follow
Ten files write one of the fields, 46 writes in all:
Every one of them already includes
mruby/internal.h, and every one includesmruby/string.hbefore it:So no
#includeline is added or moved:No
#ifdef MRUBY_STRING_Hguard is needed around the moved block either: what a macro spells has to be defined where it is expanded, not where it is written, and the four names it reaches for stay inmruby/string.h.The amalgamated header carries them
lib/mruby/amalgam.rbinlinesmruby/internal.hwhole, so the move needs no change there. Generatingmruby.hon master and on this branch and comparing the two, sorted so a block that only moved does not show:Nothing is dropped, and what is added is #7178's macro and the
#ifdef MRB_UTF8_STRINGthe moved block brings with it. The rest of the 40 added lines are the comments the two commits write. The moved writes land atmruby.h:8800onwards in the generated header, inside themruby/internal.hsection.Generated code
A move of macro definitions, so nothing changes in what is generated.
gcc 13.3.0 -O3, x86-64,.textofbin/mruby, against the same objects built from master:build_config/default.rbfull-core,i686-linux-gnu-gccObjects differing between this commit and #7178, comparing
objdump -dover every.oin the build:build_config/default.rbcxx_abiis the one build inci/gcc-clangthat goes through the C++ compiler, and the moved block is reached frommrbgems/mruby-string-bitops,mrbgems/mruby-timeandsrc/symbol.cthere as everywhere else.Testing
rake -m test, on each commit, all green, 0 KO, 0 crash, 0 warnings, and the same counts as master:build_config/default.rbfull-core,i686-linux-gnu-gccenable_debugbuild_config/host-m32.rbneeds a multilib toolchain, so the 32-bit build above isfull-corewith the compiler set toi686-linux-gnu-gccinstead.No test accompanies the change. A macro spells what it spelled and is expanded where it was expanded, so no string answers anything different.
For a gem outside the tree
One that writes either field has to include
mruby/internal.hafter this. That is a compile error and not a quiet change of behavior, which is what a gem making a claim about a string's bytes should get.Not in this PR
What the two fields mean, how wide they are, and where in the flags word they sit are all untouched. So is every write in the tree: the 46 above are the same 46, spelled the same way, in the same order.
Summary by CodeRabbit