Previously, `mrb_int` was used as the type that represents the buffer size
on memory, but the sizes of `RString` and `RArray` exceed 6 words when
`MRB_INT64` is enabled on 32-bit CPU.
I don't think it is necessary to be able to represent the buffer size on
memory that exceeds the virtual address space. Therefore, for this purpose,
introduce `mrb_ssize` which doesn't exceed the sizes of `mrb_int` and
pointer.
I think all `mrb_int` used for this purpose should be changed to
`mrb_ssize`, but currently only the members of the structures (`RString`,
`mrb_shared_string`, `RArray` and `mrb_shared_array`) are changed.
### Benchmark (with `MRB_UTF8_STRING`)
```
$ mruby -e '
COUNT = 150000
SIZE = 10000
strs = Array.new(COUNT) do
s = "a" * SIZE
s.size # set `MRB_STR_ASCII` flag
s
end
i = 0
t = Time.now
while i < COUNT
strs[i][-2..-1] = ""
i += 1
end
printf "%.2f sec\n", Time.now - t
'
1.10 sec # before
0.07 sec # after
```
### Benchmark (with `MRB_UTF8_STRING`)
```ruby
# benchmark.rb
COUNT = 300000
SIZE = 10000
s = "a" * SIZE
s.size # set `MRB_STR_ASCII` flag
i = 0
while i < COUNT
s[-1]
i += 1
end
```
#### Before this patch:
```
$ time mruby benchmark.rb
2.06 real 2.05 user 0.00 sys
```
#### After this patch:
```
$ time mruby benchmark.rb
0.05 real 0.04 user 0.00 sys
```
### Example (with `MRB_UTF8_STRING`)
```ruby
s = "\u3042"
p s.size
s.dump
p s.size
```
#### Before this patch:
```
1
3
```
#### After this patch:
```
1
1
```
1. `$/` and other Perl-ish global variables are not defined in ISO.
2. The current Ruby policy do not encourage those variables.
3. Those variables has global effect and can cause troubles.
Unlike CRuby, there's no way to process strings byte-wise by core
methods because there's no per string encoding in mruby, so that
we moved 3 byte-wise operation methods from `mruby-string-ext` gem.
Prioritize embedded string in the following functions:
- `str_new_static`
- `str_new`
- `mrb_str_new_capa`
- `mrb_str_pool`
The reasons are as follows:
- Consistency with `mrb_str_byte_subseq` and `str_replace`.
- Memory locality increases and may be slightly faster.
- No conversion cost to embedded string when modifying the string.
On 64-bit CPU, there is padding in `RBasic`, so reorder the fields and use
it as buffer of embedded string. This change allows 4 more bytes to be
embedded on 64-bit CPU.
However, an incompatibility will occur if `RString::as::ary` is accessed
directly because `RString` structure has changed.
- `mrb_str_index_m()` and `mrb_str_rindex()`
Make `mrb_get_args()` called only once from called twice.
- `mrb_str_byteslice()`
Replace `goto` with `if ~ else`.
Previously `String#rindex` returned the wrong index when given an
invalid UTF-8 string.
```terminal
% ruby26 -e 'str = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"; p str.rindex("☁")'
11
% ./mruby-head -e 'str = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"; p str.rindex("☁")'
nil
% ./mruby-patched -e 'str = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃"; p str.rindex("☁")'
11
```
I think the string buffer of NOFREE string always exists and does not need
to be released, so it can be shared as another NOFREE string.
Also changed the `mrb_shared_string` field order so that eliminate padding if
`int` and `mrb_int` sizes are less than pointer size.
`mrb_string_value_cstr` and `mrb_string_value_len`: obsolete
`mrb_string_cstr`: new function to retrieve NULL terminated C string
`RSTRING_CSTR`: wrapper macro of `mrb_string_cstr`
The binary sizes (gems are only `mruby-bin-mruby`) are reduced slightly in
my environment than before the introduction of new specifiers/modifiers
(5116789a) with this change.
------------+-------------------+-------------------+--------
BINARY | BEFORE (5116789a) | AFTER (This PR) | RATIO
------------+-------------------+-------------------+--------
mruby | 593416 bytes | 593208 bytes | -0.04%
libmruby.a | 769048 bytes | 767264 bytes | -0.23%
------------+-------------------+-------------------+--------
BTW, I accidentally changed `tasks/toolchains/visualcpp.rake` at #4613,
so I put it back.